Пример #1
0
 public function testHandleNormalization()
 {
     $context = new RequestContext();
     $context->setRequest(new FauxRequest(['titles' => "a|B|å"]));
     $main = new ApiMain($context);
     $pageSet = new ApiPageSet($main);
     $pageSet->execute();
     $this->assertSame([0 => ['A' => -1, 'B' => -2, 'Å' => -3]], $pageSet->getAllTitlesByNamespace());
     $this->assertSame([['fromencoded' => true, 'from' => 'a%CC%8A', 'to' => 'å'], ['fromencoded' => false, 'from' => 'a', 'to' => 'A'], ['fromencoded' => false, 'from' => 'å', 'to' => 'Å']], $pageSet->getNormalizedTitlesAsResult());
 }
Пример #2
0
 /**
  * Query execution happens in the following steps:
  * #1 Create a PageSet object with any pages requested by the user
  * #2 If using a generator, execute it to get a new ApiPageSet object
  * #3 Instantiate all requested modules.
  *    This way the PageSet object will know what shared data is required,
  *    and minimize DB calls.
  * #4 Output all normalization and redirect resolution information
  * #5 Execute all requested modules
  */
 public function execute()
 {
     $this->mParams = $this->extractRequestParams();
     // Instantiate requested modules
     $allModules = array();
     $this->instantiateModules($allModules, 'prop');
     $propModules = array_keys($allModules);
     $this->instantiateModules($allModules, 'list');
     $this->instantiateModules($allModules, 'meta');
     // Filter modules based on continue parameter
     $continuationManager = new ApiContinuationManager($this, $allModules, $propModules);
     $this->setContinuationManager($continuationManager);
     $modules = $continuationManager->getRunModules();
     if (!$continuationManager->isGeneratorDone()) {
         // Query modules may optimize data requests through the $this->getPageSet()
         // object by adding extra fields from the page table.
         foreach ($modules as $module) {
             $module->requestExtraData($this->mPageSet);
         }
         // Populate page/revision information
         $this->mPageSet->execute();
         // Record page information (title, namespace, if exists, etc)
         $this->outputGeneralPageInfo();
     } else {
         $this->mPageSet->executeDryRun();
     }
     $cacheMode = $this->mPageSet->getCacheMode();
     // Execute all unfinished modules
     /** @var $module ApiQueryBase */
     foreach ($modules as $module) {
         $params = $module->extractRequestParams();
         $cacheMode = $this->mergeCacheMode($cacheMode, $module->getCacheMode($params));
         $module->execute();
         Hooks::run('APIQueryAfterExecute', array(&$module));
     }
     // Set the cache mode
     $this->getMain()->setCacheMode($cacheMode);
     // Write the continuation data into the result
     $this->setContinuationManager(null);
     if ($this->mParams['rawcontinue']) {
         $data = $continuationManager->getRawContinuation();
         if ($data) {
             $this->getResult()->addValue(null, 'query-continue', $data, ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK);
         }
     } else {
         $continuationManager->setContinuationIntoResult($this->getResult());
     }
     /// @todo: Remove this after a suitable period of time. When REL1_26 is cut, if not before.
     if ($this->mParams['continue'] === null && !$this->mParams['rawcontinue'] && $this->getResult()->getResultData('continue') !== null) {
         $this->setWarning('Formatting of continuation data has changed. ' . 'To receive raw query-continue data, use the \'rawcontinue\' parameter. ' . 'To silence this warning, pass an empty string for \'continue\' in the initial query.');
     }
 }
