Merge "If a user logs in while not on https, then the user should be sent back to...
[lhc/web/wiklou.git] / includes / api / ApiPageSet.php
index db5eb52..78c33ed 100644 (file)
@@ -68,7 +68,10 @@ class ApiPageSet extends ApiBase {
        private $mPendingRedirectIDs = array();
        private $mConvertedTitles = array();
        private $mGoodRevIDs = array();
+       private $mLiveRevIDs = array();
+       private $mDeletedRevIDs = array();
        private $mMissingRevIDs = array();
+       private $mGeneratorData = array(); // [ns][dbkey] => data array
        private $mFakePageId = -1;
        private $mCacheMode = 'public';
        private $mRequestedPageFields = array();
@@ -596,13 +599,29 @@ class ApiPageSet extends ApiBase {
        }
 
        /**
-        * Get the list of revision IDs (requested with the revids= parameter)
+        * Get the list of valid revision IDs (requested with the revids= parameter)
         * @return array Array of revID (int) => pageID (int)
         */
        public function getRevisionIDs() {
                return $this->mGoodRevIDs;
        }
 
+       /**
+        * Get the list of non-deleted revision IDs (requested with the revids= parameter)
+        * @return array Array of revID (int) => pageID (int)
+        */
+       public function getLiveRevisionIDs() {
+               return $this->mLiveRevIDs;
+       }
+
+       /**
+        * Get the list of revision IDs that were associated with deleted titles.
+        * @return array Array of revID (int) => pageID (int)
+        */
+       public function getDeletedRevisionIDs() {
+               return $this->mDeletedRevIDs;
+       }
+
        /**
         * Revision IDs that were not found in the database
         * @return array Array of revision IDs
@@ -901,6 +920,7 @@ class ApiPageSet extends ApiBase {
                                $revid = intval( $row->rev_id );
                                $pageid = intval( $row->rev_page );
                                $this->mGoodRevIDs[$revid] = $pageid;
+                               $this->mLiveRevIDs[$revid] = $pageid;
                                $pageids[$pageid] = '';
                                unset( $remaining[$revid] );
                        }
@@ -911,6 +931,51 @@ class ApiPageSet extends ApiBase {
 
                // Populate all the page information
                $this->initFromPageIds( array_keys( $pageids ) );
+
+               // If the user can see deleted revisions, pull out the corresponding
+               // titles from the archive table and include them too. We ignore
+               // ar_page_id because deleted revisions are tied by title, not page_id.
+               if ( !empty( $this->mMissingRevIDs ) && $this->getUser()->isAllowed( 'deletedhistory' ) ) {
+                       $remaining = array_flip( $this->mMissingRevIDs );
+                       $tables = array( 'archive' );
+                       $fields = array( 'ar_rev_id', 'ar_namespace', 'ar_title' );
+                       $where = array( 'ar_rev_id' => $this->mMissingRevIDs );
+
+                       $this->profileDBIn();
+                       $res = $db->select( $tables, $fields, $where, __METHOD__ );
+                       $titles = array();
+                       foreach ( $res as $row ) {
+                               $revid = intval( $row->ar_rev_id );
+                               $titles[$revid] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+                               unset( $remaining[$revid] );
+                       }
+                       $this->profileDBOut();
+
+                       $this->initFromTitles( $titles );
+
+                       foreach ( $titles as $revid => $title ) {
+                               $ns = $title->getNamespace();
+                               $dbkey = $title->getDBkey();
+
+                               // Handle converted titles
+                               if ( !isset( $this->mAllPages[$ns][$dbkey] ) &&
+                                       isset( $this->mConvertedTitles[$title->getPrefixedText()] )
+                               ) {
+                                       $title = Title::newFromText( $this->mConvertedTitles[$title->getPrefixedText()] );
+                                       $ns = $title->getNamespace();
+                                       $dbkey = $title->getDBkey();
+                               }
+
+                               if ( isset( $this->mAllPages[$ns][$dbkey] ) ) {
+                                       $this->mGoodRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
+                                       $this->mDeletedRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
+                               } else {
+                                       $remaining[$revid] = true;
+                               }
+                       }
+
+                       $this->mMissingRevIDs = array_keys( $remaining );
+               }
        }
 
        /**
@@ -1109,6 +1174,100 @@ class ApiPageSet extends ApiBase {
                return $linkBatch;
        }
 
+       /**
+        * Set data for a title.
+        *
+        * This data may be extracted into an ApiResult using
+        * self::populateGeneratorData. This should generally be limited to
+        * data that is likely to be particularly useful to end users rather than
+        * just being a dump of everything returned in non-generator mode.
+        *
+        * Redirects here will *not* be followed, even if 'redirects' was
+        * specified, since in the case of multiple redirects we can't know which
+        * source's data to use on the target.
+        *
+        * @param Title $title
+        * @param array $data
+        */
+       public function setGeneratorData( Title $title, array $data ) {
+               $ns = $title->getNamespace();
+               $dbkey = $title->getDBkey();
+               $this->mGeneratorData[$ns][$dbkey] = $data;
+       }
+
+       /**
+        * Populate the generator data for all titles in the result
+        *
+        * The page data may be inserted into an ApiResult object or into an
+        * associative array. The $path parameter specifies the path within the
+        * ApiResult or array to find the "pages" node.
+        *
+        * The "pages" node itself must be an associative array mapping the page ID
+        * or fake page ID values returned by this pageset (see
+        * self::getAllTitlesByNamespace() and self::getSpecialTitles()) to
+        * associative arrays of page data. Each of those subarrays will have the
+        * data from self::setGeneratorData() merged in.
+        *
+        * Data that was set by self::setGeneratorData() for pages not in the
+        * "pages" node will be ignored.
+        *
+        * @param ApiResult|array &$result
+        * @param array $path
+        * @return boolean Whether the data fit
+        */
+       public function populateGeneratorData( &$result, array $path = array() ) {
+               if ( $result instanceof ApiResult ) {
+                       $data = $result->getData();
+               } else {
+                       $data = &$result;
+               }
+               foreach ( $path as $key ) {
+                       if ( !isset( $data[$key] ) ) {
+                               // Path isn't in $result, so nothing to add, so everything
+                               // "fits"
+                               return true;
+                       }
+                       $data = &$data[$key];
+               }
+               foreach ( $this->mGeneratorData as $ns => $dbkeys ) {
+                       if ( $ns === -1 ) {
+                               $pages = array();
+                               foreach ( $this->mSpecialTitles as $id => $title ) {
+                                       $pages[$title->getDBkey()] = $id;
+                               }
+                       } else {
+                               if ( !isset( $this->mAllPages[$ns] ) ) {
+                                       // No known titles in the whole namespace. Skip it.
+                                       continue;
+                               }
+                               $pages = $this->mAllPages[$ns];
+                       }
+                       foreach ( $dbkeys as $dbkey => $genData ) {
+                               if ( !isset( $pages[$dbkey] ) ) {
+                                       // Unknown title. Forget it.
+                                       continue;
+                               }
+                               $pageId = $pages[$dbkey];
+                               if ( !isset( $data[$pageId] ) ) {
+                                       // $pageId didn't make it into the result. Ignore it.
+                                       continue;
+                               }
+
+                               if ( $result instanceof ApiResult ) {
+                                       $path2 = array_merge( $path, array( $pageId ) );
+                                       foreach ( $genData as $key => $value ) {
+                                               if ( !$result->addValue( $path2, $key, $value ) ) {
+                                                       return false;
+                                               }
+                                       }
+                               } else {
+                                       $data[$pageId] = array_merge( $data[$pageId], $genData );
+                               }
+                       }
+               }
+               return true;
+       }
+
        /**
         * Get the database connection (read-only)
         * @return DatabaseBase