public function execute() { global $wgUser; $params = $this->extractRequestParams(); if (is_null($params['text']) && is_null($params['appendtext']) && is_null($params['prependtext']) && $params['undo'] == 0) { $this->dieUsageMsg(array('missingtext')); } $titleObj = Title::newFromText($params['title']); if (!$titleObj || $titleObj->isExternal()) { $this->dieUsageMsg(array('invalidtitle', $params['title'])); } if ($params['redirect']) { if ($titleObj->isRedirect()) { $oldTitle = $titleObj; $titles = Title::newFromRedirectArray(Revision::newFromTitle($oldTitle)->getText(Revision::FOR_THIS_USER)); $redirValues = array(); foreach ($titles as $id => $newTitle) { if (!isset($titles[$id - 1])) { $titles[$id - 1] = $oldTitle; } $redirValues[] = array('from' => $titles[$id - 1]->getPrefixedText(), 'to' => $newTitle->getPrefixedText()); $titleObj = $newTitle; } $this->getResult()->setIndexedTagName($redirValues, 'r'); $this->getResult()->addValue(null, 'redirects', $redirValues); } } // Some functions depend on $wgTitle == $ep->mTitle global $wgTitle; $wgTitle = $titleObj; if ($params['createonly'] && $titleObj->exists()) { $this->dieUsageMsg(array('createonly-exists')); } if ($params['nocreate'] && !$titleObj->exists()) { $this->dieUsageMsg(array('nocreate-missing')); } // Now let's check whether we're even allowed to do this $errors = $titleObj->getUserPermissionsErrors('edit', $wgUser); if (!$titleObj->exists()) { $errors = array_merge($errors, $titleObj->getUserPermissionsErrors('create', $wgUser)); } if (count($errors)) { $this->dieUsageMsg($errors[0]); } $articleObj = new Article($titleObj); $toMD5 = $params['text']; if (!is_null($params['appendtext']) || !is_null($params['prependtext'])) { // For non-existent pages, Article::getContent() // returns an interface message rather than '' // We do want getContent()'s behavior for non-existent // MediaWiki: pages, though if ($articleObj->getID() == 0 && $titleObj->getNamespace() != NS_MEDIAWIKI) { $content = ''; } else { $content = $articleObj->getContent(); } if (!is_null($params['section'])) { // Process the content for section edits global $wgParser; $section = intval($params['section']); $content = $wgParser->getSection($content, $section, false); if ($content === false) { $this->dieUsage("There is no section {$section}.", 'nosuchsection'); } } $params['text'] = $params['prependtext'] . $content . $params['appendtext']; $toMD5 = $params['prependtext'] . $params['appendtext']; } if ($params['undo'] > 0) { if ($params['undoafter'] > 0) { if ($params['undo'] < $params['undoafter']) { list($params['undo'], $params['undoafter']) = array($params['undoafter'], $params['undo']); } $undoafterRev = Revision::newFromID($params['undoafter']); } $undoRev = Revision::newFromID($params['undo']); if (is_null($undoRev) || $undoRev->isDeleted(Revision::DELETED_TEXT)) { $this->dieUsageMsg(array('nosuchrevid', $params['undo'])); } if ($params['undoafter'] == 0) { $undoafterRev = $undoRev->getPrevious(); } if (is_null($undoafterRev) || $undoafterRev->isDeleted(Revision::DELETED_TEXT)) { $this->dieUsageMsg(array('nosuchrevid', $params['undoafter'])); } if ($undoRev->getPage() != $articleObj->getID()) { $this->dieUsageMsg(array('revwrongpage', $undoRev->getID(), $titleObj->getPrefixedText())); } if ($undoafterRev->getPage() != $articleObj->getID()) { $this->dieUsageMsg(array('revwrongpage', $undoafterRev->getID(), $titleObj->getPrefixedText())); } $newtext = $articleObj->getUndoText($undoRev, $undoafterRev); if ($newtext === false) { $this->dieUsageMsg(array('undo-failure')); } $params['text'] = $newtext; // If no summary was given and we only undid one rev, // use an autosummary if (is_null($params['summary']) && $titleObj->getNextRevisionID($undoafterRev->getID()) == $params['undo']) { $params['summary'] = wfMsgForContent('undo-summary', $params['undo'], $undoRev->getUserText()); } } // See if the MD5 hash checks out if (!is_null($params['md5']) && md5($toMD5) !== $params['md5']) { $this->dieUsageMsg(array('hashcheckfailed')); } $ep = new EditPage($articleObj); // EditPage wants to parse its stuff from a WebRequest // That interface kind of sucks, but it's workable $reqArr = array('wpTextbox1' => $params['text'], 'wpEditToken' => $params['token'], 'wpIgnoreBlankSummary' => ''); if (!is_null($params['summary'])) { $reqArr['wpSummary'] = $params['summary']; } // Watch out for basetimestamp == '' // wfTimestamp() treats it as NOW, almost certainly causing an edit conflict if (!is_null($params['basetimestamp']) && $params['basetimestamp'] != '') { $reqArr['wpEdittime'] = wfTimestamp(TS_MW, $params['basetimestamp']); } else { $reqArr['wpEdittime'] = $articleObj->getTimestamp(); } if (!is_null($params['starttimestamp']) && $params['starttimestamp'] != '') { $reqArr['wpStarttime'] = wfTimestamp(TS_MW, $params['starttimestamp']); } else { $reqArr['wpStarttime'] = wfTimestampNow(); // Fake wpStartime } if ($params['minor'] || !$params['notminor'] && $wgUser->getOption('minordefault')) { $reqArr['wpMinoredit'] = ''; } if ($params['recreate']) { $reqArr['wpRecreate'] = ''; } if (!is_null($params['section'])) { $section = intval($params['section']); if ($section == 0 && $params['section'] != '0' && $params['section'] != 'new') { $this->dieUsage("The section parameter must be set to an integer or 'new'", "invalidsection"); } $reqArr['wpSection'] = $params['section']; } else { $reqArr['wpSection'] = ''; } $watch = $this->getWatchlistValue($params['watchlist'], $titleObj); // Deprecated parameters if ($params['watch']) { $watch = true; } elseif ($params['unwatch']) { $watch = false; } if ($watch) { $reqArr['wpWatchthis'] = ''; } $req = new FauxRequest($reqArr, true); $ep->importFormData($req); // Run hooks // Handle CAPTCHA parameters global $wgRequest; if (!is_null($params['captchaid'])) { $wgRequest->setVal('wpCaptchaId', $params['captchaid']); } if (!is_null($params['captchaword'])) { $wgRequest->setVal('wpCaptchaWord', $params['captchaword']); } $r = array(); if (!wfRunHooks('APIEditBeforeSave', array($ep, $ep->textbox1, &$r))) { if (count($r)) { $r['result'] = 'Failure'; $this->getResult()->addValue(null, $this->getModuleName(), $r); return; } else { $this->dieUsageMsg(array('hookaborted')); } } // Do the actual save $oldRevId = $articleObj->getRevIdFetched(); $result = null; // Fake $wgRequest for some hooks inside EditPage // FIXME: This interface SUCKS $oldRequest = $wgRequest; $wgRequest = $req; $retval = $ep->internalAttemptSave($result, $wgUser->isAllowed('bot') && $params['bot']); $wgRequest = $oldRequest; global $wgMaxArticleSize; switch ($retval) { case EditPage::AS_HOOK_ERROR: case EditPage::AS_HOOK_ERROR_EXPECTED: $this->dieUsageMsg(array('hookaborted')); case EditPage::AS_IMAGE_REDIRECT_ANON: $this->dieUsageMsg(array('noimageredirect-anon')); case EditPage::AS_IMAGE_REDIRECT_LOGGED: $this->dieUsageMsg(array('noimageredirect-logged')); case EditPage::AS_SPAM_ERROR: $this->dieUsageMsg(array('spamdetected', $result['spam'])); case EditPage::AS_FILTERING: $this->dieUsageMsg(array('filtered')); case EditPage::AS_BLOCKED_PAGE_FOR_USER: $this->dieUsageMsg(array('blockedtext')); case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED: case EditPage::AS_CONTENT_TOO_BIG: $this->dieUsageMsg(array('contenttoobig', $wgMaxArticleSize)); case EditPage::AS_READ_ONLY_PAGE_ANON: $this->dieUsageMsg(array('noedit-anon')); case EditPage::AS_READ_ONLY_PAGE_LOGGED: $this->dieUsageMsg(array('noedit')); case EditPage::AS_READ_ONLY_PAGE: $this->dieReadOnly(); case EditPage::AS_RATE_LIMITED: $this->dieUsageMsg(array('actionthrottledtext')); case EditPage::AS_ARTICLE_WAS_DELETED: $this->dieUsageMsg(array('wasdeleted')); case EditPage::AS_NO_CREATE_PERMISSION: $this->dieUsageMsg(array('nocreate-loggedin')); case EditPage::AS_BLANK_ARTICLE: $this->dieUsageMsg(array('blankpage')); case EditPage::AS_CONFLICT_DETECTED: $this->dieUsageMsg(array('editconflict')); // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary case EditPage::AS_TEXTBOX_EMPTY: $this->dieUsageMsg(array('emptynewsection')); case EditPage::AS_SUCCESS_NEW_ARTICLE: $r['new'] = ''; case EditPage::AS_SUCCESS_UPDATE: $r['result'] = 'Success'; $r['pageid'] = intval($titleObj->getArticleID()); $r['title'] = $titleObj->getPrefixedText(); // HACK: We create a new Article object here because getRevIdFetched() // refuses to be run twice, and because Title::getLatestRevId() // won't fetch from the master unless we select for update, which we // don't want to do. $newArticle = new Article($titleObj); $newRevId = $newArticle->getRevIdFetched(); if ($newRevId == $oldRevId) { $r['nochange'] = ''; } else { $r['oldrevid'] = intval($oldRevId); $r['newrevid'] = intval($newRevId); $r['newtimestamp'] = wfTimestamp(TS_ISO_8601, $newArticle->getTimestamp()); } break; case EditPage::AS_SUMMARY_NEEDED: $this->dieUsageMsg(array('summaryrequired')); case EditPage::AS_END: // This usually means some kind of race condition // or DB weirdness occurred. Fall through to throw an unknown // error. // This needs fixing higher up, as Article::doEdit should be // used rather than Article::updateArticle, so that specific // error conditions can be returned // This usually means some kind of race condition // or DB weirdness occurred. Fall through to throw an unknown // error. // This needs fixing higher up, as Article::doEdit should be // used rather than Article::updateArticle, so that specific // error conditions can be returned default: $this->dieUsageMsg(array('unknownerror', $retval)); } $this->getResult()->addValue(null, $this->getModuleName(), $r); }
/** * This is the default action of the index.php entry point: just view the * page of the given title. */ public function view() { global $wgUser, $wgOut, $wgRequest, $wgParser; global $wgUseFileCache, $wgUseETag; wfProfileIn(__METHOD__); # Get variables from query string $oldid = $this->getOldID(); $parserCache = ParserCache::singleton(); $parserOptions = $this->getParserOptions(); # Render printable version, use printable version cache if ($wgOut->isPrintable()) { $parserOptions->setIsPrintable(true); $parserOptions->setEditSection(false); } else { if ($wgUseETag && !$this->mTitle->quickUserCan('edit')) { $parserOptions->setEditSection(false); } } # Try client and file cache if ($oldid === 0 && $this->checkTouched()) { if ($wgUseETag) { $wgOut->setETag($parserCache->getETag($this, $parserOptions)); } # Is it client cached? if ($wgOut->checkLastModified($this->getTouched())) { wfDebug(__METHOD__ . ": done 304\n"); wfProfileOut(__METHOD__); return; # Try file cache } else { if ($wgUseFileCache && $this->tryFileCache()) { wfDebug(__METHOD__ . ": done file cache\n"); # tell wgOut that output is taken care of $wgOut->disable(); $this->viewUpdates(); wfProfileOut(__METHOD__); return; } } } # getOldID may want us to redirect somewhere else if ($this->mRedirectUrl) { $wgOut->redirect($this->mRedirectUrl); wfDebug(__METHOD__ . ": redirecting due to oldid\n"); wfProfileOut(__METHOD__); return; } $wgOut->setArticleFlag(true); # Set page title (may be overridden by DISPLAYTITLE) $wgOut->setPageTitle($this->mTitle->getPrefixedText()); # If we got diff in the query, we want to see a diff page instead of the article. if ($wgRequest->getCheck('diff')) { wfDebug(__METHOD__ . ": showing diff page\n"); $this->showDiffPage(); wfProfileOut(__METHOD__); return; } # Allow frames by default $wgOut->allowClickjacking(); if (!$wgUseETag && !$this->mTitle->quickUserCan('edit')) { $parserOptions->setEditSection(false); } # Should the parser cache be used? $useParserCache = $this->useParserCache($oldid); wfDebug('Article::view using parser cache: ' . ($useParserCache ? 'yes' : 'no') . "\n"); if ($wgUser->getStubThreshold()) { wfIncrStats('pcache_miss_stub'); } $wasRedirected = $this->showRedirectedFromHeader(); $this->showNamespaceHeader(); # Iterate through the possible ways of constructing the output text. # Keep going until $outputDone is set, or we run out of things to do. $pass = 0; $outputDone = false; $this->mParserOutput = false; while (!$outputDone && ++$pass) { switch ($pass) { case 1: wfRunHooks('ArticleViewHeader', array(&$this, &$outputDone, &$useParserCache)); break; case 2: # Try the parser cache if ($useParserCache) { $this->mParserOutput = $parserCache->get($this, $parserOptions); if ($this->mParserOutput !== false) { wfDebug(__METHOD__ . ": showing parser cache contents\n"); $wgOut->addParserOutput($this->mParserOutput); # Ensure that UI elements requiring revision ID have # the correct version information. $wgOut->setRevisionId($this->mLatest); $outputDone = true; } } break; case 3: $text = $this->getContent(); if ($text === false || $this->getID() == 0) { wfDebug(__METHOD__ . ": showing missing article\n"); $this->showMissingArticle(); wfProfileOut(__METHOD__); return; } # Another whitelist check in case oldid is altering the title if (!$this->mTitle->userCanRead()) { wfDebug(__METHOD__ . ": denied on secondary read check\n"); $wgOut->loginToUse(); $wgOut->output(); $wgOut->disable(); wfProfileOut(__METHOD__); return; } # Are we looking at an old revision if ($oldid && !is_null($this->mRevision)) { $this->setOldSubtitle($oldid); if (!$this->showDeletedRevisionHeader()) { wfDebug(__METHOD__ . ": cannot view deleted revision\n"); wfProfileOut(__METHOD__); return; } # If this "old" version is the current, then try the parser cache... if ($oldid === $this->getLatest() && $this->useParserCache(false)) { $this->mParserOutput = $parserCache->get($this, $parserOptions); if ($this->mParserOutput) { wfDebug(__METHOD__ . ": showing parser cache for current rev permalink\n"); $wgOut->addParserOutput($this->mParserOutput); $wgOut->setRevisionId($this->mLatest); $outputDone = true; break; } } } # Ensure that UI elements requiring revision ID have # the correct version information. $wgOut->setRevisionId($this->getRevIdFetched()); # Pages containing custom CSS or JavaScript get special treatment if ($this->mTitle->isCssOrJsPage() || $this->mTitle->isCssJsSubpage()) { wfDebug(__METHOD__ . ": showing CSS/JS source\n"); $this->showCssOrJsPage(); $outputDone = true; } else { $rt = Title::newFromRedirectArray($text); if ($rt) { wfDebug(__METHOD__ . ": showing redirect=no page\n"); # Viewing a redirect page (e.g. with parameter redirect=no) # Don't append the subtitle if this was an old revision $wgOut->addHTML($this->viewRedirect($rt, !$wasRedirected && $this->isCurrent())); # Parse just to get categories, displaytitle, etc. $this->mParserOutput = $wgParser->parse($text, $this->mTitle, $parserOptions); $wgOut->addParserOutputNoText($this->mParserOutput); $outputDone = true; } } break; case 4: # Run the parse, protected by a pool counter wfDebug(__METHOD__ . ": doing uncached parse\n"); $key = $parserCache->getKey($this, $parserOptions); $poolArticleView = new PoolWorkArticleView($this, $key, $useParserCache, $parserOptions); if (!$poolArticleView->execute()) { # Connection or timeout error wfProfileOut(__METHOD__); return; } else { $outputDone = true; } break; # Should be unreachable, but just in case... # Should be unreachable, but just in case... default: break 2; } } # Adjust the title if it was set by displaytitle, -{T|}- or language conversion if ($this->mParserOutput) { $titleText = $this->mParserOutput->getTitleText(); if (strval($titleText) !== '') { $wgOut->setPageTitle($titleText); } } # For the main page, overwrite the <title> element with the con- # tents of 'pagetitle-view-mainpage' instead of the default (if # that's not empty). # This message always exists because it is in the i18n files if ($this->mTitle->equals(Title::newMainPage()) && ($m = wfMsgForContent('pagetitle-view-mainpage')) !== '') { $wgOut->setHTMLTitle($m); } # Now that we've filled $this->mParserOutput, we know whether # there are any __NOINDEX__ tags on the page $policy = $this->getRobotPolicy('view'); $wgOut->setIndexPolicy($policy['index']); $wgOut->setFollowPolicy($policy['follow']); $this->showViewFooter(); $this->viewUpdates(); wfProfileOut(__METHOD__); }
protected function getRedirectHtml($text) { $rTargets = Title::newFromRedirectArray($text); if ($rTargets) { $article = new Article($this->article->getTitle()); return $article->viewRedirect($rTargets); } return ''; }
/** * Get the rendered text for previewing. * @return string */ function getPreviewText() { global $wgOut, $wgUser, $wgParser, $wgRawHtml; wfProfileIn(__METHOD__); if ($wgRawHtml && !$this->mTokenOk) { // Could be an offsite preview attempt. This is very unsafe if // HTML is enabled, as it could be an attack. $parsedNote = ''; if ($this->textbox1 !== '') { // Do not put big scary notice, if previewing the empty // string, which happens when you initially edit // a category page, due to automatic preview-on-open. $parsedNote = $wgOut->parse("<div class='previewnote'>" . wfMsg('session_fail_preview_html') . "</div>", true, true); } wfProfileOut(__METHOD__); return $parsedNote; } if ($this->mTriedSave && !$this->mTokenOk) { if ($this->mTokenOkExceptSuffix) { $note = wfMsg('token_suffix_mismatch'); } else { $note = wfMsg('session_fail_preview'); } } elseif ($this->incompleteForm) { $note = wfMsg('edit_form_incomplete'); } else { $note = wfMsg('previewnote'); } $parserOptions = ParserOptions::newFromUser($wgUser); $parserOptions->setEditSection(false); $parserOptions->setTidy(true); $parserOptions->setIsPreview(true); $parserOptions->setIsSectionPreview(!is_null($this->section) && $this->section !== ''); # don't parse non-wikitext pages, show message about preview # XXX: stupid php bug won't let us use $this->getContextTitle()->isCssJsSubpage() here -- This note has been there since r3530. Sure the bug was fixed time ago? if ($this->isCssJsSubpage || !$this->mTitle->isWikitextPage()) { if ($this->mTitle->isCssJsSubpage()) { $level = 'user'; } elseif ($this->mTitle->isCssOrJsPage()) { $level = 'site'; } else { $level = false; } # Used messages to make sure grep find them: # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview if ($level) { if (preg_match("/\\.css\$/", $this->mTitle->getText())) { $previewtext = "<div id='mw-{$level}csspreview'>\n" . wfMsg("{$level}csspreview") . "\n</div>"; $class = "mw-code mw-css"; } elseif (preg_match("/\\.js\$/", $this->mTitle->getText())) { $previewtext = "<div id='mw-{$level}jspreview'>\n" . wfMsg("{$level}jspreview") . "\n</div>"; $class = "mw-code mw-js"; } else { throw new MWException('A CSS/JS (sub)page but which is not css nor js!'); } } $parserOutput = $wgParser->parse($previewtext, $this->mTitle, $parserOptions); $previewHTML = $parserOutput->mText; $previewHTML .= "<pre class=\"{$class}\" dir=\"ltr\">\n" . htmlspecialchars($this->textbox1) . "\n</pre>\n"; } else { $rt = Title::newFromRedirectArray($this->textbox1); if ($rt) { $previewHTML = $this->mArticle->viewRedirect($rt, false); } else { $toparse = $this->textbox1; # If we're adding a comment, we need to show the # summary as the headline if ($this->section == "new" && $this->summary != "") { $toparse = wfMsgForContent('newsectionheaderdefaultlevel', $this->summary) . "\n\n" . $toparse; } wfRunHooks('EditPageGetPreviewText', array($this, &$toparse)); $parserOptions->enableLimitReport(); $toparse = $wgParser->preSaveTransform($toparse, $this->mTitle, $wgUser, $parserOptions); $parserOutput = $wgParser->parse($toparse, $this->mTitle, $parserOptions); $previewHTML = $parserOutput->getText(); $this->mParserOutput = $parserOutput; $wgOut->addParserOutputNoText($parserOutput); if (count($parserOutput->getWarnings())) { $note .= "\n\n" . implode("\n\n", $parserOutput->getWarnings()); } } } if ($this->isConflict) { $conflict = '<h2 id="mw-previewconflict">' . htmlspecialchars(wfMsg('previewconflict')) . "</h2>\n"; } else { $conflict = '<hr />'; } $previewhead = "<div class='previewnote'>\n" . '<h2 id="mw-previewheader">' . htmlspecialchars(wfMsg('preview')) . "</h2>" . $wgOut->parse($note, true, true) . $conflict . "</div>\n"; $pageLang = $this->mTitle->getPageLanguage(); $attribs = array('lang' => $pageLang->getCode(), 'dir' => $pageLang->getDir(), 'class' => 'mw-content-' . $pageLang->getDir()); $previewHTML = Html::rawElement('div', $attribs, $previewHTML); wfProfileOut(__METHOD__); return $previewhead . $previewHTML . $this->previewTextAfterContent; }
/** * This is the default action of the index.php entry point: just view the * page of the given title. */ public function view() { global $wgUser, $wgOut, $wgRequest, $wgParser; global $wgUseFileCache, $wgUseETag, $wgDebugToolbar; wfProfileIn(__METHOD__); # Get variables from query string # As side effect this will load the revision and update the title # in a revision ID is passed in the request, so this should remain # the first call of this method even if $oldid is used way below. $oldid = $this->getOldID(); # Another whitelist check in case getOldID() is altering the title $permErrors = $this->getTitle()->getUserPermissionsErrors('read', $wgUser); if (count($permErrors)) { wfDebug(__METHOD__ . ": denied on secondary read check\n"); wfProfileOut(__METHOD__); throw new PermissionsError('read', $permErrors); } # getOldID() may as well want us to redirect somewhere else if ($this->mRedirectUrl) { $wgOut->redirect($this->mRedirectUrl); wfDebug(__METHOD__ . ": redirecting due to oldid\n"); wfProfileOut(__METHOD__); return; } # If we got diff in the query, we want to see a diff page instead of the article. if ($wgRequest->getCheck('diff')) { wfDebug(__METHOD__ . ": showing diff page\n"); $this->showDiffPage(); wfProfileOut(__METHOD__); return; } # Set page title (may be overridden by DISPLAYTITLE) $wgOut->setPageTitle($this->getTitle()->getPrefixedText()); $wgOut->setArticleFlag(true); # Allow frames by default $wgOut->allowClickjacking(); $parserCache = ParserCache::singleton(); $parserOptions = $this->getParserOptions(); # Render printable version, use printable version cache if ($wgOut->isPrintable()) { $parserOptions->setIsPrintable(true); $parserOptions->setEditSection(false); } elseif (!$this->isCurrent() || !$this->getTitle()->quickUserCan('edit')) { $parserOptions->setEditSection(false); } # Try client and file cache if (!$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched()) { if ($wgUseETag) { $wgOut->setETag($parserCache->getETag($this, $parserOptions)); } # Is it client cached? if ($wgOut->checkLastModified($this->mPage->getTouched())) { wfDebug(__METHOD__ . ": done 304\n"); wfProfileOut(__METHOD__); return; # Try file cache } elseif ($wgUseFileCache && $this->tryFileCache()) { wfDebug(__METHOD__ . ": done file cache\n"); # tell wgOut that output is taken care of $wgOut->disable(); $this->mPage->doViewUpdates($wgUser); wfProfileOut(__METHOD__); return; } } # Should the parser cache be used? $useParserCache = $this->mPage->isParserCacheUsed($parserOptions, $oldid); wfDebug('Article::view using parser cache: ' . ($useParserCache ? 'yes' : 'no') . "\n"); if ($wgUser->getStubThreshold()) { wfIncrStats('pcache_miss_stub'); } $this->showRedirectedFromHeader(); $this->showNamespaceHeader(); # Iterate through the possible ways of constructing the output text. # Keep going until $outputDone is set, or we run out of things to do. $pass = 0; $outputDone = false; $this->mParserOutput = false; while (!$outputDone && ++$pass) { switch ($pass) { case 1: wfRunHooks('ArticleViewHeader', array(&$this, &$outputDone, &$useParserCache)); break; case 2: # Early abort if the page doesn't exist if (!$this->mPage->exists()) { wfDebug(__METHOD__ . ": showing missing article\n"); $this->showMissingArticle(); wfProfileOut(__METHOD__); /* Wikia change begin - @author: Marcin, #BugId: 30436 */ $text = ''; if (wfRunHooks('ArticleNonExistentPage', array(&$this, $wgOut, &$text))) { $this->mParserOutput = $wgParser->parse($text, $this->getTitle(), $parserOptions); $wgOut->addParserOutput($this->mParserOutput); } /* Wikia change end */ return; } # Try the parser cache if ($useParserCache) { $this->mParserOutput = $parserCache->get($this, $parserOptions); //Wikia Change Transaction::setAttribute(Transaction::PARAM_PARSER_CACHE_USED, $this->mParserOutput !== false); //Wikia Change End if ($this->mParserOutput !== false) { if ($oldid) { wfDebug(__METHOD__ . ": showing parser cache contents for current rev permalink\n"); $this->setOldSubtitle($oldid); } else { wfDebug(__METHOD__ . ": showing parser cache contents\n"); } $wgOut->addParserOutput($this->mParserOutput); // Wikia change - begin - @author: wladek wfRunHooks('ArticleViewAddParserOutput', array($this, $this->mParserOutput)); // Wikia change - end # Ensure that UI elements requiring revision ID have # the correct version information. $wgOut->setRevisionId($this->mPage->getLatest()); # Preload timestamp to avoid a DB hit $cachedTimestamp = $this->mParserOutput->getTimestamp(); if ($cachedTimestamp !== null) { $wgOut->setRevisionTimestamp($cachedTimestamp); $this->mPage->setTimestamp($cachedTimestamp); } $outputDone = true; } // Wikia change - begin - @author: wladek } else { Transaction::setAttribute(Transaction::PARAM_PARSER_CACHE_USED, false); // Wikia change - end } break; case 3: # This will set $this->mRevision if needed $this->fetchContent(); // Wikia change - begin // @author macbre // return status different than HTTP 200 when revision is missing (BAC-630) if (!$this->mRevision instanceof Revision) { global $wgEnableParserCache; wfDebug(__METHOD__ . ": no revision found - disabling parser cache and returning 404\n"); $wgOut->getRequest()->response()->header('X-Missing-Revision: 1', true, 404); $useParserCache = false; $wgEnableParserCache = false; } // Wikia change - end # Are we looking at an old revision if ($oldid && $this->mRevision) { $this->setOldSubtitle($oldid); if (!$this->showDeletedRevisionHeader()) { wfDebug(__METHOD__ . ": cannot view deleted revision\n"); wfProfileOut(__METHOD__); return; } } # Ensure that UI elements requiring revision ID have # the correct version information. $wgOut->setRevisionId($this->getRevIdFetched()); # Preload timestamp to avoid a DB hit $wgOut->setRevisionTimestamp($this->getTimestamp()); # Pages containing custom CSS or JavaScript get special treatment if ($this->getTitle()->isCssOrJsPage() || $this->getTitle()->isCssJsSubpage()) { wfDebug(__METHOD__ . ": showing CSS/JS source\n"); $this->showCssOrJsPage(); $outputDone = true; } elseif (!wfRunHooks('ArticleViewCustom', array($this->mContent, $this->getTitle(), $wgOut))) { # Allow extensions do their own custom view for certain pages $outputDone = true; } else { $text = $this->getContent(); $rt = Title::newFromRedirectArray($text); if ($rt) { wfDebug(__METHOD__ . ": showing redirect=no page\n"); # Viewing a redirect page (e.g. with parameter redirect=no) $wgOut->addHTML($this->viewRedirect($rt)); # Parse just to get categories, displaytitle, etc. $this->mParserOutput = $wgParser->parse($text, $this->getTitle(), $parserOptions); $wgOut->addParserOutputNoText($this->mParserOutput); $outputDone = true; } } break; case 4: # Run the parse, protected by a pool counter wfDebug(__METHOD__ . ": doing uncached parse\n"); $poolArticleView = new PoolWorkArticleView($this, $parserOptions, $this->getRevIdFetched(), $useParserCache, $this->getContent()); if (!$poolArticleView->execute()) { $error = $poolArticleView->getError(); if ($error) { $wgOut->clearHTML(); // for release() errors $wgOut->enableClientCache(false); $wgOut->setRobotPolicy('noindex,nofollow'); $errortext = $error->getWikiText(false, 'view-pool-error'); $wgOut->addWikiText('<div class="errorbox">' . $errortext . '</div>'); } # Connection or timeout error wfProfileOut(__METHOD__); return; } $this->mParserOutput = $poolArticleView->getParserOutput(); $wgOut->addParserOutput($this->mParserOutput); // Wikia change - begin - @author: wladek Transaction::setAttribute(Transaction::PARAM_PARSER_CACHE_USED, $poolArticleView->getIsDirty()); wfRunHooks('ArticleViewAddParserOutput', array($this, $this->mParserOutput)); // Wikia change - end # Don't cache a dirty ParserOutput object if ($poolArticleView->getIsDirty()) { $wgOut->setSquidMaxage(0); $wgOut->addHTML("<!-- parser cache is expired, sending anyway due to pool overload-->\n"); } # <Wikia> if (!$poolArticleView->getIsDirty()) { wfRunHooks('ArticleViewAfterParser', array($this, $this->mParserOutput)); } # </Wikia> $outputDone = true; break; # Should be unreachable, but just in case... # Should be unreachable, but just in case... default: break 2; } } # Get the ParserOutput actually *displayed* here. # Note that $this->mParserOutput is the *current* version output. $pOutput = $outputDone instanceof ParserOutput ? $outputDone : $this->mParserOutput; # Adjust title for main page & pages with displaytitle if ($pOutput) { $this->adjustDisplayTitle($pOutput); if ($pOutput->getText() == '') { \Wikia\Logger\WikiaLogger::instance()->error('PLATFORM-1212 - empty parser output'); } } # For the main page, overwrite the <title> element with the con- # tents of 'pagetitle-view-mainpage' instead of the default (if # that's not empty). # This message always exists because it is in the i18n files if ($this->getTitle()->isMainPage()) { $msg = wfMessage('pagetitle-view-mainpage')->inContentLanguage(); if (!$msg->isDisabled()) { $wgOut->setHTMLTitle($msg->title($this->getTitle())->text()); } } # Check for any __NOINDEX__ tags on the page using $pOutput $policy = $this->getRobotPolicy('view', $pOutput); $wgOut->setIndexPolicy($policy['index']); $wgOut->setFollowPolicy($policy['follow']); $this->showViewFooter(); $this->mPage->doViewUpdates($wgUser); wfProfileOut(__METHOD__); }
/** * Get the rendered text for previewing. * @return string */ function getPreviewText() { global $wgOut, $wgUser, $wgTitle, $wgParser, $wgLang, $wgContLang, $wgMessageCache; wfProfileIn(__METHOD__); if ($this->mTriedSave && !$this->mTokenOk) { if ($this->mTokenOkExceptSuffix) { $note = wfMsg('token_suffix_mismatch'); } else { $note = wfMsg('session_fail_preview'); } } else { $note = wfMsg('previewnote'); } $parserOptions = ParserOptions::newFromUser($wgUser); $parserOptions->setEditSection(false); $parserOptions->setIsPreview(true); $parserOptions->setIsSectionPreview(!is_null($this->section) && $this->section !== ''); global $wgRawHtml; if ($wgRawHtml && !$this->mTokenOk) { // Could be an offsite preview attempt. This is very unsafe if // HTML is enabled, as it could be an attack. return $wgOut->parse("<div class='previewnote'>" . wfMsg('session_fail_preview_html') . "</div>"); } # don't parse user css/js, show message about preview # XXX: stupid php bug won't let us use $wgTitle->isCssJsSubpage() here if ($this->isCssJsSubpage) { if (preg_match("/\\.css\$/", $this->mTitle->getText())) { $previewtext = wfMsg('usercsspreview'); } else { if (preg_match("/\\.js\$/", $this->mTitle->getText())) { $previewtext = wfMsg('userjspreview'); } } $parserOptions->setTidy(true); $parserOutput = $wgParser->parse($previewtext, $this->mTitle, $parserOptions); $previewHTML = $parserOutput->mText; } elseif ($rt = Title::newFromRedirectArray($this->textbox1)) { $previewHTML = $this->mArticle->viewRedirect($rt, false); } else { $toparse = $this->textbox1; # If we're adding a comment, we need to show the # summary as the headline if ($this->section == "new" && $this->summary != "") { $toparse = "== {$this->summary} ==\n\n" . $toparse; } if ($this->mMetaData != "") { $toparse .= "\n" . $this->mMetaData; } // Parse mediawiki messages with correct target language if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) { list(, $lang) = $wgMessageCache->figureMessage($this->mTitle->getText()); $obj = wfGetLangObj($lang); $parserOptions->setTargetLanguage($obj); } $parserOptions->setTidy(true); $parserOptions->enableLimitReport(); $parserOutput = $wgParser->parse($this->mArticle->preSaveTransform($toparse), $this->mTitle, $parserOptions); $previewHTML = $parserOutput->getText(); $this->mParserOutput = $parserOutput; $wgOut->addParserOutputNoText($parserOutput); if (count($parserOutput->getWarnings())) { $note .= "\n\n" . implode("\n\n", $parserOutput->getWarnings()); } } $previewhead = '<h2>' . htmlspecialchars(wfMsg('preview')) . "</h2>\n" . "<div class='previewnote'>" . $wgOut->parse($note) . "</div>\n"; if ($this->isConflict) { $previewhead .= '<h2>' . htmlspecialchars(wfMsg('previewconflict')) . "</h2>\n"; } wfProfileOut(__METHOD__); return $previewhead . $previewHTML; }
/** * Get the rendered text for previewing. * @return string */ function getPreviewText() { global $wgOut, $wgUser, $wgParser, $wgMessageCache; wfProfileIn(__METHOD__); if ($this->mTriedSave && !$this->mTokenOk) { if ($this->mTokenOkExceptSuffix) { $note = wfMsg('token_suffix_mismatch'); } else { $note = wfMsg('session_fail_preview'); } } else { $note = wfMsg('previewnote'); } $parserOptions = ParserOptions::newFromUser($wgUser); $parserOptions->setEditSection(false); $parserOptions->setIsPreview(true); $parserOptions->setIsSectionPreview(!is_null($this->section) && $this->section !== ''); global $wgRawHtml; if ($wgRawHtml && !$this->mTokenOk) { // Could be an offsite preview attempt. This is very unsafe if // HTML is enabled, as it could be an attack. $parsedNote = $wgOut->parse("<div class='previewnote'>" . wfMsg('session_fail_preview_html') . "</div>"); wfProfileOut(__METHOD__); return $parsedNote; } # don't parse user css/js, show message about preview # XXX: stupid php bug won't let us use $wgTitle->isCssJsSubpage() here -- This note has been there since r3530. Sure the bug was fixed time ago? if ($this->isCssJsSubpage || $this->mTitle->isCssOrJsPage()) { $level = 'user'; if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) { $level = 'site'; } # Used messages to make sure grep find them: # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview if (preg_match("/\\.css\$/", $this->mTitle->getText())) { $previewtext = "<div id='mw-{$level}csspreview'>\n" . wfMsg("{$level}csspreview") . "\n</div>"; $class = "mw-code mw-css"; } elseif (preg_match("/\\.js\$/", $this->mTitle->getText())) { $previewtext = "<div id='mw-{$level}jspreview'>\n" . wfMsg("{$level}jspreview") . "\n</div>"; $class = "mw-code mw-js"; } else { throw new MWException('A CSS/JS (sub)page but which is not css nor js!'); } $parserOptions->setTidy(true); $parserOutput = $wgParser->parse($previewtext, $this->mTitle, $parserOptions); $previewHTML = $parserOutput->mText; $previewHTML .= "<pre class=\"{$class}\" dir=\"ltr\">\n" . htmlspecialchars($this->textbox1) . "\n</pre>\n"; } else { $rt = Title::newFromRedirectArray($this->textbox1); if ($rt) { $previewHTML = $this->mArticle->viewRedirect($rt, false); } else { $toparse = $this->textbox1; # If we're adding a comment, we need to show the # summary as the headline if ($this->section == "new" && $this->summary != "") { $toparse = "== {$this->summary} ==\n\n" . $toparse; } wfRunHooks('EditPageGetPreviewText', array($this, &$toparse)); // Parse mediawiki messages with correct target language if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) { list(, $lang) = $wgMessageCache->figureMessage($this->mTitle->getText()); $obj = wfGetLangObj($lang); $parserOptions->setTargetLanguage($obj); } $parserOptions->setTidy(true); $parserOptions->enableLimitReport(); $parserOutput = $wgParser->parse($this->mArticle->preSaveTransform($toparse), $this->mTitle, $parserOptions); $previewHTML = $parserOutput->getText(); $this->mParserOutput = $parserOutput; $wgOut->addParserOutputNoText($parserOutput); if (count($parserOutput->getWarnings())) { $note .= "\n\n" . implode("\n\n", $parserOutput->getWarnings()); } } } if ($this->isConflict) { $conflict = '<h2 id="mw-previewconflict">' . htmlspecialchars(wfMsg('previewconflict')) . "</h2>\n"; } else { $conflict = '<hr />'; } $previewhead = "<div class='previewnote'>\n" . '<h2 id="mw-previewheader">' . htmlspecialchars(wfMsg('preview')) . "</h2>" . $wgOut->parse($note) . $conflict . "</div>\n"; wfProfileOut(__METHOD__); return $previewhead . $previewHTML . $this->previewTextAfterContent; }
/** * This is the default action of the script: just view the page of * the given title. */ public function view() { global $wgUser, $wgOut, $wgRequest, $wgContLang; global $wgEnableParserCache, $wgStylePath, $wgParser; global $wgUseTrackbacks, $wgNamespaceRobotPolicies, $wgArticleRobotPolicies; global $wgDefaultRobotPolicy; # Let the parser know if this is the printable version if ($wgOut->isPrintable()) { $wgOut->parserOptions()->setIsPrintable(true); } wfProfileIn(__METHOD__); # Get variables from query string $oldid = $this->getOldID(); # Try client and file cache if ($oldid === 0 && $this->checkTouched()) { global $wgUseETag; if ($wgUseETag) { $parserCache = ParserCache::singleton(); $wgOut->setETag($parserCache->getETag($this, $wgOut->parserOptions())); } # Is is client cached? if ($wgOut->checkLastModified($this->getTouched())) { wfProfileOut(__METHOD__); return; # Try file cache } else { if ($this->tryFileCache()) { # tell wgOut that output is taken care of $wgOut->disable(); $this->viewUpdates(); wfProfileOut(__METHOD__); return; } } } $ns = $this->mTitle->getNamespace(); # shortcut $sk = $wgUser->getSkin(); # getOldID may want us to redirect somewhere else if ($this->mRedirectUrl) { $wgOut->redirect($this->mRedirectUrl); wfProfileOut(__METHOD__); return; } $diff = $wgRequest->getVal('diff'); $rcid = $wgRequest->getVal('rcid'); $rdfrom = $wgRequest->getVal('rdfrom'); $diffOnly = $wgRequest->getBool('diffonly', $wgUser->getOption('diffonly')); $purge = $wgRequest->getVal('action') == 'purge'; $return404 = false; $wgOut->setArticleFlag(true); # Discourage indexing of printable versions, but encourage following if ($wgOut->isPrintable()) { $policy = 'noindex,follow'; } elseif (isset($wgArticleRobotPolicies[$this->mTitle->getPrefixedText()])) { $policy = $wgArticleRobotPolicies[$this->mTitle->getPrefixedText()]; } elseif (isset($wgNamespaceRobotPolicies[$ns])) { # Honour customised robot policies for this namespace $policy = $wgNamespaceRobotPolicies[$ns]; } else { $policy = $wgDefaultRobotPolicy; } $wgOut->setRobotPolicy($policy); # Allow admins to see deleted content if explicitly requested $delId = $diff ? $diff : $oldid; $unhide = $wgRequest->getInt('unhide') == 1 && $wgUser->matchEditToken($wgRequest->getVal('token'), $delId); # If we got diff and oldid in the query, we want to see a # diff page instead of the article. if (!is_null($diff)) { $wgOut->setPageTitle($this->mTitle->getPrefixedText()); $htmldiff = $wgRequest->getVal('htmldiff', false); $de = new DifferenceEngine($this->mTitle, $oldid, $diff, $rcid, $purge, $htmldiff, $unhide); // DifferenceEngine directly fetched the revision: $this->mRevIdFetched = $de->mNewid; $de->showDiffPage($diffOnly); // Needed to get the page's current revision $this->loadPageData(); if ($diff == 0 || $diff == $this->mLatest) { # Run view updates for current revision only $this->viewUpdates(); } wfProfileOut(__METHOD__); return; } if ($ns == NS_USER || $ns == NS_USER_TALK) { # User/User_talk subpages are not modified. (bug 11443) if (!$this->mTitle->isSubpage()) { $block = new Block(); if ($block->load($this->mTitle->getBaseText())) { $wgOut->setRobotpolicy('noindex,nofollow'); } } } # Should the parser cache be used? $pcache = $this->useParserCache($oldid); wfDebug('Article::view using parser cache: ' . ($pcache ? 'yes' : 'no') . "\n"); if ($wgUser->getOption('stubthreshold')) { wfIncrStats('pcache_miss_stub'); } $wasRedirected = false; if (isset($this->mRedirectedFrom)) { // This is an internally redirected page view. // We'll need a backlink to the source page for navigation. if (wfRunHooks('ArticleViewRedirect', array(&$this))) { $redir = $sk->makeKnownLinkObj($this->mRedirectedFrom, '', 'redirect=no'); $s = wfMsgExt('redirectedfrom', array('parseinline', 'replaceafter'), $redir); $wgOut->setSubtitle($s); // Set the fragment if one was specified in the redirect if (strval($this->mTitle->getFragment()) != '') { $fragment = Xml::escapeJsString($this->mTitle->getFragmentForURL()); $wgOut->addInlineScript("redirectToFragment(\"{$fragment}\");"); } // Add a <link rel="canonical"> tag $wgOut->addLink(array('rel' => 'canonical', 'href' => $this->mTitle->getLocalURL())); $wasRedirected = true; } } elseif (!empty($rdfrom)) { // This is an externally redirected view, from some other wiki. // If it was reported from a trusted site, supply a backlink. global $wgRedirectSources; if ($wgRedirectSources && preg_match($wgRedirectSources, $rdfrom)) { $redir = $sk->makeExternalLink($rdfrom, $rdfrom); $s = wfMsgExt('redirectedfrom', array('parseinline', 'replaceafter'), $redir); $wgOut->setSubtitle($s); $wasRedirected = true; } } $outputDone = false; wfRunHooks('ArticleViewHeader', array(&$this, &$outputDone, &$pcache)); if ($pcache && $wgOut->tryParserCache($this)) { // Ensure that UI elements requiring revision ID have // the correct version information. $wgOut->setRevisionId($this->mLatest); $outputDone = true; } # Fetch content and check for errors if (!$outputDone) { # If the article does not exist and was deleted, show the log if ($this->getID() == 0) { $this->showDeletionLog(); } $text = $this->getContent(); // For now, check also for ID until getContent actually returns // false for pages that do not exists if ($text === false || $this->getID() === 0) { # Failed to load, replace text with error message $t = $this->mTitle->getPrefixedText(); if ($oldid) { $d = wfMsgExt('missingarticle-rev', 'escape', $oldid); $text = wfMsgExt('missing-article', 'parsemag', $t, $d); // Always use page content for pages in the MediaWiki namespace // since it contains the default message } elseif ($this->mTitle->getNamespace() != NS_MEDIAWIKI) { $text = wfMsgExt('noarticletext', 'parsemag'); } } # Non-existent pages if ($this->getID() === 0) { $wgOut->setRobotPolicy('noindex,nofollow'); $text = "<div class='noarticletext'>\n{$text}\n</div>"; if (!$this->hasViewableContent()) { // If there's no backing content, send a 404 Not Found // for better machine handling of broken links. $return404 = true; } } if ($return404) { $wgRequest->response()->header("HTTP/1.x 404 Not Found"); } # Another whitelist check in case oldid is altering the title if (!$this->mTitle->userCanRead()) { $wgOut->loginToUse(); $wgOut->output(); $wgOut->disable(); wfProfileOut(__METHOD__); return; } # For ?curid=x urls, disallow indexing if ($wgRequest->getInt('curid')) { $wgOut->setRobotPolicy('noindex,follow'); } # We're looking at an old revision if (!empty($oldid)) { $wgOut->setRobotPolicy('noindex,nofollow'); if (is_null($this->mRevision)) { // FIXME: This would be a nice place to load the 'no such page' text. } else { $this->setOldSubtitle(isset($this->mOldId) ? $this->mOldId : $oldid); # Allow admins to see deleted content if explicitly requested if ($this->mRevision->isDeleted(Revision::DELETED_TEXT)) { if (!$unhide || !$this->mRevision->userCan(Revision::DELETED_TEXT)) { $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-permission'); $wgOut->setPageTitle($this->mTitle->getPrefixedText()); wfProfileOut(__METHOD__); return; } else { $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-view'); // and we are allowed to see... } } // Is this the current revision and otherwise cacheable? Try the parser cache... if ($oldid === $this->getLatest() && $this->useParserCache(false) && $wgOut->tryParserCache($this)) { $outputDone = true; } } } // Ensure that UI elements requiring revision ID have // the correct version information. $wgOut->setRevisionId($this->getRevIdFetched()); if ($outputDone) { // do nothing... // Pages containing custom CSS or JavaScript get special treatment } else { if ($this->mTitle->isCssOrJsPage() || $this->mTitle->isCssJsSubpage()) { $wgOut->addHTML(wfMsgExt('clearyourcache', 'parse')); // Give hooks a chance to customise the output if (wfRunHooks('ShowRawCssJs', array($this->mContent, $this->mTitle, $wgOut))) { // Wrap the whole lot in a <pre> and don't parse $m = array(); preg_match('!\\.(css|js)$!u', $this->mTitle->getText(), $m); $wgOut->addHTML("<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n"); $wgOut->addHTML(htmlspecialchars($this->mContent)); $wgOut->addHTML("\n</pre>\n"); } } else { if ($rt = Title::newFromRedirectArray($text)) { # get an array of redirect targets # Don't append the subtitle if this was an old revision $wgOut->addHTML($this->viewRedirect($rt, !$wasRedirected && $this->isCurrent())); $parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser)); $wgOut->addParserOutputNoText($parseout); } else { if ($pcache) { # Display content and save to parser cache $this->outputWikiText($text); } else { # Display content, don't attempt to save to parser cache # Don't show section-edit links on old revisions... this way lies madness. if (!$this->isCurrent()) { $oldEditSectionSetting = $wgOut->parserOptions()->setEditSection(false); } # Display content and don't save to parser cache # With timing hack -- TS 2006-07-26 $time = -wfTime(); $this->outputWikiText($text, false); $time += wfTime(); # Timing hack if ($time > 3) { wfDebugLog('slow-parse', sprintf("%-5.2f %s", $time, $this->mTitle->getPrefixedDBkey())); } if (!$this->isCurrent()) { $wgOut->parserOptions()->setEditSection($oldEditSectionSetting); } } } } } } /* title may have been set from the cache */ $t = $wgOut->getPageTitle(); if (empty($t)) { $wgOut->setPageTitle($this->mTitle->getPrefixedText()); # For the main page, overwrite the <title> element with the con- # tents of 'pagetitle-view-mainpage' instead of the default (if # that's not empty). if ($this->mTitle->equals(Title::newMainPage()) && wfMsgForContent('pagetitle-view-mainpage') !== '') { $wgOut->setHTMLTitle(wfMsgForContent('pagetitle-view-mainpage')); } } # check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page if ($ns == NS_USER_TALK && IP::isValid($this->mTitle->getText())) { $wgOut->addWikiMsg('anontalkpagetext'); } # If we have been passed an &rcid= parameter, we want to give the user a # chance to mark this new article as patrolled. if (!empty($rcid) && $this->mTitle->exists() && $this->mTitle->quickUserCan('patrol')) { $wgOut->addHTML("<div class='patrollink'>" . wfMsgHtml('markaspatrolledlink', $sk->makeKnownLinkObj($this->mTitle, wfMsgHtml('markaspatrolledtext'), "action=markpatrolled&rcid={$rcid}")) . '</div>'); } # Trackbacks if ($wgUseTrackbacks) { $this->addTrackbacks(); } $this->viewUpdates(); wfProfileOut(__METHOD__); }