Пример #3
0
 /**
  * Query execution happens in the following steps:
  * #1 Create a PageSet object with any pages requested by the user
  * #2 If using a generator, execute it to get a new ApiPageSet object
  * #3 Instantiate all requested modules.
  *    This way the PageSet object will know what shared data is required,
  *    and minimize DB calls.
  * #4 Output all normalization and redirect resolution information
  * #5 Execute all requested modules
  */
 public function execute()
 {
     $this->mParams = $this->extractRequestParams();
     // Instantiate requested modules
     $allModules = [];
     $this->instantiateModules($allModules, 'prop');
     $propModules = array_keys($allModules);
     $this->instantiateModules($allModules, 'list');
     $this->instantiateModules($allModules, 'meta');
     // Filter modules based on continue parameter
     $continuationManager = new ApiContinuationManager($this, $allModules, $propModules);
     $this->setContinuationManager($continuationManager);
     $modules = $continuationManager->getRunModules();
     if (!$continuationManager->isGeneratorDone()) {
         // Query modules may optimize data requests through the $this->getPageSet()
         // object by adding extra fields from the page table.
         foreach ($modules as $module) {
             $module->requestExtraData($this->mPageSet);
         }
         // Populate page/revision information
         $this->mPageSet->execute();
         // Record page information (title, namespace, if exists, etc)
         $this->outputGeneralPageInfo();
     } else {
         $this->mPageSet->executeDryRun();
     }
     $cacheMode = $this->mPageSet->getCacheMode();
     // Execute all unfinished modules
     /** @var $module ApiQueryBase */
     foreach ($modules as $module) {
         $params = $module->extractRequestParams();
         $cacheMode = $this->mergeCacheMode($cacheMode, $module->getCacheMode($params));
         $module->execute();
         Hooks::run('APIQueryAfterExecute', [&$module]);
     }
     // Set the cache mode
     $this->getMain()->setCacheMode($cacheMode);
     // Write the continuation data into the result
     $this->setContinuationManager(null);
     if ($this->mParams['rawcontinue']) {
         $data = $continuationManager->getRawNonContinuation();
         if ($data) {
             $this->getResult()->addValue(null, 'query-noncontinue', $data, ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK);
         }
         $data = $continuationManager->getRawContinuation();
         if ($data) {
             $this->getResult()->addValue(null, 'query-continue', $data, ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK);
         }
     } else {
         $continuationManager->setContinuationIntoResult($this->getResult());
     }
 }
Пример #4
0
 /**
  * For generator mode, execute generator, and use its output as new
  * ApiPageSet
  * @param $generator ApiQueryGeneratorBase Generator Module
  * @param $modules array of module objects
  */
 protected function executeGeneratorModule($generator, $modules)
 {
     // Generator results
     $resultPageSet = new ApiPageSet($this, $this->redirects, $this->convertTitles);
     // Add any additional fields modules may need
     $generator->requestExtraData($this->mPageSet);
     $this->addCustomFldsToPageSet($modules, $resultPageSet);
     // Populate page information with the original user input
     $this->mPageSet->execute();
     // populate resultPageSet with the generator output
     $generator->profileIn();
     $generator->executeGenerator($resultPageSet);
     wfRunHooks('APIQueryGeneratorAfterExecute', array(&$generator, &$resultPageSet));
     $resultPageSet->finishPageSetGeneration();
     $generator->profileOut();
     // Swap the resulting pageset back in
     $this->mPageSet = $resultPageSet;
 }
Пример #5
0
 /**
  * Query execution happens in the following steps:
  * #1 Create a PageSet object with any pages requested by the user
  * #2 If using a generator, execute it to get a new ApiPageSet object
  * #3 Instantiate all requested modules.
  *    This way the PageSet object will know what shared data is required,
  *    and minimize DB calls.
  * #4 Output all normalization and redirect resolution information
  * #5 Execute all requested modules
  */
 public function execute()
 {
     $this->mParams = $this->extractRequestParams();
     // Instantiate requested modules
     $allModules = array();
     $this->instantiateModules($allModules, 'prop');
     $propModules = array_keys($allModules);
     $this->instantiateModules($allModules, 'list');
     $this->instantiateModules($allModules, 'meta');
     // Filter modules based on continue parameter
     list($generatorDone, $modules) = $this->getResult()->beginContinuation($this->mParams['continue'], $allModules, $propModules);
     if (!$generatorDone) {
         // Query modules may optimize data requests through the $this->getPageSet()
         // object by adding extra fields from the page table.
         foreach ($modules as $module) {
             $module->requestExtraData($this->mPageSet);
         }
         // Populate page/revision information
         $this->mPageSet->execute();
         // Record page information (title, namespace, if exists, etc)
         $this->outputGeneralPageInfo();
     } else {
         $this->mPageSet->executeDryRun();
     }
     $cacheMode = $this->mPageSet->getCacheMode();
     // Execute all unfinished modules
     /** @var $module ApiQueryBase */
     foreach ($modules as $module) {
         $params = $module->extractRequestParams();
         $cacheMode = $this->mergeCacheMode($cacheMode, $module->getCacheMode($params));
         $module->profileIn();
         $module->execute();
         wfRunHooks('APIQueryAfterExecute', array(&$module));
         $module->profileOut();
     }
     // Set the cache mode
     $this->getMain()->setCacheMode($cacheMode);
     // Write the continuation data into the result
     $this->getResult()->endContinuation($this->mParams['continue'] === null ? 'raw' : 'standard');
 }
