(bug 29115) Add redirect target value on page info
[lhc/web/wiklou.git] / includes / api / ApiPageSet.php
index 598f9ad..bee8046 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Created on Sep 24, 2006
  *
- * Copyright © 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@ class ApiPageSet extends ApiQueryBase {
 
        /**
         * Constructor
-        * @param $query ApiQueryBase
+        * @param $query ApiBase
         * @param $resolveRedirects bool Whether redirects should be resolved
         * @param $convertTitles bool
         */
@@ -266,8 +266,8 @@ class ApiPageSet extends ApiQueryBase {
        }
 
        /**
-        * Returns the number of revisions (requested with revids= parameter)\
-        * @return int
+        * Returns the number of revisions (requested with revids= parameter).
+        * @return int Number of revisions.
         */
        public function getRevisionCount() {
                return count( $this->getRevisionIDs() );
@@ -367,7 +367,7 @@ class ApiPageSet extends ApiQueryBase {
         */
        public function processDbRow( $row ) {
                // Store Title object in various data structures
-               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+               $title = Title::newFromRow( $row );
 
                $pageId = intval( $row->page_id );
                $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
@@ -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;
        }
 
        /**