From 2629c3649facd6f6bcdccf7f3e62cd43eed73493 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Sat, 10 Dec 2011 16:30:40 +0000 Subject: [PATCH] * Added revision's timestamp to OutputPage along with revision ID; avoid a DB hit in Skin::lastModified() when showing parser cache's content. This changed with the removal of $wgArticle in Skin since now it's a different WikiPage object and thus WikiPage::setTimetstamp() call is useless (but still kept). * Added ParserOutput::(get|set)Timestamp() and the $mTimestamp member; avoid messing with isset() --- includes/Article.php | 9 +++++---- includes/OutputPage.php | 22 ++++++++++++++++++++++ includes/Skin.php | 10 +++++----- includes/SkinTemplate.php | 2 +- includes/diff/DifferenceEngine.php | 1 + includes/parser/ParserCache.php | 2 +- includes/parser/ParserOutput.php | 7 +++++-- 7 files changed, 40 insertions(+), 13 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 5945db7247..f073b5a75c 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -497,11 +497,10 @@ class Article extends Page { # Ensure that UI elements requiring revision ID have # the correct version information. $wgOut->setRevisionId( $this->mPage->getLatest() ); - $outputDone = true; # Preload timestamp to avoid a DB hit - if ( isset( $this->mParserOutput->mTimestamp ) ) { - $this->mPage->setTimestamp( $this->mParserOutput->mTimestamp ); - } + $wgOut->setRevisionTimestamp( $this->mParserOutput->getTimestamp() ); + $this->mPage->setTimestamp( $this->mParserOutput->getTimestamp() ); + $outputDone = true; } } break; @@ -523,6 +522,8 @@ class Article extends Page { # 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() ) { diff --git a/includes/OutputPage.php b/includes/OutputPage.php index feae2c1451..8c3d647a53 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -197,6 +197,7 @@ class OutputPage extends ContextSource { /// should be private. To include the variable {{REVISIONID}} var $mRevisionId = null; + private $mRevisionTimestamp = null; var $mFileVersion = null; @@ -1339,6 +1340,27 @@ class OutputPage extends ContextSource { return $this->mRevisionId; } + /** + * Set the timestamp of the revision which will be displayed. This is used + * to avoid a extra DB call in Skin::lastModified(). + * + * @param $revid Mixed: string, or null + * @return Mixed: previous value + */ + public function setRevisionTimestamp( $timestmap ) { + return wfSetVar( $this->mRevisionTimestamp, $timestmap ); + } + + /** + * Get the timestamp of displayed revision. + * This will be null if not filled by setRevisionTimestamp(). + * + * @return String or null + */ + public function getRevisionTimestamp() { + return $this->mRevisionTimestamp; + } + /** * Set the displayed file version * diff --git a/includes/Skin.php b/includes/Skin.php index 03a83381b6..eb890b2772 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -828,14 +828,14 @@ abstract class Skin extends ContextSource { /** * Get the timestamp of the latest revision, formatted in user language * - * @param $page WikiPage object. Used if we're working with the current revision * @return String */ - protected function lastModified( $page ) { - if ( !$this->isRevisionCurrent() ) { + protected function lastModified() { + $timestamp = $this->getOutput()->getRevisionTimestamp(); + + # No cached timestamp, load it from the database + if ( $timestamp === null ) { $timestamp = Revision::getTimestampFromId( $this->getTitle(), $this->getRevisionId() ); - } else { - $timestamp = $page->getTimestamp(); } if ( $timestamp ) { diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php index c56bd6f8d6..f78ae83044 100644 --- a/includes/SkinTemplate.php +++ b/includes/SkinTemplate.php @@ -353,7 +353,7 @@ class SkinTemplate extends Skin { if ( $wgMaxCredits != 0 ) { $tpl->set( 'credits', Action::factory( 'credits', $page, $this->getContext() )->getCredits( $wgMaxCredits, $wgShowCreditsIfMax ) ); } else { - $tpl->set( 'lastmod', $this->lastModified( $page ) ); + $tpl->set( 'lastmod', $this->lastModified() ); } } $tpl->set( 'copyright', $this->getCopyright() ); diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index 6fd2d64227..3236e61ba4 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -499,6 +499,7 @@ class DifferenceEngine extends ContextSource { if ( wfRunHooks( 'ArticleContentOnDiff', array( $this, $out ) ) ) { $this->loadNewText(); $out->setRevisionId( $this->mNewid ); + $out->setRevisionTimestamp( $this->mNewRev->getTimestamp() ); $out->setArticleFlag( true ); if ( $this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage() ) { diff --git a/includes/parser/ParserCache.php b/includes/parser/ParserCache.php index 54a27b45bf..f91f26a2ff 100644 --- a/includes/parser/ParserCache.php +++ b/includes/parser/ParserCache.php @@ -220,7 +220,7 @@ class ParserCache { $popts->optionsHash( $optionsKey->mUsedOptions, $article->getTitle() ) ); // Save the timestamp so that we don't have to load the revision row on view - $parserOutput->mTimestamp = $article->getTimestamp(); + $parserOutput->setTimestamp( $article->getTimestamp() ); $parserOutput->mText .= "\n\n"; wfDebug( "Saved in parser cache with key $parserOutputKey and timestamp $now\n" ); diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index 2e80f4e30f..2877dcb00f 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -138,8 +138,9 @@ class ParserOutput extends CacheTime { $mSections = array(), # Table of contents $mEditSectionTokens = false, # prefix/suffix markers if edit sections were output as tokens $mProperties = array(), # Name/value pairs to be cached in the DB - $mTOCHTML = ''; # HTML of the TOC - private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change. + $mTOCHTML = '', # HTML of the TOC + $mTimestamp; # Timestamp of the revision + private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change. private $mAccessedOptions = array(); # List of ParserOptions (stored in the keys) const EDITSECTION_REGEX = '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)())#'; @@ -205,6 +206,7 @@ class ParserOutput extends CacheTime { function getWarnings() { return array_keys( $this->mWarnings ); } function getIndexPolicy() { return $this->mIndexPolicy; } function getTOCHTML() { return $this->mTOCHTML; } + function getTimestamp() { return $this->mTimestamp; } function setText( $text ) { return wfSetVar( $this->mText, $text ); } function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); } @@ -215,6 +217,7 @@ class ParserOutput extends CacheTime { function setEditSectionTokens( $t ) { return wfSetVar( $this->mEditSectionTokens, $t ); } function setIndexPolicy( $policy ) { return wfSetVar( $this->mIndexPolicy, $policy ); } function setTOCHTML( $tochtml ) { return wfSetVar( $this->mTOCHTML, $tochtml ); } + function setTimestamp( $timestamp ) { return wfSetVar( $this->mTimestamp, $timestamp ); } function addCategory( $c, $sort ) { $this->mCategories[$c] = $sort; } function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; } -- 2.20.1