/** * Show the new revision of the page. */ public function renderNewRevision() { $out = $this->getOutput(); $revHeader = $this->getRevisionHeader($this->mNewRev); # Add "current version as of X" title $out->addHTML("<hr class='diff-hr' id='mw-oldid' />\n\t\t<h2 class='diff-currentversion-title'>{$revHeader}</h2>\n"); # Page content may be handled by a hooked call instead... # @codingStandardsIgnoreStart Ignoring long lines. if (Hooks::run('ArticleContentOnDiff', [$this, $out])) { $this->loadNewText(); $out->setRevisionId($this->mNewid); $out->setRevisionTimestamp($this->mNewRev->getTimestamp()); $out->setArticleFlag(true); // NOTE: only needed for B/C: custom rendering of JS/CSS via hook if ($this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage()) { // This needs to be synchronised with Article::showCssOrJsPage(), which sucks // Give hooks a chance to customise the output // @todo standardize this crap into one function if (ContentHandler::runLegacyHooks('ShowRawCssJs', [$this->mNewContent, $this->mNewPage, $out], '1.24')) { // NOTE: deprecated hook, B/C only // use the content object's own rendering $cnt = $this->mNewRev->getContent(); $po = $cnt ? $cnt->getParserOutput($this->mNewRev->getTitle(), $this->mNewRev->getId()) : null; if ($po) { $out->addParserOutputContent($po); } } } elseif (!Hooks::run('ArticleContentViewCustom', [$this->mNewContent, $this->mNewPage, $out])) { // Handled by extension } elseif (!ContentHandler::runLegacyHooks('ArticleViewCustom', [$this->mNewContent, $this->mNewPage, $out], '1.21')) { // NOTE: deprecated hook, B/C only // Handled by extension } else { // Normal page if ($this->getTitle()->equals($this->mNewPage)) { // If the Title stored in the context is the same as the one // of the new revision, we can use its associated WikiPage // object. $wikiPage = $this->getWikiPage(); } else { // Otherwise we need to create our own WikiPage object $wikiPage = WikiPage::factory($this->mNewPage); } $parserOutput = $this->getParserOutput($wikiPage, $this->mNewRev); # WikiPage::getParserOutput() should not return false, but just in case if ($parserOutput) { // Allow extensions to change parser output here if (Hooks::run('DifferenceEngineRenderRevisionAddParserOutput', [$this, $out, $parserOutput, $wikiPage])) { $out->addParserOutput($parserOutput); } } } } # @codingStandardsIgnoreEnd // Allow extensions to optionally not show the final patrolled link if (Hooks::run('DifferenceEngineRenderRevisionShowFinalPatrolLink')) { # Add redundant patrol link on bottom... $out->addHTML($this->markPatrolledLink()); } }
/** * @param Title $title * @return null|string */ protected function getContent($title) { if (!$title->isCssJsSubpage() && !$title->isCssOrJsPage()) { return null; } $revision = Revision::newFromTitle($title, false, Revision::READ_NORMAL); if (!$revision) { return null; } $content = $revision->getContent(Revision::RAW); if (!$content) { wfDebugLog('resourceloader', __METHOD__ . ': failed to load content of JS/CSS page!'); return null; } $model = $content->getModel(); if ($model !== CONTENT_MODEL_CSS && $model !== CONTENT_MODEL_JAVASCRIPT) { wfDebugLog('resourceloader', __METHOD__ . ': bad content model $model for JS/CSS page!'); return null; } return $content->getNativeData(); //NOTE: this is safe, we know it's JS or CSS }
/** * @param Title $title * @return null|string */ protected function getContent($title) { if (!$title->isCssJsSubpage() && !$title->isCssOrJsPage()) { return null; } $revision = Revision::newFromTitle($title, false, Revision::READ_NORMAL); if (!$revision) { return null; } $content = $revision->getContent(Revision::RAW); if (!$content) { wfDebugLog('resourceloader', __METHOD__ . ': failed to load content of JS/CSS page!'); return null; } if ($content->isSupportedFormat(CONTENT_FORMAT_JAVASCRIPT)) { return $content->serialize(CONTENT_FORMAT_JAVASCRIPT); } elseif ($content->isSupportedFormat(CONTENT_FORMAT_CSS)) { return $content->serialize(CONTENT_FORMAT_CSS); } else { wfDebugLog('resourceloader', __METHOD__ . ": bad content model {$content->getModel()} for JS/CSS page!"); return null; } }
/** * 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; }
/** * Should the parser cache be used? * * @param $user User The relevant user * @return boolean */ public function isParserCacheUsed(User $user, $oldid) { global $wgEnableParserCache; return $wgEnableParserCache && $user->getStubThreshold() == 0 && $this->exists() && empty($oldid) && !$this->mTitle->isCssOrJsPage() && !$this->mTitle->isCssJsSubpage(); }
/** * Get the rendered text for previewing. * @throws MWException * @return string */ function getPreviewText() { global $wgOut, $wgUser, $wgRawHtml, $wgLang; global $wgAllowUserCss, $wgAllowUserJs; 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'>" . wfMessage('session_fail_preview_html')->text() . "</div>", true, true); } wfProfileOut(__METHOD__); return $parsedNote; } $note = ''; try { $content = $this->toEditContent($this->textbox1); $previewHTML = ''; if (!wfRunHooks('AlternateEditPreview', array($this, &$content, &$previewHTML, &$this->mParserOutput))) { wfProfileOut(__METHOD__); return $previewHTML; } # provide a anchor link to the editform $continueEditing = '<span class="mw-continue-editing">' . '[[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' . wfMessage('continue-editing')->text() . ']]</span>'; if ($this->mTriedSave && !$this->mTokenOk) { if ($this->mTokenOkExceptSuffix) { $note = wfMessage('token_suffix_mismatch')->plain(); } else { $note = wfMessage('session_fail_preview')->plain(); } } elseif ($this->incompleteForm) { $note = wfMessage('edit_form_incomplete')->plain(); } else { $note = wfMessage('previewnote')->plain() . ' ' . $continueEditing; } $parserOptions = $this->mArticle->makeParserOptions($this->mArticle->getContext()); $parserOptions->setEditSection(false); $parserOptions->setIsPreview(true); $parserOptions->setIsSectionPreview(!is_null($this->section) && $this->section !== ''); # don't parse non-wikitext pages, show message about preview if ($this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage()) { if ($this->mTitle->isCssJsSubpage()) { $level = 'user'; } elseif ($this->mTitle->isCssOrJsPage()) { $level = 'site'; } else { $level = false; } if ($content->getModel() == CONTENT_MODEL_CSS) { $format = 'css'; if ($level === 'user' && !$wgAllowUserCss) { $format = false; } } elseif ($content->getModel() == CONTENT_MODEL_JAVASCRIPT) { $format = 'js'; if ($level === 'user' && !$wgAllowUserJs) { $format = false; } } else { $format = false; } # Used messages to make sure grep find them: # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview if ($level && $format) { $note = "<div id='mw-{$level}{$format}preview'>" . wfMessage("{$level}{$format}preview")->text() . ' ' . $continueEditing . "</div>"; } } # If we're adding a comment, we need to show the # summary as the headline if ($this->section === "new" && $this->summary !== "") { $content = $content->addSectionHeader($this->summary); } $hook_args = array($this, &$content); ContentHandler::runLegacyHooks('EditPageGetPreviewText', $hook_args); wfRunHooks('EditPageGetPreviewContent', $hook_args); $parserOptions->enableLimitReport(); # For CSS/JS pages, we should have called the ShowRawCssJs hook here. # But it's now deprecated, so never mind $content = $content->preSaveTransform($this->mTitle, $wgUser, $parserOptions); $parserOutput = $content->getParserOutput($this->getArticle()->getTitle(), null, $parserOptions); $previewHTML = $parserOutput->getText(); $this->mParserOutput = $parserOutput; $wgOut->addParserOutputMetadata($parserOutput); if (count($parserOutput->getWarnings())) { $note .= "\n\n" . implode("\n\n", $parserOutput->getWarnings()); } } catch (MWContentSerializationException $ex) { $m = wfMessage('content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage()); $note .= "\n\n" . $m->parse(); $previewHTML = ''; } if ($this->isConflict) { $conflict = '<h2 id="mw-previewconflict">' . wfMessage('previewconflict')->escaped() . "</h2>\n"; } else { $conflict = '<hr />'; } $previewhead = "<div class='previewnote'>\n" . '<h2 id="mw-previewheader">' . wfMessage('preview')->escaped() . "</h2>" . $wgOut->parse($note, true, true) . $conflict . "</div>\n"; $pageViewLang = $this->mTitle->getPageViewLanguage(); $attribs = array('lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(), 'class' => 'mw-content-' . $pageViewLang->getDir()); $previewHTML = Html::rawElement('div', $attribs, $previewHTML); wfProfileOut(__METHOD__); return $previewhead . $previewHTML . $this->previewTextAfterContent; }
/** * Check if edited page is a code page * (page to edit CSS, JS or Lua code) * * @param Title $articleTitle page title * @return bool */ public static function isCodePage(Title $articleTitle) { $namespace = $articleTitle->getNamespace(); return $articleTitle->isCssOrJsPage() || $articleTitle->isCssJsSubpage() || $namespace === NS_MODULE || self::isInfoboxTemplate($articleTitle); }
/** * Get the rendered text for previewing. * @throws MWException * @return string */ function getPreviewText() { global $wgOut, $wgRawHtml, $wgLang; global $wgAllowUserCss, $wgAllowUserJs; $stats = $wgOut->getContext()->getStats(); 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'>" . $this->context->msg('session_fail_preview_html')->text() . "</div>", true, true); } $stats->increment('edit.failures.session_loss'); return $parsedNote; } $note = ''; try { $content = $this->toEditContent($this->textbox1); $previewHTML = ''; if (!Hooks::run('AlternateEditPreview', [$this, &$content, &$previewHTML, &$this->mParserOutput])) { return $previewHTML; } # provide a anchor link to the editform $continueEditing = '<span class="mw-continue-editing">' . '[[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' . $this->context->msg('continue-editing')->text() . ']]</span>'; if ($this->mTriedSave && !$this->mTokenOk) { if ($this->mTokenOkExceptSuffix) { $note = $this->context->msg('token_suffix_mismatch')->plain(); $stats->increment('edit.failures.bad_token'); } else { $note = $this->context->msg('session_fail_preview')->plain(); $stats->increment('edit.failures.session_loss'); } } elseif ($this->incompleteForm) { $note = $this->context->msg('edit_form_incomplete')->plain(); if ($this->mTriedSave) { $stats->increment('edit.failures.incomplete_form'); } } else { $note = $this->context->msg('previewnote')->plain() . ' ' . $continueEditing; } # don't parse non-wikitext pages, show message about preview if ($this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage()) { if ($this->mTitle->isCssJsSubpage()) { $level = 'user'; } elseif ($this->mTitle->isCssOrJsPage()) { $level = 'site'; } else { $level = false; } if ($content->getModel() == CONTENT_MODEL_CSS) { $format = 'css'; if ($level === 'user' && !$wgAllowUserCss) { $format = false; } } elseif ($content->getModel() == CONTENT_MODEL_JAVASCRIPT) { $format = 'js'; if ($level === 'user' && !$wgAllowUserJs) { $format = false; } } else { $format = false; } # Used messages to make sure grep find them: # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview if ($level && $format) { $note = "<div id='mw-{$level}{$format}preview'>" . $this->context->msg("{$level}{$format}preview")->text() . ' ' . $continueEditing . "</div>"; } } # If we're adding a comment, we need to show the # summary as the headline if ($this->section === "new" && $this->summary !== "") { $content = $content->addSectionHeader($this->summary); } $hook_args = [$this, &$content]; ContentHandler::runLegacyHooks('EditPageGetPreviewText', $hook_args, '1.25'); Hooks::run('EditPageGetPreviewContent', $hook_args); $parserResult = $this->doPreviewParse($content); $parserOutput = $parserResult['parserOutput']; $previewHTML = $parserResult['html']; $this->mParserOutput = $parserOutput; $wgOut->addParserOutputMetadata($parserOutput); if (count($parserOutput->getWarnings())) { $note .= "\n\n" . implode("\n\n", $parserOutput->getWarnings()); } } catch (MWContentSerializationException $ex) { $m = $this->context->msg('content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage()); $note .= "\n\n" . $m->parse(); $previewHTML = ''; } if ($this->isConflict) { $conflict = '<h2 id="mw-previewconflict">' . $this->context->msg('previewconflict')->escaped() . "</h2>\n"; } else { $conflict = '<hr />'; } $previewhead = "<div class='previewnote'>\n" . '<h2 id="mw-previewheader">' . $this->context->msg('preview')->escaped() . "</h2>" . $wgOut->parse($note, true, true) . $conflict . "</div>\n"; $pageViewLang = $this->mTitle->getPageViewLanguage(); $attribs = ['lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(), 'class' => 'mw-content-' . $pageViewLang->getDir()]; $previewHTML = Html::rawElement('div', $attribs, $previewHTML); return $previewhead . $previewHTML . $this->previewTextAfterContent; }
/** * This is the function that gets called for "action=edit". It * sets up various member variables, then passes execution to * another function, usually showEditForm() * * The edit form is self-submitting, so that when things like * preview and edit conflicts occur, we get the same form back * with the extra stuff added. Only when the final submission * is made and all is well do we actually save and redirect to * the newly-edited page. */ function edit() { global $wgOut, $wgRequest, $wgUser; // Allow extensions to modify/prevent this form or submission if (!wfRunHooks('AlternateEdit', array($this))) { return; } wfProfileIn(__METHOD__); wfDebug(__METHOD__ . ": enter\n"); // This is not an article $wgOut->setArticleFlag(false); $this->importFormData($wgRequest); $this->firsttime = false; if ($this->live) { $this->livePreview(); wfProfileOut(__METHOD__); return; } if (wfReadOnly() && $this->save) { // Force preview $this->save = false; $this->preview = true; } $wgOut->addModules(array('mediawiki.action.edit')); if ($wgUser->getOption('uselivepreview', false)) { $wgOut->addModules('mediawiki.legacy.preview'); } // Bug #19334: textarea jumps when editing articles in IE8 $wgOut->addStyle('common/IE80Fixes.css', 'screen', 'IE 8'); $permErrors = $this->getEditPermissionErrors(); if ($permErrors) { // Auto-block user's IP if the account was "hard" blocked $wgUser->spreadAnyEditBlock(); wfDebug(__METHOD__ . ": User can't edit\n"); $content = $this->getContent(null); $content = $content === '' ? null : $content; $this->readOnlyPage($content, true, $permErrors, 'edit'); wfProfileOut(__METHOD__); return; } else { if ($this->save) { $this->formtype = 'save'; } elseif ($this->preview) { $this->formtype = 'preview'; } elseif ($this->diff) { $this->formtype = 'diff'; } else { # First time through $this->firsttime = true; if ($this->previewOnOpen()) { $this->formtype = 'preview'; } else { $this->formtype = 'initial'; } } } // If they used redlink=1 and the page exists, redirect to the main article if ($wgRequest->getBool('redlink') && $this->mTitle->exists()) { $wgOut->redirect($this->mTitle->getFullURL()); } wfProfileIn(__METHOD__ . "-business-end"); $this->isConflict = false; // css / js subpages of user pages get a special treatment $this->isCssJsSubpage = $this->mTitle->isCssJsSubpage(); $this->isCssSubpage = $this->mTitle->isCssSubpage(); $this->isJsSubpage = $this->mTitle->isJsSubpage(); $this->isWrongCaseCssJsPage = $this->isWrongCaseCssJsPage(); $this->isNew = !$this->mTitle->exists() || $this->section == 'new'; # Show applicable editing introductions if ($this->formtype == 'initial' || $this->firsttime) { $this->showIntro(); } if ($this->mTitle->isTalkPage()) { $wgOut->addWikiMsg('talkpagetext'); } # Optional notices on a per-namespace and per-page basis $editnotice_ns = 'editnotice-' . $this->mTitle->getNamespace(); $editnotice_ns_message = wfMessage($editnotice_ns)->inContentLanguage(); if ($editnotice_ns_message->exists()) { $wgOut->addWikiText($editnotice_ns_message->plain()); } if (MWNamespace::hasSubpages($this->mTitle->getNamespace())) { $parts = explode('/', $this->mTitle->getDBkey()); $editnotice_base = $editnotice_ns; while (count($parts) > 0) { $editnotice_base .= '-' . array_shift($parts); $editnotice_base_msg = wfMessage($editnotice_base)->inContentLanguage(); if ($editnotice_base_msg->exists()) { $wgOut->addWikiText($editnotice_base_msg->plain()); } } } # Attempt submission here. This will check for edit conflicts, # and redundantly check for locked database, blocked IPs, etc. # that edit() already checked just in case someone tries to sneak # in the back door with a hand-edited submission URL. if ('save' == $this->formtype) { if (!$this->attemptSave()) { wfProfileOut(__METHOD__ . "-business-end"); wfProfileOut(__METHOD__); return; } } # First time through: get contents, set time for conflict # checking, etc. if ('initial' == $this->formtype || $this->firsttime) { if ($this->initialiseForm() === false) { $this->noSuchSectionPage(); wfProfileOut(__METHOD__ . "-business-end"); wfProfileOut(__METHOD__); return; } if (!$this->mTitle->getArticleId()) { wfRunHooks('EditFormPreloadText', array(&$this->textbox1, &$this->mTitle)); } else { wfRunHooks('EditFormInitialText', array($this)); } } $this->showEditForm(); wfProfileOut(__METHOD__ . "-business-end"); wfProfileOut(__METHOD__); }
/** * Show the new revision of the page. */ public function renderNewRevision() { wfProfileIn(__METHOD__); $out = $this->getOutput(); $revHeader = $this->getRevisionHeader($this->mNewRev); # Add "current version as of X" title $out->addHTML("<hr class='diff-hr' />\n\t\t<h2 class='diff-currentversion-title'>{$revHeader}</h2>\n"); # Page content may be handled by a hooked call instead... # @codingStandardsIgnoreStart Ignoring long lines. if (wfRunHooks('ArticleContentOnDiff', array($this, $out))) { $this->loadNewText(); $out->setRevisionId($this->mNewid); $out->setRevisionTimestamp($this->mNewRev->getTimestamp()); $out->setArticleFlag(true); // NOTE: only needed for B/C: custom rendering of JS/CSS via hook if ($this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage()) { // Stolen from Article::view --AG 2007-10-11 // Give hooks a chance to customise the output // @todo standardize this crap into one function if (ContentHandler::runLegacyHooks('ShowRawCssJs', array($this->mNewContent, $this->mNewPage, $out))) { // NOTE: deprecated hook, B/C only // use the content object's own rendering $cnt = $this->mNewRev->getContent(); $po = $cnt ? $cnt->getParserOutput($this->mNewRev->getTitle(), $this->mNewRev->getId()) : null; $txt = $po ? $po->getText() : ''; $out->addHTML($txt); } } elseif (!wfRunHooks('ArticleContentViewCustom', array($this->mNewContent, $this->mNewPage, $out))) { // Handled by extension } elseif (!ContentHandler::runLegacyHooks('ArticleViewCustom', array($this->mNewContent, $this->mNewPage, $out))) { // NOTE: deprecated hook, B/C only // Handled by extension } else { // Normal page if ($this->getTitle()->equals($this->mNewPage)) { // If the Title stored in the context is the same as the one // of the new revision, we can use its associated WikiPage // object. $wikiPage = $this->getWikiPage(); } else { // Otherwise we need to create our own WikiPage object $wikiPage = WikiPage::factory($this->mNewPage); } $parserOutput = $this->getParserOutput($wikiPage, $this->mNewRev); # Also try to load it as a redirect $rt = $this->mNewContent ? $this->mNewContent->getRedirectTarget() : null; if ($rt) { $article = Article::newFromTitle($this->mNewPage, $this->getContext()); $out->addHTML($article->viewRedirect($rt)); # WikiPage::getParserOutput() should not return false, but just in case if ($parserOutput) { # Show categories etc. $out->addParserOutputNoText($parserOutput); } } elseif ($parserOutput) { $out->addParserOutput($parserOutput); } } } # @codingStandardsIgnoreEnd # Add redundant patrol link on bottom... $out->addHTML($this->markPatrolledLink()); wfProfileOut(__METHOD__); }
/** * Clear the preloadTitleInfo() cache for all wiki modules on this wiki on * page change if it was a JS or CSS page * * @param Title $title * @param Revision|null $old Prior page revision * @param Revision|null $new New page revision * @param string $wikiId * @since 1.28 */ public static function invalidateModuleCache(Title $title, Revision $old = null, Revision $new = null, $wikiId) { static $formats = [CONTENT_FORMAT_CSS, CONTENT_FORMAT_JAVASCRIPT]; if ($old && in_array($old->getContentFormat(), $formats)) { $purge = true; } elseif ($new && in_array($new->getContentFormat(), $formats)) { $purge = true; } else { $purge = $title->isCssOrJsPage() || $title->isCssJsSubpage(); } if ($purge) { $cache = ObjectCache::getMainWANInstance(); $key = $cache->makeGlobalKey('resourceloader', 'titleinfo', $wikiId); $cache->touchCheckKey($key); } }
/** * Get list of all URLs to be purged for a given Title * * @param Title $title page to be purged * @param Array $urls list of URLs to be purged * @return mixed true - it's a hook */ public static function onTitleGetSquidURLs(Title $title, array $urls) { // if this is a site css or js purge it as well global $wgUseSiteCss, $wgAllowUserJs; global $wgSquidMaxage, $wgJsMimeType; wfProfileIn(__METHOD__); if ($wgUseSiteCss && $title->getNamespace() == NS_MEDIAWIKI) { global $wgServer; $urls[] = $wgServer . '/__am/'; $urls[] = $wgServer . '/__wikia_combined/'; $query = array('usemsgcache' => 'yes', 'ctype' => 'text/css', 'smaxage' => $wgSquidMaxage, 'action' => 'raw', 'maxage' => $wgSquidMaxage); if ($title->getText() == 'Common.css' || $title->getText() == 'Wikia.css') { // BugId:20929 - tell (or trick) varnish to store the latest revisions of Wikia.css and Common.css. $oTitleCommonCss = Title::newFromText('Common.css', NS_MEDIAWIKI); $oTitleWikiaCss = Title::newFromText('Wikia.css', NS_MEDIAWIKI); $query['maxrev'] = max((int) $oTitleWikiaCss->getLatestRevID(), (int) $oTitleCommonCss->getLatestRevID()); unset($oTitleWikiaCss, $oTitleCommonCss); $urls[] = $title->getInternalURL($query); } else { foreach (Skin::getSkinNames() as $skinkey => $skinname) { if ($title->getText() == ucfirst($skinkey) . '.css') { $urls[] = str_replace('text%2Fcss', 'text/css', $title->getInternalURL($query)); // For Artur $urls[] = $title->getInternalURL($query); // For Artur break; } elseif ($title->getText() == 'Common.js') { $urls[] = Skin::makeUrl('-', "action=raw&smaxage=86400&gen=js&useskin=" . urlencode($skinkey)); } } } } elseif ($wgAllowUserJs && $title->isCssJsSubpage()) { if ($title->isJsSubpage()) { $urls[] = $title->getInternalURL('action=raw&ctype=' . $wgJsMimeType); } elseif ($title->isCssSubpage()) { $urls[] = $title->getInternalURL('action=raw&ctype=text/css'); } } // purge Special:RecentChanges too $urls[] = SpecialPage::getTitleFor('RecentChanges')->getInternalURL(); wfProfileOut(__METHOD__); return true; }