API: Add ApiPageSet accessors for just good and missing titles
authorBrad Jorsch <bjorsch@wikimedia.org>
Fri, 26 Sep 2014 14:56:00 +0000 (10:56 -0400)
committerBrad Jorsch <bjorsch@wikimedia.org>
Fri, 26 Sep 2014 15:25:36 +0000 (11:25 -0400)
ApiPageSet::getAllTitlesByNamespace is fine when that's what you want.
But in all existing uses in core, it's not what's actually wanted.
* ApiQueryBacklinksprop can generate wrong ORDER BY because it considers
  redirect and invalid titles that it doesn't acutally query.
* ApiQueryCategoryInfo raises a fatal error with category redirects.
* ApiQueryDuplicateFiles and ApiQueryImageInfo will add information for
  redirects, leaving them missing the standard data and missing from
  indexpageids.

What all these need is really something along the lines of
"ApiPageSet::getGoodAndMissingTitlesByNamespace". So let's add that,
plus a few similar methods for good measure.

Bug: 71337
Change-Id: I3a205057edcbc303393718e1c8bfb1f1b1f95323

includes/api/ApiPageSet.php
includes/api/ApiQueryBacklinksprop.php
includes/api/ApiQueryCategoryInfo.php
includes/api/ApiQueryDuplicateFiles.php
includes/api/ApiQueryImageInfo.php

index 0f26467..3bdecaa 100644 (file)
@@ -53,7 +53,10 @@ class ApiPageSet extends ApiBase {
 
        private $mAllPages = array(); // [ns][dbkey] => page_id or negative when missing
        private $mTitles = array();
+       private $mGoodAndMissingPages = array(); // [ns][dbkey] => page_id or negative when missing
+       private $mGoodPages = array(); // [ns][dbkey] => page_id
        private $mGoodTitles = array();
+       private $mMissingPages = array(); // [ns][dbkey] => fake page_id
        private $mMissingTitles = array();
        private $mInvalidTitles = array();
        private $mMissingPageIDs = array();
@@ -343,6 +346,14 @@ class ApiPageSet extends ApiBase {
                return count( $this->mTitles );
        }
 
+       /**
+        * Returns an array [ns][dbkey] => page_id for all good titles.
+        * @return array
+        */
+       public function getGoodTitlesByNamespace() {
+               return $this->mGoodPages;
+       }
+
        /**
         * Title objects that were found in the database.
         * @return Title[] Array page_id (int) => Title (obj)
@@ -359,6 +370,15 @@ class ApiPageSet extends ApiBase {
                return count( $this->mGoodTitles );
        }
 
+       /**
+        * Returns an array [ns][dbkey] => fake_page_id for all missing titles.
+        * fake_page_id is a unique negative number.
+        * @return array
+        */
+       public function getMissingTitlesByNamespace() {
+               return $this->mMissingPages;
+       }
+
        /**
         * Title objects that were NOT found in the database.
         * The array's index will be negative for each item
@@ -368,6 +388,22 @@ class ApiPageSet extends ApiBase {
                return $this->mMissingTitles;
        }
 
+       /**
+        * Returns an array [ns][dbkey] => page_id for all good and missing titles.
+        * @return array
+        */
+       public function getGoodAndMissingTitlesByNamespace() {
+               return $this->mGoodAndMissingPages;
+       }
+
+       /**
+        * Title objects for good and missing titles.
+        * @return array
+        */
+       public function getGoodAndMissingTitles() {
+               return $this->mGoodTitles + $this->mMissingTitles;
+       }
+
        /**
         * Titles that were deemed invalid by Title::newFromText()
         * The array's index will be unique and negative for each item
@@ -667,6 +703,8 @@ class ApiPageSet extends ApiBase {
                if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
                        $this->mPendingRedirectIDs[$pageId] = $title;
                } else {
+                       $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
+                       $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
                        $this->mGoodTitles[$pageId] = $title;
                }
 
@@ -803,6 +841,8 @@ class ApiPageSet extends ApiBase {
                                        foreach ( array_keys( $dbkeys ) as $dbkey ) {
                                                $title = Title::makeTitle( $ns, $dbkey );
                                                $this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
+                                               $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
+                                               $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
                                                $this->mMissingTitles[$this->mFakePageId] = $title;
                                                $this->mFakePageId--;
                                                $this->mTitles[] = $title;
index cd68261..2458a26 100644 (file)
@@ -106,8 +106,8 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
                $emptyString = $db->addQuotes( '' );
 
                $pageSet = $this->getPageSet();
-               $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
-               $map = $pageSet->getAllTitlesByNamespace();
+               $titles = $pageSet->getGoodAndMissingTitles();
+               $map = $pageSet->getGoodAndMissingTitlesByNamespace();
 
                // Determine our fields to query on
                $p = $settings['prefix'];
index 6e9f33c..3dd4c65 100644 (file)
@@ -38,14 +38,13 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
 
        public function execute() {
                $params = $this->extractRequestParams();
-               $alltitles = $this->getPageSet()->getAllTitlesByNamespace();
+               $alltitles = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
                if ( empty( $alltitles[NS_CATEGORY] ) ) {
                        return;
                }
                $categories = $alltitles[NS_CATEGORY];
 
-               $titles = $this->getPageSet()->getGoodTitles() +
-                       $this->getPageSet()->getMissingTitles();
+               $titles = $this->getPageSet()->getGoodAndMissingTitles();
                $cattitles = array();
                foreach ( $categories as $c ) {
                        /** @var $t Title */
index 6d836cd..2212957 100644 (file)
@@ -52,7 +52,7 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
         */
        private function run( $resultPageSet = null ) {
                $params = $this->extractRequestParams();
-               $namespaces = $this->getPageSet()->getAllTitlesByNamespace();
+               $namespaces = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
                if ( empty( $namespaces[NS_FILE] ) ) {
                        return;
                }
index 945374b..ad5cdbd 100644 (file)
@@ -58,7 +58,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        'revdelUser' => $this->getUser(),
                );
 
-               $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
+               $pageIds = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
                if ( !empty( $pageIds[NS_FILE] ) ) {
                        $titles = array_keys( $pageIds[NS_FILE] );
                        asort( $titles ); // Ensure the order is always the same