From: umherirrender Date: Tue, 29 Oct 2013 21:02:59 +0000 (+0100) Subject: Add expensive parser functions {{REVISION*:}} X-Git-Tag: 1.31.0-rc.0~18295^2 X-Git-Url: http://git.cyclocoop.org/data/%24oldEdit?a=commitdiff_plain;h=1523621054e81380a724e0956447b66e8b85f4d0;p=lhc%2Fweb%2Fwiklou.git Add expensive parser functions {{REVISION*:}} The magic words REVISIONID, REVISIONUSER and REVISIONTIMESTAMP (with friends) now exists as parser function to fetch revision information from another page specified as param to the parser function. Invalid title or non-existing title will return an empty string. Requesting revision deleted information will always return an empty string, because this is for public audience and goes into the parser cache. The parser function will register a template link to get updated with refresh jobs on edit of the remote page. This is the same way, than the parser function pagesize is working. When the given param is equal to the current title of the parser, the parser function will yield the previous versions on preview and on substitution, that includes empty strings when used on page creation, but using the values from the current version for page view, including viewing old revisions. Bug: 6092 Change-Id: Ib15a4e54c65192ec3caef71fd5dcb93fb6fc444e --- diff --git a/RELEASE-NOTES-1.23 b/RELEASE-NOTES-1.23 index 6c7825388b..711b8a9142 100644 --- a/RELEASE-NOTES-1.23 +++ b/RELEASE-NOTES-1.23 @@ -18,6 +18,8 @@ production. This capability can be enabled by setting $wgResourceLoaderStorageEnabled to true. This feature is currently considered experimental and should only be enabled with care. +* (bug 6092) Add expensive parser functions {{REVISIONID:}}, {{REVISIONUSER:}} + and {{REVISIONTIMESTAMP:}} (with friends). === Bug fixes in 1.23 === * (bug 41759) The "updated since last visit" markers (on history pages, recent diff --git a/includes/parser/CoreParserFunctions.php b/includes/parser/CoreParserFunctions.php index 4b6eeca2fe..44c7458161 100644 --- a/includes/parser/CoreParserFunctions.php +++ b/includes/parser/CoreParserFunctions.php @@ -100,6 +100,15 @@ class CoreParserFunctions { $parser->setFunctionHook( 'subjectpagenamee', array( __CLASS__, 'subjectpagenamee' ), SFH_NO_HASH ); $parser->setFunctionHook( 'tag', array( __CLASS__, 'tagObj' ), SFH_OBJECT_ARGS ); $parser->setFunctionHook( 'formatdate', array( __CLASS__, 'formatDate' ) ); + $parser->setFunctionHook( 'pageid', array( __CLASS__, 'pageid' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionid', array( __CLASS__, 'revisionid' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionday', array( __CLASS__, 'revisionday' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionday2', array( __CLASS__, 'revisionday2' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionmonth', array( __CLASS__, 'revisionmonth' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionmonth1', array( __CLASS__, 'revisionmonth1' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionyear', array( __CLASS__, 'revisionyear' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisiontimestamp', array( __CLASS__, 'revisiontimestamp' ), SFH_NO_HASH ); + $parser->setFunctionHook( 'revisionuser', array( __CLASS__, 'revisionuser' ), SFH_NO_HASH ); if ( $wgAllowDisplayTitle ) { $parser->setFunctionHook( 'displaytitle', array( __CLASS__, 'displaytitle' ), SFH_NO_HASH ); @@ -707,29 +716,15 @@ class CoreParserFunctions { * @return string */ static function pagesize( $parser, $page = '', $raw = null ) { - static $cache = array(); $title = Title::newFromText( $page ); if ( !is_object( $title ) ) { - $cache[$page] = 0; return self::formatRaw( 0, $raw ); } - # Normalize name for cache - $page = $title->getPrefixedText(); - - $length = 0; - if ( isset( $cache[$page] ) ) { - $length = $cache[$page]; - } elseif ( $parser->incrementExpensiveFunctionCount() ) { - $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL ); - $pageID = $rev ? $rev->getPage() : 0; - $revID = $rev ? $rev->getId() : 0; - $length = $cache[$page] = $rev ? $rev->getSize() : 0; - - // Register dependency in templatelinks - $parser->mOutput->addTemplate( $title, $pageID, $revID ); - } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $title ); + $length = $rev ? $rev->getSize() : 0; return self::formatRaw( $length, $raw ); } @@ -949,4 +944,204 @@ class CoreParserFunctions { ); return $parser->extensionSubstitution( $params, $frame ); } + + /** + * Fetched the current revision of the given title and return this. + * Will increment the expensive function count and + * add a template link to get the value refreshed on changes. + * For a given title, which is equal to the current parser title, + * the revision object from the parser is used, when that is the current one + * + * @param $parser Parser + * @param $title Title + * @return Revision + * @since 1.23 + */ + private static function getCachedRevisionObject( $parser, $title = null ) { + static $cache = array(); + + if ( is_null( $title ) ) { + return null; + } + + // Use the revision from the parser itself, when param is the current page + // and the revision is the current one + if ( $title->equals( $parser->getTitle() ) ) { + $parserRev = $parser->getRevisionObject(); + if ( $parserRev && $parserRev->isCurrent() ) { + // force reparse after edit with vary-revision flag + $parser->getOutput()->setFlag( 'vary-revision' ); + wfDebug( __METHOD__ . ": use current revision from parser, setting vary-revision...\n" ); + return $parserRev; + } + } + + // Normalize name for cache + $page = $title->getPrefixedDBkey(); + + if ( array_key_exists( $page, $cache ) ) { // cache contains null values + return $cache[$page]; + } + if ( $parser->incrementExpensiveFunctionCount() ) { + $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL ); + $pageID = $rev ? $rev->getPage() : 0; + $revID = $rev ? $rev->getId() : 0; + $cache[$page] = $rev; // maybe null + + // Register dependency in templatelinks + $parser->getOutput()->addTemplate( $title, $pageID, $revID ); + + return $rev; + } + $cache[$page] = null; + return null; + } + + /** + * Get the pageid of a specified page + * @param $parser Parser + * @param $title string Title to get the pageid from + * @since 1.23 + */ + public static function pageid( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // Use title from parser to have correct pageid after edit + if ( $t->equals( $parser->getTitle() ) ) { + $t = $parser->getTitle(); + } + // fetch pageid from cache/database and return the value + $pageid = $t->getArticleID(); + return $pageid ? $pageid : ''; + } + + /** + * Get the id from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the id from + * @since 1.23 + */ + public static function revisionid( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? $rev->getId() : ''; + } + + /** + * Get the day from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the day from + * @since 1.23 + */ + public static function revisionday( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'j' ) : ''; + } + + /** + * Get the day with leading zeros from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the day from + * @since 1.23 + */ + public static function revisionday2( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'd' ) : ''; + } + + /** + * Get the month with leading zeros from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the month from + * @since 1.23 + */ + public static function revisionmonth( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'm' ) : ''; + } + + /** + * Get the month from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the month from + * @since 1.23 + */ + public static function revisionmonth1( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'n' ) : ''; + } + + /** + * Get the year from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the year from + * @since 1.23 + */ + public static function revisionyear( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'Y' ) : ''; + } + + /** + * Get the timestamp from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the timestamp from + * @since 1.23 + */ + public static function revisiontimestamp( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'YmdHis' ) : ''; + } + + /** + * Get the user from the last revision of a specified page. + * @param $parser Parser + * @param $title string Title to get the user from + * @since 1.23 + */ + public static function revisionuser( $parser, $title = null ) { + $t = Title::newFromText( $title ); + if ( is_null( $t ) ) { + return ''; + } + // fetch revision from cache/database and return the value + $rev = self::getCachedRevisionObject( $parser, $t ); + return $rev ? $rev->getUserText() : ''; + } } diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 1f14223d69..be7fc033a6 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -5760,8 +5760,9 @@ class Parser { * Get the revision object for $this->mRevisionId * * @return Revision|null either a Revision object or null + * @since 1.23 (public since 1.23) */ - protected function getRevisionObject() { + public function getRevisionObject() { if ( !is_null( $this->mRevisionObject ) ) { return $this->mRevisionObject; }