From c1f9b1f7b1b77776192048005dcc66dcf3df2bfb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 27 Dec 2014 15:41:37 +0100 Subject: Update to MediaWiki 1.24.1 --- includes/specials/SpecialRecentchanges.php | 562 ++++++++++------------------- 1 file changed, 198 insertions(+), 364 deletions(-) (limited to 'includes/specials/SpecialRecentchanges.php') diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php index a42a2171..e6d8f1c3 100644 --- a/includes/specials/SpecialRecentchanges.php +++ b/includes/specials/SpecialRecentchanges.php @@ -26,12 +26,38 @@ * * @ingroup SpecialPage */ -class SpecialRecentChanges extends IncludableSpecialPage { - var $rcOptions, $rcSubpage; - protected $customFilters; +class SpecialRecentChanges extends ChangesListSpecialPage { + // @codingStandardsIgnoreStart Needed "useless" override to change parameters. + public function __construct( $name = 'Recentchanges', $restriction = '' ) { + parent::__construct( $name, $restriction ); + } + // @codingStandardsIgnoreEnd + + /** + * Main execution point + * + * @param string $subpage + */ + public function execute( $subpage ) { + // Backwards-compatibility: redirect to new feed URLs + $feedFormat = $this->getRequest()->getVal( 'feed' ); + if ( !$this->including() && $feedFormat ) { + $query = $this->getFeedQuery(); + $query['feedformat'] = $feedFormat === 'atom' ? 'atom' : 'rss'; + $this->getOutput()->redirect( wfAppendQuery( wfScript( 'api' ), $query ) ); + + return; + } + + // 10 seconds server-side caching max + $this->getOutput()->setSquidMaxage( 10 ); + // Check if the client has a cached version + $lastmod = $this->checkLastModified(); + if ( $lastmod === false ) { + return; + } - public function __construct( $name = 'Recentchanges' ) { - parent::__construct( $name ); + parent::execute( $subpage ); } /** @@ -40,7 +66,7 @@ class SpecialRecentChanges extends IncludableSpecialPage { * @return FormOptions */ public function getDefaultOptions() { - $opts = new FormOptions(); + $opts = parent::getDefaultOptions(); $user = $this->getUser(); $opts->add( 'days', $user->getIntOption( 'rcdays' ) ); @@ -54,10 +80,6 @@ class SpecialRecentChanges extends IncludableSpecialPage { $opts->add( 'hidepatrolled', $user->getBoolOption( 'hidepatrolled' ) ); $opts->add( 'hidemyself', false ); - $opts->add( 'namespace', '', FormOptions::INTNULL ); - $opts->add( 'invert', false ); - $opts->add( 'associated', false ); - $opts->add( 'categories', '' ); $opts->add( 'categories_any', false ); $opts->add( 'tagfilter', '' ); @@ -65,32 +87,6 @@ class SpecialRecentChanges extends IncludableSpecialPage { return $opts; } - /** - * Create a FormOptions object with options as specified by the user - * - * @param array $parameters - * - * @return FormOptions - */ - public function setup( $parameters ) { - $opts = $this->getDefaultOptions(); - - foreach ( $this->getCustomFilters() as $key => $params ) { - $opts->add( $key, $params['default'] ); - } - - $opts->fetchValuesFromRequest( $this->getRequest() ); - - // Give precedence to subpage syntax - if ( $parameters !== null ) { - $this->parseParameters( $parameters, $opts ); - } - - $opts->validateIntBounds( 'limit', 0, 5000 ); - - return $opts; - } - /** * Get custom show/hide filters * @@ -98,116 +94,15 @@ class SpecialRecentChanges extends IncludableSpecialPage { */ protected function getCustomFilters() { if ( $this->customFilters === null ) { - $this->customFilters = array(); - wfRunHooks( 'SpecialRecentChangesFilters', array( $this, &$this->customFilters ) ); + $this->customFilters = parent::getCustomFilters(); + wfRunHooks( 'SpecialRecentChangesFilters', array( $this, &$this->customFilters ), '1.23' ); } return $this->customFilters; } /** - * Create a FormOptions object specific for feed requests and return it - * - * @return FormOptions - */ - public function feedSetup() { - global $wgFeedLimit; - $opts = $this->getDefaultOptions(); - $opts->fetchValuesFromRequest( $this->getRequest() ); - $opts->validateIntBounds( 'limit', 0, $wgFeedLimit ); - - return $opts; - } - - /** - * Get the current FormOptions for this request - */ - public function getOptions() { - if ( $this->rcOptions === null ) { - if ( $this->including() ) { - $isFeed = false; - } else { - $isFeed = (bool)$this->getRequest()->getVal( 'feed' ); - } - $this->rcOptions = $isFeed ? $this->feedSetup() : $this->setup( $this->rcSubpage ); - } - - return $this->rcOptions; - } - - /** - * Main execution point - * - * @param string $subpage - */ - public function execute( $subpage ) { - $this->rcSubpage = $subpage; - $feedFormat = $this->including() ? null : $this->getRequest()->getVal( 'feed' ); - - # 10 seconds server-side caching max - $this->getOutput()->setSquidMaxage( 10 ); - # Check if the client has a cached version - $lastmod = $this->checkLastModified( $feedFormat ); - if ( $lastmod === false ) { - return; - } - - $opts = $this->getOptions(); - $this->setHeaders(); - $this->outputHeader(); - $this->addModules(); - - // Fetch results, prepare a batch link existence check query - $conds = $this->buildMainQueryConds( $opts ); - $rows = $this->doMainQuery( $conds, $opts ); - if ( $rows === false ) { - if ( !$this->including() ) { - $this->doHeader( $opts ); - } - - return; - } - - if ( !$feedFormat ) { - $batch = new LinkBatch; - foreach ( $rows as $row ) { - $batch->add( NS_USER, $row->rc_user_text ); - $batch->add( NS_USER_TALK, $row->rc_user_text ); - $batch->add( $row->rc_namespace, $row->rc_title ); - } - $batch->execute(); - } - if ( $feedFormat ) { - list( $changesFeed, $formatter ) = $this->getFeedObject( $feedFormat ); - /** @var ChangesFeed $changesFeed */ - $changesFeed->execute( $formatter, $rows, $lastmod, $opts ); - } else { - $this->webOutput( $rows, $opts ); - } - - $rows->free(); - } - - /** - * Return an array with a ChangesFeed object and ChannelFeed object - * - * @param string $feedFormat Feed's format (either 'rss' or 'atom') - * @return array - */ - public function getFeedObject( $feedFormat ) { - $changesFeed = new ChangesFeed( $feedFormat, 'rcfeed' ); - $formatter = $changesFeed->getFeedObject( - $this->msg( 'recentchanges' )->inContentLanguage()->text(), - $this->msg( 'recentchanges-feed-description' )->inContentLanguage()->text(), - $this->getTitle()->getFullURL() - ); - - return array( $changesFeed, $formatter ); - } - - /** - * Process $par and put options found if $opts - * Mainly used when including the page + * Process $par and put options found in $opts. Used when including the page. * * @param string $par * @param FormOptions $opts @@ -257,25 +152,9 @@ class SpecialRecentChanges extends IncludableSpecialPage { } } - /** - * Get last modified date, for client caching - * Don't use this if we are using the patrol feature, patrol changes don't - * update the timestamp - * - * @param string $feedFormat - * @return string|bool - */ - public function checkLastModified( $feedFormat ) { - $dbr = wfGetDB( DB_SLAVE ); - $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, __METHOD__ ); - if ( $feedFormat || !$this->getUser()->useRCPatrol() ) { - if ( $lastmod && $this->getOutput()->checkLastModified( $lastmod ) ) { - # Client cache fresh and headers sent, nothing more to do. - return false; - } - } - - return $lastmod; + public function validateOptions( FormOptions $opts ) { + $opts->validateIntBounds( 'limit', 0, 5000 ); + parent::validateOptions( $opts ); } /** @@ -285,21 +164,8 @@ class SpecialRecentChanges extends IncludableSpecialPage { * @return array */ public function buildMainQueryConds( FormOptions $opts ) { - $dbr = wfGetDB( DB_SLAVE ); - $conds = array(); - - # It makes no sense to hide both anons and logged-in users - # Where this occurs, force anons to be shown - $forcebot = false; - if ( $opts['hideanons'] && $opts['hideliu'] ) { - # Check if the user wants to show bots only - if ( $opts['hidebots'] ) { - $opts['hideanons'] = false; - } else { - $forcebot = true; - $opts['hidebots'] = false; - } - } + $dbr = $this->getDB(); + $conds = parent::buildMainQueryConds( $opts ); // Calculate cutoff $cutoff_unixtime = time() - ( $opts['days'] * 86400 ); @@ -315,59 +181,6 @@ class SpecialRecentChanges extends IncludableSpecialPage { $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes( $cutoff ); - $hidePatrol = $this->getUser()->useRCPatrol() && $opts['hidepatrolled']; - $hideLoggedInUsers = $opts['hideliu'] && !$forcebot; - $hideAnonymousUsers = $opts['hideanons'] && !$forcebot; - - if ( $opts['hideminor'] ) { - $conds['rc_minor'] = 0; - } - if ( $opts['hidebots'] ) { - $conds['rc_bot'] = 0; - } - if ( $hidePatrol ) { - $conds['rc_patrolled'] = 0; - } - if ( $forcebot ) { - $conds['rc_bot'] = 1; - } - if ( $hideLoggedInUsers ) { - $conds[] = 'rc_user = 0'; - } - if ( $hideAnonymousUsers ) { - $conds[] = 'rc_user != 0'; - } - - if ( $opts['hidemyself'] ) { - if ( $this->getUser()->getId() ) { - $conds[] = 'rc_user != ' . $dbr->addQuotes( $this->getUser()->getId() ); - } else { - $conds[] = 'rc_user_text != ' . $dbr->addQuotes( $this->getUser()->getName() ); - } - } - - # Namespace filtering - if ( $opts['namespace'] !== '' ) { - $selectedNS = $dbr->addQuotes( $opts['namespace'] ); - $operator = $opts['invert'] ? '!=' : '='; - $boolean = $opts['invert'] ? 'AND' : 'OR'; - - # namespace association (bug 2429) - if ( !$opts['associated'] ) { - $condition = "rc_namespace $operator $selectedNS"; - } else { - # Also add the associated namespace - $associatedNS = $dbr->addQuotes( - MWNamespace::getAssociated( $opts['namespace'] ) - ); - $condition = "(rc_namespace $operator $selectedNS " - . $boolean - . " rc_namespace $operator $associatedNS)"; - } - - $conds[] = $condition; - } - return $conds; } @@ -379,37 +192,32 @@ class SpecialRecentChanges extends IncludableSpecialPage { * @return bool|ResultWrapper Result or false (for Recentchangeslinked only) */ public function doMainQuery( $conds, $opts ) { + $dbr = $this->getDB(); + $user = $this->getUser(); + $tables = array( 'recentchanges' ); + $fields = RecentChange::selectFields(); + $query_options = array(); $join_conds = array(); - $query_options = array( - 'USE INDEX' => array( 'recentchanges' => 'rc_timestamp' ) - ); - - $uid = $this->getUser()->getId(); - $dbr = wfGetDB( DB_SLAVE ); - $limit = $opts['limit']; - $namespace = $opts['namespace']; - $invert = $opts['invert']; - $associated = $opts['associated']; - $fields = RecentChange::selectFields(); // JOIN on watchlist for users - if ( $uid && $this->getUser()->isAllowed( 'viewmywatchlist' ) ) { + if ( $user->getId() && $user->isAllowed( 'viewmywatchlist' ) ) { $tables[] = 'watchlist'; $fields[] = 'wl_user'; $fields[] = 'wl_notificationtimestamp'; $join_conds['watchlist'] = array( 'LEFT JOIN', array( - 'wl_user' => $uid, + 'wl_user' => $user->getId(), 'wl_title=rc_title', 'wl_namespace=rc_namespace' ) ); } - if ( $this->getUser()->isAllowed( 'rollback' ) ) { + + if ( $user->isAllowed( 'rollback' ) ) { $tables[] = 'page'; $fields[] = 'page_latest'; $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' ); } - // Tag stuff. + ChangeTags::modifyDisplayQuery( $tables, $fields, @@ -419,48 +227,81 @@ class SpecialRecentChanges extends IncludableSpecialPage { $opts['tagfilter'] ); - if ( !wfRunHooks( 'SpecialRecentChangesQuery', - array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$fields ) ) + if ( !$this->runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, + $opts ) ) { return false; } // rc_new is not an ENUM, but adding a redundant rc_new IN (0,1) gives mysql enough // knowledge to use an index merge if it wants (it may use some other index though). - return $dbr->select( + $rows = $dbr->select( $tables, $fields, $conds + array( 'rc_new' => array( 0, 1 ) ), __METHOD__, - array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) + $query_options, + array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $opts['limit'] ) + $query_options, $join_conds ); + + // Build the final data + if ( $this->getConfig()->get( 'AllowCategorizedRecentChanges' ) ) { + $this->filterByCategories( $rows, $opts ); + } + + return $rows; + } + + protected function runMainQueryHook( &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) { + return parent::runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts ) + && wfRunHooks( + 'SpecialRecentChangesQuery', + array( &$conds, &$tables, &$join_conds, $opts, &$query_options, &$fields ), + '1.23' + ); + } + + public function outputFeedLinks() { + $this->addFeedLinks( $this->getFeedQuery() ); } /** - * Send output to the OutputPage object, only called if not used feeds + * Get URL query parameters for action=feedrecentchanges API feed of current recent changes view. + * + * @return array + */ + private function getFeedQuery() { + $query = array_filter( $this->getOptions()->getAllValues(), function ( $value ) { + // API handles empty parameters in a different way + return $value !== ''; + } ); + $query['action'] = 'feedrecentchanges'; + $feedLimit = $this->getConfig()->get( 'FeedLimit' ); + if ( $query['limit'] > $feedLimit ) { + $query['limit'] = $feedLimit; + } + + return $query; + } + + /** + * Build and output the actual changes list. * * @param array $rows Database rows * @param FormOptions $opts */ - public function webOutput( $rows, $opts ) { - global $wgRCShowWatchingUsers, $wgShowUpdatedMarker, $wgAllowCategorizedRecentChanges; - - // Build the final data - - if ( $wgAllowCategorizedRecentChanges ) { - $this->filterByCategories( $rows, $opts ); - } - + public function outputChangesList( $rows, $opts ) { $limit = $opts['limit']; - $showWatcherCount = $wgRCShowWatchingUsers && $this->getUser()->getOption( 'shownumberswatching' ); + $showWatcherCount = $this->getConfig()->get( 'RCShowWatchingUsers' ) + && $this->getUser()->getOption( 'shownumberswatching' ); $watcherCache = array(); - $dbr = wfGetDB( DB_SLAVE ); + $dbr = $this->getDB(); $counter = 1; $list = ChangesList::newFromContext( $this->getContext() ); + $list->initChangesListRows( $rows ); $rclistOutput = $list->beginRecentChangesList(); foreach ( $rows as $obj ) { @@ -470,7 +311,7 @@ class SpecialRecentChanges extends IncludableSpecialPage { $rc = RecentChange::newFromRow( $obj ); $rc->counter = $counter++; # Check if the page has been updated since the last visit - if ( $wgShowUpdatedMarker && !empty( $obj->wl_notificationtimestamp ) ) { + if ( $this->getConfig()->get( 'ShowUpdatedMarker' ) && !empty( $obj->wl_notificationtimestamp ) ) { $rc->notificationtimestamp = ( $obj->rc_timestamp >= $obj->wl_notificationtimestamp ); } else { $rc->notificationtimestamp = false; // Default @@ -501,68 +342,35 @@ class SpecialRecentChanges extends IncludableSpecialPage { } $rclistOutput .= $list->endRecentChangesList(); - // Print things out - - if ( !$this->including() ) { - // Output options box - $this->doHeader( $opts ); - } - - // And now for the content - $feedQuery = $this->getFeedQuery(); - if ( $feedQuery !== '' ) { - $this->getOutput()->setFeedAppendQuery( $feedQuery ); - } else { - $this->getOutput()->setFeedAppendQuery( false ); - } - if ( $rows->numRows() === 0 ) { - $this->getOutput()->wrapWikiMsg( - "
\n$1\n
", 'recentchanges-noresult' + $this->getOutput()->addHtml( + '
' . + $this->msg( 'recentchanges-noresult' )->parse() . + '
' ); + if ( !$this->including() ) { + $this->getOutput()->setStatusCode( 404 ); + } } else { $this->getOutput()->addHTML( $rclistOutput ); } } /** - * Get the query string to append to feed link URLs. - * - * @return string - */ - public function getFeedQuery() { - global $wgFeedLimit; - - $this->getOptions()->validateIntBounds( 'limit', 0, $wgFeedLimit ); - $options = $this->getOptions()->getChangedValues(); - - // wfArrayToCgi() omits options set to null or false - foreach ( $options as &$value ) { - if ( $value === false ) { - $value = '0'; - } - } - unset( $value ); - - return wfArrayToCgi( $options ); - } - - /** - * Return the text to be displayed above the changes + * Set the text to be displayed above the changes * * @param FormOptions $opts - * @return string XHTML + * @param int $numRows Number of rows in the result to show after this header */ - public function doHeader( $opts ) { - global $wgScript; - + public function doHeader( $opts, $numRows ) { $this->setTopText( $opts ); $defaults = $opts->getAllValues(); $nondefaults = $opts->getChangedValues(); $panel = array(); - $panel[] = $this->optionsPanel( $defaults, $nondefaults ); + $panel[] = self::makeLegend( $this->getContext() ); + $panel[] = $this->optionsPanel( $defaults, $nondefaults, $numRows ); $panel[] = '
'; $extraOpts = $this->getExtraOptions( $opts ); @@ -604,9 +412,9 @@ class SpecialRecentChanges extends IncludableSpecialPage { $out .= Html::hidden( $key, $value ); } - $t = $this->getTitle(); + $t = $this->getPageTitle(); $out .= Html::hidden( 'title', $t->getPrefixedText() ); - $form = Xml::tags( 'form', array( 'action' => $wgScript ), $out ); + $form = Xml::tags( 'form', array( 'action' => wfScript() ), $out ); $panel[] = $form; $panelString = implode( "\n", $panel ); @@ -621,6 +429,27 @@ class SpecialRecentChanges extends IncludableSpecialPage { $this->setBottomText( $opts ); } + /** + * Send the text to be displayed above the options + * + * @param FormOptions $opts Unused + */ + function setTopText( FormOptions $opts ) { + global $wgContLang; + + $message = $this->msg( 'recentchangestext' )->inContentLanguage(); + if ( !$message->isDisabled() ) { + $this->getOutput()->addWikiText( + Html::rawElement( 'p', + array( 'lang' => $wgContLang->getCode(), 'dir' => $wgContLang->getDir() ), + "\n" . $message->plain() . "\n" + ), + /* $lineStart */ false, + /* $interface */ false + ); + } + } + /** * Get options to be displayed in a form * @@ -635,8 +464,7 @@ class SpecialRecentChanges extends IncludableSpecialPage { $extraOpts = array(); $extraOpts['namespace'] = $this->namespaceFilterForm( $opts ); - global $wgAllowCategorizedRecentChanges; - if ( $wgAllowCategorizedRecentChanges ) { + if ( $this->getConfig()->get( 'AllowCategorizedRecentChanges' ) ) { $extraOpts['category'] = $this->categoryFilterForm( $opts ); } @@ -654,38 +482,31 @@ class SpecialRecentChanges extends IncludableSpecialPage { } /** - * Send the text to be displayed above the options - * - * @param FormOptions $opts Unused + * Add page-specific modules. */ - function setTopText( FormOptions $opts ) { - global $wgContLang; - - $message = $this->msg( 'recentchangestext' )->inContentLanguage(); - if ( !$message->isDisabled() ) { - $this->getOutput()->addWikiText( - Html::rawElement( 'p', - array( 'lang' => $wgContLang->getCode(), 'dir' => $wgContLang->getDir() ), - "\n" . $message->plain() . "\n" - ), - /* $lineStart */ false, - /* $interface */ false - ); - } + protected function addModules() { + parent::addModules(); + $out = $this->getOutput(); + $out->addModules( 'mediawiki.special.recentchanges' ); } /** - * Send the text to be displayed after the options, for use in subclasses. + * Get last modified date, for client caching + * Don't use this if we are using the patrol feature, patrol changes don't + * update the timestamp * - * @param FormOptions $opts + * @return string|bool */ - function setBottomText( FormOptions $opts ) { + public function checkLastModified() { + $dbr = $this->getDB(); + $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, __METHOD__ ); + + return $lastmod; } /** * Creates the choose namespace selection * - * @todo Uses radio buttons (HASHAR) * @param FormOptions $opts * @return string */ @@ -710,7 +531,7 @@ class SpecialRecentChanges extends IncludableSpecialPage { } /** - * Create a input to filter changes by categories + * Create an input to filter changes by categories * * @param FormOptions $opts * @return array @@ -728,7 +549,7 @@ class SpecialRecentChanges extends IncludableSpecialPage { /** * Filter $rows by categories set in $opts * - * @param array $rows Database rows + * @param ResultWrapper $rows Database rows * @param FormOptions $opts */ function filterByCategories( &$rows, FormOptions $opts ) { @@ -774,9 +595,9 @@ class SpecialRecentChanges extends IncludableSpecialPage { } # Look up - $c = new Categoryfinder; - $c->seed( $articles, $cats, $opts['categories_any'] ? 'OR' : 'AND' ); - $match = $c->run(); + $catFind = new CategoryFinder; + $catFind->seed( $articles, $cats, $opts['categories_any'] ? 'OR' : 'AND' ); + $match = $catFind->run(); # Filter $newrows = array(); @@ -815,7 +636,7 @@ class SpecialRecentChanges extends IncludableSpecialPage { $text = '' . $text . ''; } - return Linker::linkKnown( $this->getTitle(), $text, array(), $params ); + return Linker::linkKnown( $this->getPageTitle(), $text, array(), $params ); } /** @@ -823,11 +644,10 @@ class SpecialRecentChanges extends IncludableSpecialPage { * * @param array $defaults * @param array $nondefaults + * @param int $numRows Number of rows in the result to show after this header * @return string */ - function optionsPanel( $defaults, $nondefaults ) { - global $wgRCLinkLimits, $wgRCLinkDays; - + function optionsPanel( $defaults, $nondefaults, $numRows ) { $options = $nondefaults + $defaults; $note = ''; @@ -839,19 +659,24 @@ class SpecialRecentChanges extends IncludableSpecialPage { $lang = $this->getLanguage(); $user = $this->getUser(); if ( $options['from'] ) { - $note .= $this->msg( 'rcnotefrom' )->numParams( $options['limit'] )->params( - $lang->userTimeAndDate( $options['from'], $user ), - $lang->userDate( $options['from'], $user ), - $lang->userTime( $options['from'], $user ) )->parse() . '
'; + $note .= $this->msg( 'rcnotefrom' ) + ->numParams( $options['limit'] ) + ->params( + $lang->userTimeAndDate( $options['from'], $user ), + $lang->userDate( $options['from'], $user ), + $lang->userTime( $options['from'], $user ) + ) + ->numParams( $numRows ) + ->parse() . '
'; } # Sort data for display and make sure it's unique after we've added user data. - $linkLimits = $wgRCLinkLimits; + $linkLimits = $this->getConfig()->get( 'RCLinkLimits' ); $linkLimits[] = $options['limit']; sort( $linkLimits ); $linkLimits = array_unique( $linkLimits ); - $linkDays = $wgRCLinkDays; + $linkDays = $this->getConfig()->get( 'RCLinkDays' ); $linkDays[] = $options['days']; sort( $linkDays ); $linkDays = array_unique( $linkDays ); @@ -873,7 +698,6 @@ class SpecialRecentChanges extends IncludableSpecialPage { $dl = $lang->pipeList( $dl ); // show/hide links - $showhide = array( $this->msg( 'show' )->text(), $this->msg( 'hide' )->text() ); $filters = array( 'hideminor' => 'rcshowhideminor', 'hidebots' => 'rcshowhidebots', @@ -882,6 +706,9 @@ class SpecialRecentChanges extends IncludableSpecialPage { 'hidepatrolled' => 'rcshowhidepatr', 'hidemyself' => 'rcshowhidemine' ); + + $showhide = array( 'show', 'hide' ); + foreach ( $this->getCustomFilters() as $key => $params ) { $filters[$key] = $params['msg']; } @@ -892,35 +719,42 @@ class SpecialRecentChanges extends IncludableSpecialPage { $links = array(); foreach ( $filters as $key => $msg ) { - $link = $this->makeOptionsLink( $showhide[1 - $options[$key]], + // The following messages are used here: + // rcshowhideminor-show, rcshowhideminor-hide, rcshowhidebots-show, rcshowhidebots-hide, + // rcshowhideanons-show, rcshowhideanons-hide, rcshowhideliu-show, rcshowhideliu-hide, + // rcshowhidepatr-show, rcshowhidepatr-hide, rcshowhidemine-show, rcshowhidemine-hide. + $linkMessage = $this->msg( $msg . '-' . $showhide[1 - $options[$key]] ); + // Extensions can define additional filters, but don't need to define the corresponding + // messages. If they don't exist, just fall back to 'show' and 'hide'. + if ( !$linkMessage->exists() ) { + $linkMessage = $this->msg( $showhide[1 - $options[$key]] ); + } + + $link = $this->makeOptionsLink( $linkMessage->text(), array( $key => 1 - $options[$key] ), $nondefaults ); - $links[] = $this->msg( $msg )->rawParams( $link )->escaped(); + $links[] = "" . $this->msg( $msg )->rawParams( $link )->escaped() . ''; } // show from this onward link $timestamp = wfTimestampNow(); $now = $lang->userTimeAndDate( $timestamp, $user ); - $tl = $this->makeOptionsLink( - $now, array( 'from' => $timestamp ), $nondefaults - ); + $timenow = $lang->userTime( $timestamp, $user ); + $datenow = $lang->userDate( $timestamp, $user ); + $pipedLinks = '' . $lang->pipeList( $links ) . ''; - $rclinks = $this->msg( 'rclinks' )->rawParams( $cl, $dl, $lang->pipeList( $links ) ) - ->parse(); - $rclistfrom = $this->msg( 'rclistfrom' )->rawParams( $tl )->parse(); + $rclinks = '' . $this->msg( 'rclinks' )->rawParams( $cl, $dl, $pipedLinks ) + ->parse() . ''; - return "{$note}$rclinks
$rclistfrom"; - } + $rclistfrom = '' . $this->makeOptionsLink( + $this->msg( 'rclistfrom' )->rawParams( $now, $timenow, $datenow )->parse(), + array( 'from' => $timestamp ), + $nondefaults + ) . ''; - /** - * Add page-specific modules. - */ - protected function addModules() { - $this->getOutput()->addModules( array( - 'mediawiki.special.recentchanges', - ) ); + return "{$note}$rclinks
$rclistfrom"; } - protected function getGroupName() { - return 'changes'; + public function isIncludable() { + return true; } } -- cgit v1.2.2