(bug 29115) Add redirect target value on page info
authorumherirrender <umherirrender_de.wp@web.de>
Fri, 30 Nov 2012 10:55:42 +0000 (11:55 +0100)
committerumherirrender <umherirrender_de.wp@web.de>
Sun, 9 Dec 2012 19:09:15 +0000 (20:09 +0100)
Added inprop=redirecttarget

Refactored ApiPageSet::getRedirectTargets to having one method for
resolving redirect targets and calling that from prop=info.

Change-Id: Ia5fb9f25488880c2dd63e613c913a0864464d327

RELEASE-NOTES-1.21
includes/api/ApiPageSet.php
includes/api/ApiQueryInfo.php

index 87a0058..b7571bb 100644 (file)
@@ -122,6 +122,7 @@ production.
 * (bug 41042) Revert change to action=parse&page=... behavior when the page
   does not exist.
 * (bug 27202) Add timestamp sort to list=allimages.
+* (bug 29115) Add redirect target value on page info.
 
 === Languages updated in 1.21 ===
 
index 0f5be6b..bee8046 100644 (file)
@@ -624,10 +624,43 @@ class ApiPageSet extends ApiQueryBase {
         * @return LinkBatch
         */
        private function getRedirectTargets() {
+               $redirectTitles = $this->resolveIdsToRedirectTargets( array_keys( $this->mPendingRedirectIDs ), 'profileDB' );
+
                $lb = new LinkBatch();
+               foreach( $this->mPendingRedirectIDs as $rdfrom => $from ) {
+                       if( !isset( $redirectTitles[$rdfrom] ) ) {
+                               continue;
+                       }
+                       $to = $redirectTitles[$rdfrom];
+                       if ( $to && !isset( $this->mAllPages[$to->getNamespace()][$to->getText()] ) ) {
+                               $lb->addObj( $to );
+                       }
+                       $this->mRedirectTitles[$from->getPrefixedText()] = $to;
+               }
+               return $lb;
+       }
+
+       /**
+        * Get the targets of redirects from the database
+        *
+        * Also creates entries in the redirect table for redirects that don't
+        * have one.
+        *
+        * @param $redirectIDs array The array of pageids to resolve
+        * @param $profileDB string if profileDBIn should called
+        * @return array id => redirect target as title
+        * @since 1.21
+        */
+       public function resolveIdsToRedirectTargets( $redirectIDs, $profileDB = '' ) {
+               if( !$redirectIDs ) {
+                       return array();
+               }
+
                $db = $this->getDB();
 
-               $this->profileDBIn();
+               if( $profileDB ) {
+                       $this->profileDBIn();
+               }
                $res = $db->select(
                        'redirect',
                        array(
@@ -636,37 +669,38 @@ class ApiPageSet extends ApiQueryBase {
                                'rd_fragment',
                                'rd_interwiki',
                                'rd_title'
-                       ), array( 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ),
+                       ), array( 'rd_from' => $redirectIDs ),
                        __METHOD__
                );
-               $this->profileDBOut();
+               if( $profileDB ) {
+                       $this->profileDBOut();
+               }
+
+               $redirectTitles = array();
                foreach ( $res as $row ) {
                        $rdfrom = intval( $row->rd_from );
-                       $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
                        $to = Title::makeTitle( $row->rd_namespace, $row->rd_title, $row->rd_fragment, $row->rd_interwiki );
-                       unset( $this->mPendingRedirectIDs[$rdfrom] );
-                       if ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
-                               $lb->add( $row->rd_namespace, $row->rd_title );
-                       }
-                       $this->mRedirectTitles[$from] = $to;
+                       $redirectTitles[$rdfrom] = $to;
                }
 
-               if ( $this->mPendingRedirectIDs ) {
+               $unresolvedRedirectIDs = array_diff( $redirectIDs, array_keys( $redirectTitles ) );
+               if ( $unresolvedRedirectIDs ) {
                        // We found pages that aren't in the redirect table
                        // Add them
-                       foreach ( $this->mPendingRedirectIDs as $id => $title ) {
-                               $page = WikiPage::factory( $title );
+                       foreach ( $unresolvedRedirectIDs as $id ) {
+                               $page = WikiPage::newFromID( $id );
+                               if ( !$page ) {
+                                       continue;
+                               }
                                $rt = $page->insertRedirect();
                                if ( !$rt ) {
                                        // What the hell. Let's just ignore this
                                        continue;
                                }
-                               $lb->addObj( $rt );
-                               $this->mRedirectTitles[$title->getPrefixedText()] = $rt;
-                               unset( $this->mPendingRedirectIDs[$id] );
+                               $redirectTitles[$id] = $rt;
                        }
                }
-               return $lb;
+               return $redirectTitles;
        }
 
        /**
index e5cea96..76d1e3b 100644 (file)
@@ -34,12 +34,12 @@ class ApiQueryInfo extends ApiQueryBase {
        private $fld_protection = false, $fld_talkid = false,
                $fld_subjectid = false, $fld_url = false,
                $fld_readable = false, $fld_watched = false, $fld_notificationtimestamp = false,
-               $fld_preload = false, $fld_displaytitle = false;
+               $fld_preload = false, $fld_displaytitle = false, $fld_redirecttarget = false;
 
        private $params, $titles, $missing, $everything, $pageCounter;
 
        private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched,
-               $pageLatest, $pageLength;
+               $pageLatest, $pageLength, $redirectTarget;
 
        private $protections, $watched, $notificationtimestamps, $talkids, $subjectids, $displaytitles;
 
@@ -255,6 +255,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        $this->fld_readable = isset( $prop['readable'] );
                        $this->fld_preload = isset( $prop['preload'] );
                        $this->fld_displaytitle = isset( $prop['displaytitle'] );
+                       $this->fld_redirecttarget = isset( $prop['redirecttarget'] );
                }
 
                $pageSet = $this->getPageSet();
@@ -317,6 +318,10 @@ class ApiQueryInfo extends ApiQueryBase {
                        $this->getDisplayTitle();
                }
 
+               if ( $this->fld_redirecttarget ) {
+                       $this->redirectTarget = $pageSet->resolveIdsToRedirectTargets( array_keys( $this->pageIsRedir ) );
+               }
+
                foreach ( $this->everything as $pageid => $title ) {
                        $pageInfo = $this->extractPageInfo( $pageid, $title );
                        $fit = $result->addValue( array(
@@ -359,6 +364,13 @@ class ApiQueryInfo extends ApiQueryBase {
                        if ( $this->pageIsNew[$pageid] ) {
                                $pageInfo['new'] = '';
                        }
+                       if ( $this->fld_redirecttarget && isset( $this->redirectTarget[$pageid] ) ) {
+                               $targetTitle = $this->redirectTarget[$pageid];
+                               $pageInfo['redirecttarget'] = $targetTitle->getPrefixedText();
+                               if( $targetTitle->getFragment() !== '' ) {
+                                       $pageInfo['redirecttargetfragment'] = $targetTitle->getFragment();
+                               }
+                       }
                }
 
                if ( !is_null( $this->params['token'] ) ) {
@@ -686,6 +698,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        'url',
                        'preload',
                        'displaytitle',
+                       'redirecttarget',
                );
                if ( !is_null( $params['prop'] ) ) {
                        foreach ( $params['prop'] as $prop ) {
@@ -715,6 +728,7 @@ class ApiQueryInfo extends ApiQueryBase {
                                        'readable', # private
                                        'preload',
                                        'displaytitle',
+                                       'redirecttarget',
                                        // If you add more properties here, please consider whether they
                                        // need to be added to getCacheMode()
                                ) ),
@@ -740,6 +754,7 @@ class ApiQueryInfo extends ApiQueryBase {
                                ' readable              - Whether the user can read this page',
                                ' preload               - Gives the text returned by EditFormPreloadText',
                                ' displaytitle          - Gives the way the page title is actually displayed',
+                               ' redirecttarget        - Gives the redirect target, if this page is a redirect',
                        ),
                        'token' => 'Request a token to perform a data-modifying action on a page',
                        'continue' => 'When more results are available, use this to continue',
@@ -797,6 +812,13 @@ class ApiQueryInfo extends ApiQueryBase {
                        ),
                        'displaytitle' => array(
                                'displaytitle' => 'string'
+                       ),
+                       'redirecttarget' => array(
+                               'redirecttarget' => 'string',
+                               'redirecttargetfragment' => array(
+                                       ApiBase::PROP_TYPE => 'string',
+                                       ApiBase::PROP_NULLABLE => true
+                               )
                        )
                );