Пример #6
0
 /**
  * Query execution happens in the following steps:
  * #1 Create a PageSet object with any pages requested by the user
  * #2 If using a generator, execute it to get a new ApiPageSet object
  * #3 Instantiate all requested modules.
  *    This way the PageSet object will know what shared data is required,
  *    and minimize DB calls.
  * #4 Output all normalization and redirect resolution information
  * #5 Execute all requested modules
  */
 public function execute()
 {
     $this->mParams = $this->extractRequestParams();
     // $pagesetParams is a array of parameter names used by the pageset generator
     //   or null if pageset has already finished and is no longer needed
     // $completeModules is a set of complete modules with the name as key
     $this->initContinue($pagesetParams, $completeModules);
     // Instantiate requested modules
     $allModules = array();
     $this->instantiateModules($allModules, 'prop');
     $propModules = $allModules;
     // Keep a copy
     $this->instantiateModules($allModules, 'list');
     $this->instantiateModules($allModules, 'meta');
     // Filter modules based on continue parameter
     $modules = $this->initModules($allModules, $completeModules, $pagesetParams !== null);
     // Execute pageset if in legacy mode or if pageset is not done
     if ($completeModules === null || $pagesetParams !== null) {
         // Populate page/revision information
         $this->mPageSet->execute();
         // Record page information (title, namespace, if exists, etc)
         $this->outputGeneralPageInfo();
     } else {
         $this->mPageSet->executeDryRun();
     }
     $cacheMode = $this->mPageSet->getCacheMode();
     // Execute all unfinished modules
     /** @var $module ApiQueryBase */
     foreach ($modules as $module) {
         $params = $module->extractRequestParams();
         $cacheMode = $this->mergeCacheMode($cacheMode, $module->getCacheMode($params));
         $module->profileIn();
         $module->execute();
         wfRunHooks('APIQueryAfterExecute', array(&$module));
         $module->profileOut();
     }
     // Set the cache mode
     $this->getMain()->setCacheMode($cacheMode);
     if ($completeModules === null) {
         return;
         // Legacy continue, we are done
     }
     // Reformat query-continue result section
     $result = $this->getResult();
     $qc = $result->getData();
     if (isset($qc['query-continue'])) {
         $qc = $qc['query-continue'];
         $result->unsetValue(null, 'query-continue');
     } elseif ($this->mGeneratorContinue !== null) {
         $qc = array();
     } else {
         // no more "continue"s, we are done!
         return;
     }
     // we are done with all the modules that do not have result in query-continue
     $completeModules = array_merge($completeModules, array_diff_key($modules, $qc));
     if ($pagesetParams !== null) {
         // The pageset is still in use, check if all props have finished
         $incompleteProps = array_intersect_key($propModules, $qc);
         if (count($incompleteProps) > 0) {
             // Properties are not done, continue with the same pageset state - copy current parameters
             $main = $this->getMain();
             $contValues = array();
             foreach ($pagesetParams as $param) {
                 // The param name is already prefix-encoded
                 $contValues[$param] = $main->getVal($param);
             }
         } elseif ($this->mGeneratorContinue !== null) {
             // Move to the next set of pages produced by pageset, properties need to be restarted
             $contValues = $this->mGeneratorContinue;
             $pagesetParams = array_keys($contValues);
             $completeModules = array_diff_key($completeModules, $propModules);
         } else {
             // Done with the pageset, finish up with the the lists and meta modules
             $pagesetParams = null;
         }
     }
     $continue = '||' . implode('|', array_keys($completeModules));
     if ($pagesetParams !== null) {
         // list of all pageset parameters to use in the next request
         $continue = implode('|', $pagesetParams) . $continue;
     } else {
         // we are done with the pageset
         $contValues = array();
         $continue = '-' . $continue;
     }
     $contValues['continue'] = $continue;
     foreach ($qc as $qcModule) {
         foreach ($qcModule as $qcKey => $qcValue) {
             $contValues[$qcKey] = $qcValue;
         }
     }
     $this->getResult()->addValue(null, 'continue', $contValues);
 }
 public function execute()
 {
     $user = $this->getUser();
     if ($user->isAnon()) {
         $this->dieUsage('Anonymous users cannot use watchlist change notifications', 'notloggedin');
     }
     $params = $this->extractRequestParams();
     $this->requireMaxOneParameter($params, 'timestamp', 'torevid', 'newerthanrevid');
     $pageSet = new ApiPageSet($this);
     $args = array_merge(array($params, 'entirewatchlist'), array_keys($pageSet->getAllowedParams()));
     call_user_func_array(array($this, 'requireOnlyOneParameter'), $args);
     $dbw = $this->getDB(DB_MASTER);
     $timestamp = null;
     if (isset($params['timestamp'])) {
         $timestamp = $dbw->timestamp($params['timestamp']);
     }
     if (!$params['entirewatchlist']) {
         $pageSet->execute();
     }
     if (isset($params['torevid'])) {
         if ($params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1) {
             $this->dieUsage('torevid may only be used with a single page', 'multpages');
         }
         $title = reset($pageSet->getGoodTitles());
         $timestamp = Revision::getTimestampFromId($title, $params['torevid']);
         if ($timestamp) {
             $timestamp = $dbw->timestamp($timestamp);
         } else {
             $timestamp = null;
         }
     } elseif (isset($params['newerthanrevid'])) {
         if ($params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1) {
             $this->dieUsage('newerthanrevid may only be used with a single page', 'multpages');
         }
         $title = reset($pageSet->getGoodTitles());
         $revid = $title->getNextRevisionID($params['newerthanrevid']);
         if ($revid) {
             $timestamp = $dbw->timestamp(Revision::getTimestampFromId($title, $revid));
         } else {
             $timestamp = null;
         }
     }
     $apiResult = $this->getResult();
     $result = array();
     if ($params['entirewatchlist']) {
         // Entire watchlist mode: Just update the thing and return a success indicator
         $dbw->update('watchlist', array('wl_notificationtimestamp' => $timestamp), array('wl_user' => $user->getID()), __METHOD__);
         $result['notificationtimestamp'] = is_null($timestamp) ? '' : wfTimestamp(TS_ISO_8601, $timestamp);
     } else {
         // First, log the invalid titles
         foreach ($pageSet->getInvalidTitles() as $title) {
             $r = array();
             $r['title'] = $title;
             $r['invalid'] = '';
             $result[] = $r;
         }
         foreach ($pageSet->getMissingPageIDs() as $p) {
             $page = array();
             $page['pageid'] = $p;
             $page['missing'] = '';
             $page['notwatched'] = '';
             $result[] = $page;
         }
         foreach ($pageSet->getMissingRevisionIDs() as $r) {
             $rev = array();
             $rev['revid'] = $r;
             $rev['missing'] = '';
             $rev['notwatched'] = '';
             $result[] = $rev;
         }
         // Now process the valid titles
         $lb = new LinkBatch($pageSet->getTitles());
         $dbw->update('watchlist', array('wl_notificationtimestamp' => $timestamp), array('wl_user' => $user->getID(), $lb->constructSet('wl', $dbw)), __METHOD__);
         // Query the results of our update
         $timestamps = array();
         $res = $dbw->select('watchlist', array('wl_namespace', 'wl_title', 'wl_notificationtimestamp'), array('wl_user' => $user->getID(), $lb->constructSet('wl', $dbw)), __METHOD__);
         foreach ($res as $row) {
             $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
         }
         // Now, put the valid titles into the result
         foreach ($pageSet->getTitles() as $title) {
             $ns = $title->getNamespace();
             $dbkey = $title->getDBkey();
             $r = array('ns' => intval($ns), 'title' => $title->getPrefixedText());
             if (!$title->exists()) {
                 $r['missing'] = '';
             }
             if (isset($timestamps[$ns]) && array_key_exists($dbkey, $timestamps[$ns])) {
                 $r['notificationtimestamp'] = '';
                 if ($timestamps[$ns][$dbkey] !== null) {
                     $r['notificationtimestamp'] = wfTimestamp(TS_ISO_8601, $timestamps[$ns][$dbkey]);
                 }
             } else {
                 $r['notwatched'] = '';
             }
             $result[] = $r;
         }
         $apiResult->setIndexedTagName($result, 'page');
     }
     $apiResult->addValue(null, $this->getModuleName(), $result);
 }
