Beispiel #1
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'];
     $page = $params['page'];
     $oldid = $params['oldid'];
     if (!is_null($page) && (!is_null($text) || $title != "API")) {
         $this->dieUsage("The page parameter cannot be used together with the text and title parameters", 'params');
     }
     $prop = array_flip($params['prop']);
     $revid = false;
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     global $wgParser, $wgUser, $wgTitle, $wgEnableParserCache;
     $popts = new ParserOptions();
     $popts->setTidy(true);
     $popts->enableLimitReport();
     $redirValues = null;
     if (!is_null($oldid) || !is_null($page)) {
         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->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $text = $rev->getText(Revision::FOR_THIS_USER);
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             $p_result = $wgParser->parse($text, $titleObj, $popts);
         } else {
             if ($params['redirects']) {
                 $req = new FauxRequest(array('action' => 'query', 'redirects' => '', 'titles' => $page));
                 $main = new ApiMain($req);
                 $main->execute();
                 $data = $main->getResultData();
                 $redirValues = @$data['query']['redirects'];
                 $to = $page;
                 foreach ((array) $redirValues as $r) {
                     $to = $r['to'];
                 }
             } else {
                 $to = $page;
             }
             $titleObj = Title::newFromText($to);
             if (!$titleObj) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $articleObj = new Article($titleObj);
             if (isset($prop['revid'])) {
                 $oldid = $articleObj->getRevIdFetched();
             }
             // Try the parser cache first
             $p_result = false;
             $pcache = ParserCache::singleton();
             if ($wgEnableParserCache) {
                 $p_result = $pcache->get($articleObj, $wgUser);
             }
             if (!$p_result) {
                 $p_result = $wgParser->parse($articleObj->getContent(), $titleObj, $popts);
                 if ($wgEnableParserCache) {
                     $pcache->save($p_result, $articleObj, $popts);
                 }
             }
         }
     } else {
         $titleObj = Title::newFromText($title);
         if (!$titleObj) {
             $titleObj = Title::newFromText("API");
         }
         $wgTitle = $titleObj;
         if ($params['pst'] || $params['onlypst']) {
             $text = $wgParser->preSaveTransform($text, $titleObj, $wgUser, $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array['text'] = array();
             $this->getResult()->setContent($result_array['text'], $text);
             $this->getResult()->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         $p_result = $wgParser->parse($text, $titleObj, $popts);
     }
     // Return result
     $result = $this->getResult();
     $result_array = array();
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if (isset($prop['text'])) {
         $result_array['text'] = array();
         $result->setContent($result_array['text'], $p_result->getText());
     }
     if (!is_null($params['summary'])) {
         $result_array['parsedsummary'] = array();
         $result->setContent($result_array['parsedsummary'], $wgUser->getSkin()->formatComment($params['summary'], $titleObj));
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     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'])) {
         $result_array['headitems'] = $this->formatHeadItems($p_result->getHeadItems());
     }
     if (isset($prop['headhtml'])) {
         $out = new OutputPage();
         $out->addParserOutputNoText($p_result);
         $result_array['headhtml'] = array();
         $result->setContent($result_array['headhtml'], $out->headElement($wgUser->getSkin()));
     }
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'sections' => 's', 'headitems' => 'hi');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
 }
Beispiel #2
0
 /**
  * Get parser options suitable for rendering the primary article wikitext
  * @param $canonical boolean Determines that the generated options must not depend on user preferences (see bug 14404)
  * @return mixed ParserOptions object or boolean false
  */
 public function getParserOptions($canonical = false)
 {
     global $wgUser, $wgLanguageCode;
     if (!$this->mParserOptions || $canonical) {
         $user = !$canonical ? $wgUser : new User();
         $parserOptions = new ParserOptions($user);
         $parserOptions->setTidy(true);
         $parserOptions->enableLimitReport();
         if ($canonical) {
             $parserOptions->setUserLang($wgLanguageCode);
             # Must be set explicitely
             return $parserOptions;
         }
         $this->mParserOptions = $parserOptions;
     }
     // Clone to allow modifications of the return value without affecting cache
     return clone $this->mParserOptions;
 }
