Merge "mediawiki.mixins.rotation: Remove unnecessary @-o-keyframes"
[lhc/web/wiklou.git] / includes / api / ApiPageSet.php
index 1415b79..c6abf40 100644 (file)
@@ -58,7 +58,8 @@ class ApiPageSet extends ApiBase {
        private $mGoodTitles = array();
        private $mMissingPages = array(); // [ns][dbkey] => fake page_id
        private $mMissingTitles = array();
-       private $mInvalidTitles = array(); // [fake_page_id] => array( 'title' => $title, 'invalidreason' => $reason )
+       /** @var array [fake_page_id] => array( 'title' => $title, 'invalidreason' => $reason ) */
+       private $mInvalidTitles = array();
        private $mMissingPageIDs = array();
        private $mRedirectTitles = array();
        private $mSpecialTitles = array();
@@ -78,6 +79,8 @@ class ApiPageSet extends ApiBase {
        private $mRequestedPageFields = array();
        /** @var int */
        private $mDefaultNamespace = NS_MAIN;
+       /** @var callable|null */
+       private $mRedirectMergePolicy;
 
        /**
         * Add all items from $values into the result
@@ -700,7 +703,7 @@ class ApiPageSet extends ApiBase {
         * Note that the query result must include the columns returned by
         * $this->getPageTableFields().
         *
-        * @param DatabaseBase $db
+        * @param IDatabase $db
         * @param ResultWrapper $queryResult Query result object
         */
        public function populateFromQueryResult( $db, $queryResult ) {
@@ -1196,6 +1199,29 @@ class ApiPageSet extends ApiBase {
                $this->mGeneratorData[$ns][$dbkey] = $data;
        }
 
+       /**
+        * Controls how generator data about a redirect source is merged into
+        * the generator data for the redirect target. When not set no data
+        * is merged. Note that if multiple titles redirect to the same target
+        * the order of operations is undefined.
+        *
+        * Example to include generated data from redirect in target, prefering
+        * the data generated for the destination when there is a collision:
+        * @code
+        *   $pageSet->setRedirectMergePolicy( function( array $current, array $new ) {
+        *       return $current + $new;
+        *   } );
+        * @endcode
+        *
+        * @param callable|null $callable Recieves two array arguments, first the
+        *  generator data for the redirect target and second the generator data
+        *  for the redirect source. Returns the resulting generator data to use
+        *  for the redirect target.
+        */
+       public function setRedirectMergePolicy( $callable ) {
+               $this->mRedirectMergePolicy = $callable;
+       }
+
        /**
         * Populate the generator data for all titles in the result
         *
@@ -1269,6 +1295,36 @@ class ApiPageSet extends ApiBase {
                                }
                        }
                }
+
+               // Merge data generated about redirect titles into the redirect destination
+               if ( $this->mRedirectMergePolicy ) {
+                       foreach ( $this->mResolvedRedirectTitles as $titleFrom ) {
+                               $dest = $titleFrom;
+                               while ( isset( $this->mRedirectTitles[$dest->getPrefixedText()] ) ) {
+                                       $dest = $this->mRedirectTitles[$dest->getPrefixedText()];
+                               }
+                               $fromNs = $titleFrom->getNamespace();
+                               $fromDBkey = $titleFrom->getDBkey();
+                               $toPageId = $dest->getArticleID();
+                               if ( isset( $data[$toPageId] ) &&
+                                       isset( $this->mGeneratorData[$fromNs][$fromDBkey] )
+                               ) {
+                                       // It is necesary to set both $data and add to $result, if an ApiResult,
+                                       // to ensure multiple redirects to the same destination are all merged.
+                                       $data[$toPageId] = call_user_func(
+                                               $this->mRedirectMergePolicy,
+                                               $data[$toPageId],
+                                               $this->mGeneratorData[$fromNs][$fromDBkey]
+                                       );
+                                       if ( $result instanceof ApiResult ) {
+                                               if ( !$result->addValue( $path, $toPageId, $data[$toPageId], ApiResult::OVERRIDE ) ) {
+                                                       return false;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
                return true;
        }