Пример #8
0
 public function execute()
 {
     // The data is hot but user-dependent, like page views, so we set vary cookies
     $this->getMain()->setCacheMode('anon-public-user-private');
     // Get parameters
     $params = $this->extractRequestParams();
     $text = $params['text'];
     $title = $params['title'];
     if ($title === null) {
         $titleProvided = false;
         // A title is needed for parsing, so arbitrarily choose one
         $title = 'API';
     } else {
         $titleProvided = true;
     }
     $page = $params['page'];
     $pageid = $params['pageid'];
     $oldid = $params['oldid'];
     $model = $params['contentmodel'];
     $format = $params['contentformat'];
     if (!is_null($page) && (!is_null($text) || $titleProvided)) {
         $this->dieUsage('The page parameter cannot be used together with the text and title parameters', 'params');
     }
     $prop = array_flip($params['prop']);
     if (isset($params['section'])) {
         $this->section = $params['section'];
         if (!preg_match('/^((T-)?\\d+|new)$/', $this->section)) {
             $this->dieUsage("The section parameter must be a valid section id or 'new'", "invalidsection");
         }
     } else {
         $this->section = false;
     }
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     // TODO: Does this still need $wgTitle?
     global $wgParser, $wgTitle;
     $redirValues = null;
     // Return result
     $result = $this->getResult();
     if (!is_null($oldid) || !is_null($pageid) || !is_null($page)) {
         if ($this->section === 'new') {
             $this->dieUsage('section=new cannot be combined with oldid, pageid or page parameters. ' . 'Please use text', 'params');
         }
         if (!is_null($oldid)) {
             // Don't use the parser cache
             $rev = Revision::newFromId($oldid);
             if (!$rev) {
                 $this->dieUsage("There is no revision ID {$oldid}", 'missingrev');
             }
             if (!$rev->userCan(Revision::DELETED_TEXT, $this->getUser())) {
                 $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             $pageObj = WikiPage::factory($titleObj);
             $popts = $this->makeParserOptions($pageObj, $params);
             // If for some reason the "oldid" is actually the current revision, it may be cached
             // Deliberately comparing $pageObj->getLatest() with $rev->getId(), rather than
             // checking $rev->isCurrent(), because $pageObj is what actually ends up being used,
             // and if its ->getLatest() is outdated, $rev->isCurrent() won't tell us that.
             if ($rev->getId() == $pageObj->getLatest()) {
                 // May get from/save to parser cache
                 $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
             } else {
                 // This is an old revision, so get the text differently
                 $this->content = $rev->getContent(Revision::FOR_THIS_USER, $this->getUser());
                 if ($this->section !== false) {
                     $this->content = $this->getSectionContent($this->content, 'r' . $rev->getId());
                 }
                 // Should we save old revision parses to the parser cache?
                 $p_result = $this->content->getParserOutput($titleObj, $rev->getId(), $popts);
             }
         } else {
             // Not $oldid, but $pageid or $page
             if ($params['redirects']) {
                 $reqParams = array('redirects' => '');
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                 } else {
                     // $page
                     $reqParams['titles'] = $page;
                 }
                 $req = new FauxRequest($reqParams);
                 $main = new ApiMain($req);
                 $pageSet = new ApiPageSet($main);
                 $pageSet->execute();
                 $redirValues = $pageSet->getRedirectTitlesAsResult($this->getResult());
                 $to = $page;
                 foreach ($pageSet->getRedirectTitles() as $title) {
                     $to = $title->getFullText();
                 }
                 $pageParams = array('title' => $to);
             } elseif (!is_null($pageid)) {
                 $pageParams = array('pageid' => $pageid);
             } else {
                 // $page
                 $pageParams = array('title' => $page);
             }
             $pageObj = $this->getTitleOrPageId($pageParams, 'fromdb');
             $titleObj = $pageObj->getTitle();
             if (!$titleObj || !$titleObj->exists()) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $wgTitle = $titleObj;
             if (isset($prop['revid'])) {
                 $oldid = $pageObj->getLatest();
             }
             $popts = $this->makeParserOptions($pageObj, $params);
             // Don't pollute the parser cache when setting options that aren't
             // in ParserOptions::optionsHash()
             /// @todo: This should be handled closer to the actual cache instead of here, see T110269
             $suppressCache = $params['disablepp'] || $params['disablelimitreport'] || $params['preview'] || $params['sectionpreview'] || $params['disabletidy'];
             if ($suppressCache) {
                 $this->content = $this->getContent($pageObj, $pageid);
                 $p_result = $this->content->getParserOutput($titleObj, null, $popts);
             } else {
                 // Potentially cached
                 $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
             }
         }
     } else {
         // Not $oldid, $pageid, $page. Hence based on $text
         $titleObj = Title::newFromText($title);
         if (!$titleObj || $titleObj->isExternal()) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         $wgTitle = $titleObj;
         if ($titleObj->canExist()) {
             $pageObj = WikiPage::factory($titleObj);
         } else {
             // Do like MediaWiki::initializeArticle()
             $article = Article::newFromTitle($titleObj, $this->getContext());
             $pageObj = $article->getPage();
         }
         $popts = $this->makeParserOptions($pageObj, $params);
         $textProvided = !is_null($text);
         if (!$textProvided) {
             if ($titleProvided && ($prop || $params['generatexml'])) {
                 $this->setWarning("'title' used without 'text', and parsed page properties were requested " . "(did you mean to use 'page' instead of 'title'?)");
             }
             // Prevent warning from ContentHandler::makeContent()
             $text = '';
         }
         // If we are parsing text, do not use the content model of the default
         // API title, but default to wikitext to keep BC.
         if ($textProvided && !$titleProvided && is_null($model)) {
             $model = CONTENT_MODEL_WIKITEXT;
             $this->setWarning("No 'title' or 'contentmodel' was given, assuming {$model}.");
         }
         try {
             $this->content = ContentHandler::makeContent($text, $titleObj, $model, $format);
         } catch (MWContentSerializationException $ex) {
             $this->dieUsage($ex->getMessage(), 'parseerror');
         }
         if ($this->section !== false) {
             if ($this->section === 'new') {
                 // Insert the section title above the content.
                 if (!is_null($params['sectiontitle']) && $params['sectiontitle'] !== '') {
                     $this->content = $this->content->addSectionHeader($params['sectiontitle']);
                 }
             } else {
                 $this->content = $this->getSectionContent($this->content, $titleObj->getPrefixedText());
             }
         }
         if ($params['pst'] || $params['onlypst']) {
             $this->pstContent = $this->content->preSaveTransform($titleObj, $this->getUser(), $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array = array();
             $result_array['text'] = $this->pstContent->serialize($format);
             $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
             if (isset($prop['wikitext'])) {
                 $result_array['wikitext'] = $this->content->serialize($format);
                 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
             }
             if (!is_null($params['summary']) || !is_null($params['sectiontitle']) && $this->section === 'new') {
                 $result_array['parsedsummary'] = $this->formatSummary($titleObj, $params);
                 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
             }
             $result->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         // Not cached (save or load)
         if ($params['pst']) {
             $p_result = $this->pstContent->getParserOutput($titleObj, null, $popts);
         } else {
             $p_result = $this->content->getParserOutput($titleObj, null, $popts);
         }
     }
     $result_array = array();
     $result_array['title'] = $titleObj->getPrefixedText();
     $result_array['pageid'] = $pageid ? $pageid : $pageObj->getId();
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if ($params['disabletoc']) {
         $p_result->setTOCEnabled(false);
     }
     if (isset($prop['text'])) {
         $result_array['text'] = $p_result->getText();
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
     }
     if (!is_null($params['summary']) || !is_null($params['sectiontitle']) && $this->section === 'new') {
         $result_array['parsedsummary'] = $this->formatSummary($titleObj, $params);
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
     }
     if (isset($prop['langlinks'])) {
         $langlinks = $p_result->getLanguageLinks();
         if ($params['effectivelanglinks']) {
             // Link flags are ignored for now, but may in the future be
             // included in the result.
             $linkFlags = array();
             Hooks::run('LanguageLinks', array($titleObj, &$langlinks, &$linkFlags));
         }
     } else {
         $langlinks = false;
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($langlinks);
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['categorieshtml'])) {
         $result_array['categorieshtml'] = $this->categoriesHtml($p_result->getCategories());
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'categorieshtml';
     }
     if (isset($prop['links'])) {
         $result_array['links'] = $this->formatLinks($p_result->getLinks());
     }
     if (isset($prop['templates'])) {
         $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
     }
     if (isset($prop['images'])) {
         $result_array['images'] = array_keys($p_result->getImages());
     }
     if (isset($prop['externallinks'])) {
         $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
     }
     if (isset($prop['sections'])) {
         $result_array['sections'] = $p_result->getSections();
     }
     if (isset($prop['displaytitle'])) {
         $result_array['displaytitle'] = $p_result->getDisplayTitle() ? $p_result->getDisplayTitle() : $titleObj->getPrefixedText();
     }
     if (isset($prop['headitems']) || isset($prop['headhtml'])) {
         $context = $this->getContext();
         $context->setTitle($titleObj);
         $context->getOutput()->addParserOutputMetadata($p_result);
         if (isset($prop['headitems'])) {
             $headItems = $this->formatHeadItems($p_result->getHeadItems());
             $css = $this->formatCss($context->getOutput()->buildCssLinksArray());
             $scripts = array($context->getOutput()->getHeadScripts());
             $result_array['headitems'] = array_merge($headItems, $css, $scripts);
         }
         if (isset($prop['headhtml'])) {
             $result_array['headhtml'] = $context->getOutput()->headElement($context->getSkin());
             $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'headhtml';
         }
     }
     if (isset($prop['modules'])) {
         $result_array['modules'] = array_values(array_unique($p_result->getModules()));
         $result_array['modulescripts'] = array_values(array_unique($p_result->getModuleScripts()));
         $result_array['modulestyles'] = array_values(array_unique($p_result->getModuleStyles()));
         // To be removed in 1.27
         $result_array['modulemessages'] = array();
         $this->setWarning('modulemessages is deprecated since MediaWiki 1.26');
     }
     if (isset($prop['jsconfigvars'])) {
         $result_array['jsconfigvars'] = ApiResult::addMetadataToResultVars($p_result->getJsConfigVars());
     }
     if (isset($prop['encodedjsconfigvars'])) {
         $result_array['encodedjsconfigvars'] = FormatJson::encode($p_result->getJsConfigVars(), false, FormatJson::ALL_OK);
         $result_array[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
     }
     if (isset($prop['modules']) && !isset($prop['jsconfigvars']) && !isset($prop['encodedjsconfigvars'])) {
         $this->setWarning("Property 'modules' was set but not 'jsconfigvars' " . "or 'encodedjsconfigvars'. Configuration variables are necessary " . "for proper module usage.");
     }
     if (isset($prop['indicators'])) {
         $result_array['indicators'] = (array) $p_result->getIndicators();
         ApiResult::setArrayType($result_array['indicators'], 'BCkvp', 'name');
     }
     if (isset($prop['iwlinks'])) {
         $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks());
     }
     if (isset($prop['wikitext'])) {
         $result_array['wikitext'] = $this->content->serialize($format);
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
         if (!is_null($this->pstContent)) {
             $result_array['psttext'] = $this->pstContent->serialize($format);
             $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'psttext';
         }
     }
     if (isset($prop['properties'])) {
         $result_array['properties'] = (array) $p_result->getProperties();
         ApiResult::setArrayType($result_array['properties'], 'BCkvp', 'name');
     }
     if (isset($prop['limitreportdata'])) {
         $result_array['limitreportdata'] = $this->formatLimitReportData($p_result->getLimitReportData());
     }
     if (isset($prop['limitreporthtml'])) {
         $result_array['limitreporthtml'] = EditPage::getPreviewLimitReport($p_result);
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'limitreporthtml';
     }
     if (isset($prop['parsetree']) || $params['generatexml']) {
         if ($this->content->getModel() != CONTENT_MODEL_WIKITEXT) {
             $this->dieUsage("parsetree is only supported for wikitext content", "notwikitext");
         }
         $wgParser->startExternalParse($titleObj, $popts, Parser::OT_PREPROCESS);
         $dom = $wgParser->preprocessToDom($this->content->getNativeData());
         if (is_callable(array($dom, 'saveXML'))) {
             $xml = $dom->saveXML();
         } else {
             $xml = $dom->__toString();
         }
         $result_array['parsetree'] = $xml;
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsetree';
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'iwlinks' => 'iw', 'sections' => 's', 'headitems' => 'hi', 'modules' => 'm', 'indicators' => 'ind', 'modulescripts' => 'm', 'modulestyles' => 'm', 'modulemessages' => 'm', 'properties' => 'pp', 'limitreportdata' => 'lr');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
 }
Пример #9
0
 /**
  * Purges the cache of a page
  */
 public function execute()
 {
     $user = $this->getUser();
     $params = $this->extractRequestParams();
     if (!$user->isAllowed('purge') && !$this->getMain()->isInternalMode() && !$this->getRequest()->wasPosted()) {
         $this->dieUsageMsg(array('mustbeposted', $this->getModuleName()));
     }
     $forceLinkUpdate = $params['forcelinkupdate'];
     $pageSet = new ApiPageSet($this);
     $pageSet->execute();
     $result = array();
     foreach ($pageSet->getInvalidTitles() as $title) {
         $r = array();
         $r['title'] = $title;
         $r['invalid'] = '';
         $result[] = $r;
     }
     foreach ($pageSet->getMissingPageIDs() as $p) {
         $page = array();
         $page['pageid'] = $p;
         $page['missing'] = '';
         $result[] = $page;
     }
     foreach ($pageSet->getMissingRevisionIDs() as $r) {
         $rev = array();
         $rev['revid'] = $r;
         $rev['missing'] = '';
         $result[] = $rev;
     }
     foreach ($pageSet->getTitles() as $title) {
         $r = array();
         ApiQueryBase::addTitleInfo($r, $title);
         if (!$title->exists()) {
             $r['missing'] = '';
             $result[] = $r;
             continue;
         }
         $page = WikiPage::factory($title);
         $page->doPurge();
         // Directly purge and skip the UI part of purge().
         $r['purged'] = '';
         if ($forceLinkUpdate) {
             if (!$user->pingLimiter()) {
                 global $wgParser, $wgEnableParserCache;
                 $popts = $page->makeParserOptions('canonical');
                 $p_result = $wgParser->parse($page->getRawText(), $title, $popts, true, true, $page->getLatest());
                 # Update the links tables
                 $updates = $p_result->getSecondaryDataUpdates($title);
                 DataUpdate::runUpdates($updates);
                 $r['linkupdate'] = '';
                 if ($wgEnableParserCache) {
                     $pcache = ParserCache::singleton();
                     $pcache->save($p_result, $page, $popts);
                 }
             } else {
                 $error = $this->parseMsg(array('actionthrottledtext'));
                 $this->setWarning($error['info']);
                 $forceLinkUpdate = false;
             }
         }
         $result[] = $r;
     }
     $apiResult = $this->getResult();
     $apiResult->setIndexedTagName($result, 'page');
     $apiResult->addValue(null, $this->getModuleName(), $result);
 }