Beispiel #3
0
 /**
  * Prepare text which is about to be saved.
  * Returns a stdclass with source, pst and output members
  */
 public function prepareTextForEdit($text, $revid = null)
 {
     if ($this->mPreparedEdit && $this->mPreparedEdit->newText == $text && $this->mPreparedEdit->revid == $revid) {
         // Already prepared
         return $this->mPreparedEdit;
     }
     global $wgParser;
     $edit = (object) array();
     $edit->revid = $revid;
     $edit->newText = $text;
     $edit->pst = $this->preSaveTransform($text);
     $options = new ParserOptions();
     $options->setTidy(true);
     $options->enableLimitReport();
     $edit->output = $wgParser->parse($edit->pst, $this->mTitle, $options, true, true, $revid);
     $edit->oldText = $this->getContent();
     $this->mPreparedEdit = $edit;
     return $edit;
 }
 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'];
     $page = $params['page'];
     $pageid = $params['pageid'];
     $oldid = $params['oldid'];
     if (!is_null($page) && (!is_null($text) || $title != 'API')) {
         $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'];
     } else {
         $this->section = false;
     }
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     global $wgParser, $wgUser, $wgTitle, $wgLang;
     // Currently unnecessary, code to act as a safeguard against any change in current behaviour of uselang breaks
     $oldLang = null;
     if (isset($params['uselang']) && $params['uselang'] != $wgLang->getCode()) {
         $oldLang = $wgLang;
         // Backup wgLang
         $wgLang = Language::factory($params['uselang']);
     }
     $popts = new ParserOptions();
     $popts->setTidy(true);
     $popts->enableLimitReport(!$params['disablepp']);
     $redirValues = null;
     // Return result
     $result = $this->getResult();
     if (!is_null($oldid) || !is_null($pageid) || !is_null($page)) {
         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->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             // If for some reason the "oldid" is actually the current revision, it may be cached
             if ($titleObj->getLatestRevID() === intval($oldid)) {
                 $articleObj = new Article($titleObj, 0);
                 $p_result = $this->getParsedSectionOrText($articleObj, $titleObj, $popts, $pageid, isset($prop['wikitext']));
             } else {
                 // This is an old revision, so get the text differently
                 $this->text = $rev->getText(Revision::FOR_THIS_USER);
                 $wgTitle = $titleObj;
                 if ($this->section !== false) {
                     $this->text = $this->getSectionText($this->text, 'r' . $rev->getId());
                 }
                 $p_result = $wgParser->parse($this->text, $titleObj, $popts);
             }
         } else {
             // Not $oldid
             if ($params['redirects']) {
                 $reqParams = array('action' => 'query', 'redirects' => '');
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                 } else {
                     // $page
                     $reqParams['titles'] = $page;
                 }
                 $req = new FauxRequest($reqParams);
                 $main = new ApiMain($req);
                 $main->execute();
                 $data = $main->getResultData();
                 $redirValues = isset($data['query']['redirects']) ? $data['query']['redirects'] : array();
                 $to = $page;
                 foreach ((array) $redirValues as $r) {
                     $to = $r['to'];
                 }
                 $titleObj = Title::newFromText($to);
             } else {
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                     $titleObj = Title::newFromID($pageid);
                 } else {
                     // $page
                     $to = $page;
                     $titleObj = Title::newFromText($to);
                 }
             }
             if (!is_null($pageid)) {
                 if (!$titleObj) {
                     // Still throw nosuchpageid error if pageid was provided
                     $this->dieUsageMsg(array('nosuchpageid', $pageid));
                 }
             } elseif (!$titleObj || !$titleObj->exists()) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $wgTitle = $titleObj;
             $articleObj = new Article($titleObj, 0);
             if (isset($prop['revid'])) {
                 $oldid = $articleObj->getRevIdFetched();
             }
             $p_result = $this->getParsedSectionOrText($articleObj, $titleObj, $popts, $pageid, isset($prop['wikitext']));
         }
     } else {
         // Not $oldid, $pageid, $page. Hence based on $text
         $this->text = $text;
         $titleObj = Title::newFromText($title);
         if (!$titleObj) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         $wgTitle = $titleObj;
         if ($this->section !== false) {
             $this->text = $this->getSectionText($this->text, $titleObj->getText());
         }
         if ($params['pst'] || $params['onlypst']) {
             $this->pstText = $wgParser->preSaveTransform($this->text, $titleObj, $wgUser, $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array['text'] = array();
             $result->setContent($result_array['text'], $this->pstText);
             if (isset($prop['wikitext'])) {
                 $result_array['wikitext'] = array();
                 $result->setContent($result_array['wikitext'], $this->text);
             }
             $result->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         $p_result = $wgParser->parse($params['pst'] ? $this->pstText : $this->text, $titleObj, $popts);
     }
     $result_array = array();
     $result_array['title'] = $titleObj->getPrefixedText();
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if (isset($prop['text'])) {
         $result_array['text'] = array();
         $result->setContent($result_array['text'], $p_result->getText());
     }
     if (!is_null($params['summary'])) {
         $result_array['parsedsummary'] = array();
         $result->setContent($result_array['parsedsummary'], $wgUser->getSkin()->formatComment($params['summary'], $titleObj));
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
     }
     if (isset($prop['languageshtml'])) {
         $languagesHtml = $this->languagesHtml($p_result->getLanguageLinks());
         $result_array['languageshtml'] = array();
         $result->setContent($result_array['languageshtml'], $languagesHtml);
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['categorieshtml'])) {
         $categoriesHtml = $this->categoriesHtml($p_result->getCategories());
         $result_array['categorieshtml'] = array();
         $result->setContent($result_array['categorieshtml'], $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 = new RequestContext();
         $context->getOutput()->addParserOutputNoText($p_result);
         if (isset($prop['headitems'])) {
             $headItems = $this->formatHeadItems($p_result->getHeadItems());
             $context->getSkin()->setupUserCss($context->getOutput());
             $css = $this->formatCss($context->getOutput()->buildCssLinksArray());
             $scripts = array($context->getOutput()->getHeadScripts($context->getSkin()));
             $result_array['headitems'] = array_merge($headItems, $css, $scripts);
         }
         if (isset($prop['headhtml'])) {
             $result_array['headhtml'] = array();
             $result->setContent($result_array['headhtml'], $context->getOutput()->headElement($context->getSkin()));
         }
     }
     if (isset($prop['iwlinks'])) {
         $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks());
     }
     if (isset($prop['wikitext'])) {
         $result_array['wikitext'] = array();
         $result->setContent($result_array['wikitext'], $this->text);
         if (!is_null($this->pstText)) {
             $result_array['psttext'] = array();
             $result->setContent($result_array['psttext'], $this->pstText);
         }
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'iwlinks' => 'iw', 'sections' => 's', 'headitems' => 'hi');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
     if (!is_null($oldLang)) {
         $wgLang = $oldLang;
         // Reset $wgLang to $oldLang
     }
 }
Beispiel #5
0
 /**
  * Do standard deferred updates after page edit.
  * Update links tables, site stats, search index and message cache.
  * Purges pages that include this page if the text was changed here.
  * Every 100th edit, prune the recent changes table.
  *
  * @private
  * @param $text New text of the article
  * @param $summary Edit summary
  * @param $minoredit Minor edit
  * @param $timestamp_of_pagechange Timestamp associated with the page change
  * @param $newid rev_id value of the new revision
  * @param $changed Whether or not the content actually changed
  */
 public function editUpdates($text, $summary, $minoredit, $timestamp_of_pagechange, $newid, $changed = true)
 {
     global $wgDeferredUpdateList, $wgMessageCache, $wgUser, $wgParser, $wgEnableParserCache;
     wfProfileIn(__METHOD__);
     # Parse the text
     # Be careful not to double-PST: $text is usually already PST-ed once
     if (!$this->mPreparedEdit || $this->mPreparedEdit->output->getFlag('vary-revision')) {
         wfDebug(__METHOD__ . ": No prepared edit or vary-revision is set...\n");
         $editInfo = $this->prepareTextForEdit($text, $newid);
     } else {
         wfDebug(__METHOD__ . ": No vary-revision, using prepared edit...\n");
         $editInfo = $this->mPreparedEdit;
     }
     # Save it to the parser cache
     if ($wgEnableParserCache) {
         $popts = new ParserOptions();
         $popts->setTidy(true);
         $popts->enableLimitReport();
         $parserCache = ParserCache::singleton();
         $parserCache->save($editInfo->output, $this, $popts);
     }
     # Update the links tables
     $u = new LinksUpdate($this->mTitle, $editInfo->output);
     $u->doUpdate();
     wfRunHooks('ArticleEditUpdates', array(&$this, &$editInfo, $changed));
     if (wfRunHooks('ArticleEditUpdatesDeleteFromRecentchanges', array(&$this))) {
         if (0 == mt_rand(0, 99)) {
             // Flush old entries from the `recentchanges` table; we do this on
             // random requests so as to avoid an increase in writes for no good reason
             global $wgRCMaxAge;
             $dbw = wfGetDB(DB_MASTER);
             $cutoff = $dbw->timestamp(time() - $wgRCMaxAge);
             $recentchanges = $dbw->tableName('recentchanges');
             $sql = "DELETE FROM {$recentchanges} WHERE rc_timestamp < '{$cutoff}'";
             $dbw->query($sql);
         }
     }
     $id = $this->getID();
     $title = $this->mTitle->getPrefixedDBkey();
     $shortTitle = $this->mTitle->getDBkey();
     if (0 == $id) {
         wfProfileOut(__METHOD__);
         return;
     }
     $u = new SiteStatsUpdate(0, 1, $this->mGoodAdjustment, $this->mTotalAdjustment);
     array_push($wgDeferredUpdateList, $u);
     $u = new SearchUpdate($id, $title, $text);
     array_push($wgDeferredUpdateList, $u);
     # If this is another user's talk page, update newtalk
     # Don't do this if $changed = false otherwise some idiot can null-edit a
     # load of user talk pages and piss people off, nor if it's a minor edit
     # by a properly-flagged bot.
     if ($this->mTitle->getNamespace() == NS_USER_TALK && $shortTitle != $wgUser->getTitleKey() && $changed && !($minoredit && $wgUser->isAllowed('nominornewtalk'))) {
         if (wfRunHooks('ArticleEditUpdateNewTalk', array(&$this))) {
             $other = User::newFromName($shortTitle, false);
             if (!$other) {
                 wfDebug(__METHOD__ . ": invalid username\n");
             } elseif (User::isIP($shortTitle)) {
                 // An anonymous user
                 $other->setNewtalk(true);
             } elseif ($other->isLoggedIn()) {
                 $other->setNewtalk(true);
             } else {
                 wfDebug(__METHOD__ . ": don't need to notify a nonexistent user\n");
             }
         }
     }
     if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) {
         $wgMessageCache->replace($shortTitle, $text);
     }
     wfProfileOut(__METHOD__);
 }