2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2010-06-21 12:59:04 +00:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
2010-06-21 13:16:32 +00:00
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2010-06-21 12:59:04 +00:00
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
|
*/
|
2008-06-26 19:12:52 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
2008-06-26 19:12:52 +00:00
|
|
|
* Implements Special:Recentchanges
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @ingroup SpecialPage
|
2004-09-02 23:28:24 +00:00
|
|
|
*/
|
2010-07-17 19:04:07 +00:00
|
|
|
class SpecialRecentChanges extends IncludableSpecialPage {
|
2010-02-10 04:13:43 +00:00
|
|
|
var $rcOptions, $rcSubpage;
|
|
|
|
|
|
2010-07-17 19:04:07 +00:00
|
|
|
public function __construct( $name = 'Recentchanges' ) {
|
|
|
|
|
parent::__construct( $name );
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Get a FormOptions object containing the default options
|
|
|
|
|
*
|
|
|
|
|
* @return FormOptions
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function getDefaultOptions() {
|
2008-07-25 16:46:43 +00:00
|
|
|
global $wgUser;
|
2008-06-17 08:24:00 +00:00
|
|
|
$opts = new FormOptions();
|
|
|
|
|
|
2008-07-25 16:46:43 +00:00
|
|
|
$opts->add( 'days', (int)$wgUser->getOption( 'rcdays' ) );
|
|
|
|
|
$opts->add( 'limit', (int)$wgUser->getOption( 'rclimit' ) );
|
2008-06-17 08:24:00 +00:00
|
|
|
$opts->add( 'from', '' );
|
|
|
|
|
|
2009-01-13 13:46:02 +00:00
|
|
|
$opts->add( 'hideminor', $wgUser->getBoolOption( 'hideminor' ) );
|
2009-04-19 21:03:30 +00:00
|
|
|
$opts->add( 'hidebots', true );
|
2008-06-17 08:24:00 +00:00
|
|
|
$opts->add( 'hideanons', false );
|
|
|
|
|
$opts->add( 'hideliu', false );
|
2009-01-13 13:46:02 +00:00
|
|
|
$opts->add( 'hidepatrolled', $wgUser->getBoolOption( 'hidepatrolled' ) );
|
2009-04-19 21:03:30 +00:00
|
|
|
$opts->add( 'hidemyself', false );
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$opts->add( 'namespace', '', FormOptions::INTNULL );
|
|
|
|
|
$opts->add( 'invert', false );
|
|
|
|
|
|
|
|
|
|
$opts->add( 'categories', '' );
|
|
|
|
|
$opts->add( 'categories_any', false );
|
2009-01-28 19:08:18 +00:00
|
|
|
$opts->add( 'tagfilter', '' );
|
2008-06-17 08:24:00 +00:00
|
|
|
return $opts;
|
2008-06-26 19:12:52 +00:00
|
|
|
}
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
2010-02-10 04:13:43 +00:00
|
|
|
* Create a FormOptions object with options as specified by the user
|
2008-06-26 19:12:52 +00:00
|
|
|
*
|
|
|
|
|
* @return FormOptions
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function setup( $parameters ) {
|
2008-07-25 16:46:43 +00:00
|
|
|
global $wgRequest;
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$opts = $this->getDefaultOptions();
|
|
|
|
|
$opts->fetchValuesFromRequest( $wgRequest );
|
|
|
|
|
|
|
|
|
|
// Give precedence to subpage syntax
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $parameters !== null ) {
|
2008-06-17 10:44:12 +00:00
|
|
|
$this->parseParameters( $parameters, $opts );
|
2004-12-12 04:13:19 +00:00
|
|
|
}
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2009-09-14 21:26:04 +00:00
|
|
|
$opts->validateIntBounds( 'limit', 0, 5000 );
|
2008-06-17 08:24:00 +00:00
|
|
|
return $opts;
|
2003-07-02 06:22:03 +00:00
|
|
|
}
|
2004-08-09 05:38:11 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
2010-02-10 04:13:43 +00:00
|
|
|
* Create a FormOptions object specific for feed requests and return it
|
2008-06-26 19:12:52 +00:00
|
|
|
*
|
|
|
|
|
* @return FormOptions
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function feedSetup() {
|
|
|
|
|
global $wgFeedLimit, $wgRequest;
|
|
|
|
|
$opts = $this->getDefaultOptions();
|
2009-12-17 15:42:17 +00:00
|
|
|
# Feed is cached on limit,hideminor,namespace; other params would randomly not work
|
|
|
|
|
$opts->fetchValuesFromRequest( $wgRequest, array( 'limit', 'hideminor', 'namespace' ) );
|
2008-06-17 08:24:00 +00:00
|
|
|
$opts->validateIntBounds( 'limit', 0, $wgFeedLimit );
|
|
|
|
|
return $opts;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-10 04:13:43 +00:00
|
|
|
/**
|
|
|
|
|
* Get the current FormOptions for this request
|
|
|
|
|
*/
|
|
|
|
|
public function getOptions() {
|
|
|
|
|
if ( $this->rcOptions === null ) {
|
|
|
|
|
global $wgRequest;
|
|
|
|
|
$feedFormat = $wgRequest->getVal( 'feed' );
|
|
|
|
|
$this->rcOptions = $feedFormat ? $this->feedSetup() : $this->setup( $this->rcSubpage );
|
|
|
|
|
}
|
|
|
|
|
return $this->rcOptions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Main execution point
|
|
|
|
|
*
|
2010-07-03 21:09:25 +00:00
|
|
|
* @param $subpage String
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
2010-02-10 04:13:43 +00:00
|
|
|
public function execute( $subpage ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
global $wgRequest, $wgOut;
|
2010-02-10 04:13:43 +00:00
|
|
|
$this->rcSubpage = $subpage;
|
2008-06-17 08:24:00 +00:00
|
|
|
$feedFormat = $wgRequest->getVal( 'feed' );
|
|
|
|
|
|
|
|
|
|
# 10 seconds server-side caching max
|
|
|
|
|
$wgOut->setSquidMaxage( 10 );
|
2008-12-20 08:36:14 +00:00
|
|
|
# Check if the client has a cached version
|
2008-06-17 08:24:00 +00:00
|
|
|
$lastmod = $this->checkLastModified( $feedFormat );
|
2008-12-20 08:36:14 +00:00
|
|
|
if( $lastmod === false ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-10 04:13:43 +00:00
|
|
|
$opts = $this->getOptions();
|
2008-06-17 08:24:00 +00:00
|
|
|
$this->setHeaders();
|
2008-06-26 19:12:52 +00:00
|
|
|
$this->outputHeader();
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
// Fetch results, prepare a batch link existence check query
|
|
|
|
|
$conds = $this->buildMainQueryConds( $opts );
|
2008-07-27 18:14:59 +00:00
|
|
|
$rows = $this->doMainQuery( $conds, $opts );
|
|
|
|
|
if( $rows === false ){
|
2008-10-08 21:30:21 +00:00
|
|
|
if( !$this->including() ) {
|
|
|
|
|
$this->doHeader( $opts );
|
|
|
|
|
}
|
2008-06-26 19:12:52 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2008-07-26 15:51:49 +00:00
|
|
|
|
2008-12-20 08:36:14 +00:00
|
|
|
if( !$feedFormat ) {
|
|
|
|
|
$batch = new LinkBatch;
|
|
|
|
|
foreach( $rows as $row ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
$batch->add( NS_USER, $row->rc_user_text );
|
|
|
|
|
$batch->add( NS_USER_TALK, $row->rc_user_text );
|
2009-01-29 01:22:43 +00:00
|
|
|
$batch->add( $row->rc_namespace, $row->rc_title );
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
2008-12-20 08:36:14 +00:00
|
|
|
$batch->execute();
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $feedFormat ) {
|
2010-02-10 04:13:43 +00:00
|
|
|
list( $changesFeed, $formatter ) = $this->getFeedObject( $feedFormat );
|
|
|
|
|
$changesFeed->execute( $formatter, $rows, $lastmod, $opts );
|
2008-06-17 08:24:00 +00:00
|
|
|
} else {
|
|
|
|
|
$this->webOutput( $rows, $opts );
|
|
|
|
|
}
|
2008-07-27 18:14:59 +00:00
|
|
|
|
|
|
|
|
$rows->free();
|
2005-05-04 21:56:14 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Return an array with a ChangesFeed object and ChannelFeed object
|
|
|
|
|
*
|
2010-07-03 21:09:25 +00:00
|
|
|
* @return Array
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
|
|
|
|
public function getFeedObject( $feedFormat ){
|
2010-02-10 04:13:43 +00:00
|
|
|
$changesFeed = new ChangesFeed( $feedFormat, 'rcfeed' );
|
|
|
|
|
$formatter = $changesFeed->getFeedObject(
|
2008-06-26 19:12:52 +00:00
|
|
|
wfMsgForContent( 'recentchanges' ),
|
|
|
|
|
wfMsgForContent( 'recentchanges-feed-description' )
|
|
|
|
|
);
|
2010-02-10 04:13:43 +00:00
|
|
|
return array( $changesFeed, $formatter );
|
2008-06-26 19:12:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Process $par and put options found if $opts
|
|
|
|
|
* Mainly used when including the page
|
|
|
|
|
*
|
|
|
|
|
* @param $par String
|
|
|
|
|
* @param $opts FormOptions
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function parseParameters( $par, FormOptions $opts ) {
|
|
|
|
|
$bits = preg_split( '/\s*,\s*/', trim( $par ) );
|
2008-11-28 23:06:25 +00:00
|
|
|
foreach( $bits as $bit ) {
|
|
|
|
|
if( 'hidebots' === $bit ) $opts['hidebots'] = true;
|
|
|
|
|
if( 'bots' === $bit ) $opts['hidebots'] = false;
|
|
|
|
|
if( 'hideminor' === $bit ) $opts['hideminor'] = true;
|
|
|
|
|
if( 'minor' === $bit ) $opts['hideminor'] = false;
|
|
|
|
|
if( 'hideliu' === $bit ) $opts['hideliu'] = true;
|
|
|
|
|
if( 'hidepatrolled' === $bit ) $opts['hidepatrolled'] = true;
|
|
|
|
|
if( 'hideanons' === $bit ) $opts['hideanons'] = true;
|
|
|
|
|
if( 'hidemyself' === $bit ) $opts['hidemyself'] = true;
|
|
|
|
|
|
|
|
|
|
if( is_numeric( $bit ) ) $opts['limit'] = $bit;
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$m = array();
|
2008-11-28 23:06:25 +00:00
|
|
|
if( preg_match( '/^limit=(\d+)$/', $bit, $m ) ) $opts['limit'] = $m[1];
|
|
|
|
|
if( preg_match( '/^days=(\d+)$/', $bit, $m ) ) $opts['days'] = $m[1];
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
2004-11-18 11:37:14 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* 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 $feedFormat String
|
2010-07-03 21:09:25 +00:00
|
|
|
* @return String or false
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function checkLastModified( $feedFormat ) {
|
|
|
|
|
global $wgUseRCPatrol, $wgOut;
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-05-11 15:32:51 +00:00
|
|
|
$lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, __METHOD__ );
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $feedFormat || !$wgUseRCPatrol ) {
|
2008-12-14 00:13:16 +00:00
|
|
|
if( $lastmod && $wgOut->checkLastModified( $lastmod ) ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
# Client cache fresh and headers sent, nothing more to do.
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-11-18 11:37:14 +00:00
|
|
|
}
|
2008-06-17 08:24:00 +00:00
|
|
|
return $lastmod;
|
2003-12-11 20:16:34 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Return an array of conditions depending of options set in $opts
|
|
|
|
|
*
|
|
|
|
|
* @param $opts FormOptions
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function buildMainQueryConds( FormOptions $opts ) {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
|
|
|
|
|
$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;
|
|
|
|
|
}
|
2008-04-02 10:47:50 +00:00
|
|
|
}
|
2006-04-03 01:32:35 +00:00
|
|
|
|
2008-06-17 08:24:00 +00:00
|
|
|
// Calculate cutoff
|
|
|
|
|
$cutoff_unixtime = time() - ( $opts['days'] * 86400 );
|
|
|
|
|
$cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400);
|
|
|
|
|
$cutoff = $dbr->timestamp( $cutoff_unixtime );
|
2008-04-02 10:47:50 +00:00
|
|
|
|
2008-06-17 08:24:00 +00:00
|
|
|
$fromValid = preg_match('/^[0-9]{14}$/', $opts['from']);
|
|
|
|
|
if( $fromValid && $opts['from'] > wfTimestamp(TS_MW,$cutoff) ) {
|
|
|
|
|
$cutoff = $dbr->timestamp($opts['from']);
|
2006-02-11 12:28:50 +00:00
|
|
|
} else {
|
2008-06-17 08:24:00 +00:00
|
|
|
$opts->reset( 'from' );
|
2006-02-11 12:28:50 +00:00
|
|
|
}
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$conds[] = 'rc_timestamp >= ' . $dbr->addQuotes( $cutoff );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$hidePatrol = $wgUser->useRCPatrol() && $opts['hidepatrolled'];
|
|
|
|
|
$hideLoggedInUsers = $opts['hideliu'] && !$forcebot;
|
|
|
|
|
$hideAnonymousUsers = $opts['hideanons'] && !$forcebot;
|
|
|
|
|
|
2008-11-28 23:06:25 +00:00
|
|
|
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';
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
if( $opts['hidemyself'] ) {
|
|
|
|
|
if( $wgUser->getId() ) {
|
|
|
|
|
$conds[] = 'rc_user != ' . $dbr->addQuotes( $wgUser->getId() );
|
|
|
|
|
} else {
|
|
|
|
|
$conds[] = 'rc_user_text != ' . $dbr->addQuotes( $wgUser->getName() );
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-06-26 19:12:52 +00:00
|
|
|
|
2008-06-17 08:24:00 +00:00
|
|
|
# Namespace filtering
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $opts['namespace'] !== '' ) {
|
|
|
|
|
if( !$opts['invert'] ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
$conds[] = 'rc_namespace = ' . $dbr->addQuotes( $opts['namespace'] );
|
|
|
|
|
} else {
|
|
|
|
|
$conds[] = 'rc_namespace != ' . $dbr->addQuotes( $opts['namespace'] );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $conds;
|
2006-02-11 12:28:50 +00:00
|
|
|
}
|
2006-04-03 01:32:35 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Process the query
|
|
|
|
|
*
|
2010-07-03 21:09:25 +00:00
|
|
|
* @param $conds Array
|
2008-06-26 19:12:52 +00:00
|
|
|
* @param $opts FormOptions
|
|
|
|
|
* @return database result or false (for Recentchangeslinked only)
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function doMainQuery( $conds, $opts ) {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
|
2008-09-16 05:56:43 +00:00
|
|
|
$tables = array( 'recentchanges' );
|
|
|
|
|
$join_conds = array();
|
2009-03-31 13:01:05 +00:00
|
|
|
$query_options = array( 'USE INDEX' => array('recentchanges' => 'rc_timestamp') );
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$uid = $wgUser->getId();
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
$limit = $opts['limit'];
|
|
|
|
|
$namespace = $opts['namespace'];
|
|
|
|
|
$invert = $opts['invert'];
|
|
|
|
|
|
|
|
|
|
// JOIN on watchlist for users
|
2008-06-26 19:12:52 +00:00
|
|
|
if( $uid ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
$tables[] = 'watchlist';
|
2009-01-28 19:08:18 +00:00
|
|
|
$join_conds['watchlist'] = array('LEFT JOIN',
|
|
|
|
|
"wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace");
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
2009-03-29 11:02:16 +00:00
|
|
|
if ($wgUser->isAllowed("rollback")) {
|
|
|
|
|
$tables[] = 'page';
|
2009-03-29 11:14:08 +00:00
|
|
|
$join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
|
2009-03-29 11:02:16 +00:00
|
|
|
}
|
2010-07-23 22:37:52 +00:00
|
|
|
if ( !$this->including() ) {
|
|
|
|
|
// Tag stuff.
|
|
|
|
|
// Doesn't work when transcluding. See bug 23293
|
|
|
|
|
$fields = array();
|
|
|
|
|
// Fields are * in this case, so let the function modify an empty array to keep it happy.
|
|
|
|
|
ChangeTags::modifyDisplayQuery(
|
|
|
|
|
$tables, $fields, $conds, $join_conds, $query_options, $opts['tagfilter']
|
|
|
|
|
);
|
|
|
|
|
}
|
2009-01-28 19:08:18 +00:00
|
|
|
|
2010-01-29 17:27:30 +00:00
|
|
|
if ( !wfRunHooks( 'SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts, &$query_options ) ) )
|
|
|
|
|
return false;
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2010-01-28 08:57:34 +00:00
|
|
|
// Don't use the new_namespace_time timestamp index if:
|
|
|
|
|
// (a) "All namespaces" selected
|
|
|
|
|
// (b) We want all pages NOT in a certain namespaces (inverted)
|
|
|
|
|
// (c) There is a tag to filter on (use tag index instead)
|
|
|
|
|
// (d) UNION + sort/limit is not an option for the DBMS
|
2009-10-17 12:23:23 +00:00
|
|
|
if( is_null($namespace)
|
|
|
|
|
|| $invert
|
2010-01-28 08:57:34 +00:00
|
|
|
|| $opts['tagfilter'] != ''
|
2009-10-17 12:23:23 +00:00
|
|
|
|| !$dbr->unionSupportsOrderAndLimit() )
|
|
|
|
|
{
|
2008-06-17 08:24:00 +00:00
|
|
|
$res = $dbr->select( $tables, '*', $conds, __METHOD__,
|
2009-03-31 13:01:05 +00:00
|
|
|
array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) +
|
|
|
|
|
$query_options,
|
2008-06-17 08:24:00 +00:00
|
|
|
$join_conds );
|
|
|
|
|
// We have a new_namespace_time index! UNION over new=(0,1) and sort result set!
|
|
|
|
|
} else {
|
|
|
|
|
// New pages
|
|
|
|
|
$sqlNew = $dbr->selectSQLText( $tables, '*',
|
|
|
|
|
array( 'rc_new' => 1 ) + $conds,
|
|
|
|
|
__METHOD__,
|
2008-06-26 19:12:52 +00:00
|
|
|
array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit,
|
2009-06-15 14:44:28 +00:00
|
|
|
'USE INDEX' => array('recentchanges' => 'rc_timestamp') ),
|
2008-06-17 08:24:00 +00:00
|
|
|
$join_conds );
|
|
|
|
|
// Old pages
|
|
|
|
|
$sqlOld = $dbr->selectSQLText( $tables, '*',
|
|
|
|
|
array( 'rc_new' => 0 ) + $conds,
|
|
|
|
|
__METHOD__,
|
2008-06-26 19:12:52 +00:00
|
|
|
array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit,
|
2009-06-15 14:44:28 +00:00
|
|
|
'USE INDEX' => array('recentchanges' => 'rc_timestamp') ),
|
2008-06-17 08:24:00 +00:00
|
|
|
$join_conds );
|
|
|
|
|
# Join the two fast queries, and sort the result set
|
2009-05-19 16:58:56 +00:00
|
|
|
$sql = $dbr->unionQueries(array($sqlNew, $sqlOld), false).' ORDER BY rc_timestamp DESC';
|
|
|
|
|
$sql = $dbr->limitResult($sql, $limit, false);
|
2008-06-17 08:24:00 +00:00
|
|
|
$res = $dbr->query( $sql, __METHOD__ );
|
2005-11-15 11:12:21 +00:00
|
|
|
}
|
2005-04-03 08:27:08 +00:00
|
|
|
|
2008-06-17 08:24:00 +00:00
|
|
|
return $res;
|
2004-01-28 15:57:47 +00:00
|
|
|
}
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
2008-09-16 05:56:43 +00:00
|
|
|
* Send output to $wgOut, only called if not used feeds
|
2008-06-26 19:12:52 +00:00
|
|
|
*
|
2010-07-03 21:09:25 +00:00
|
|
|
* @param $rows Array of database rows
|
2008-06-26 19:12:52 +00:00
|
|
|
* @param $opts FormOptions
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function webOutput( $rows, $opts ) {
|
|
|
|
|
global $wgOut, $wgUser, $wgRCShowWatchingUsers, $wgShowUpdatedMarker;
|
|
|
|
|
global $wgAllowCategorizedRecentChanges;
|
|
|
|
|
|
|
|
|
|
$limit = $opts['limit'];
|
|
|
|
|
|
2008-11-28 23:06:25 +00:00
|
|
|
if( !$this->including() ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
// Output options box
|
|
|
|
|
$this->doHeader( $opts );
|
2005-05-28 11:09:22 +00:00
|
|
|
}
|
2005-05-04 21:56:14 +00:00
|
|
|
|
|
|
|
|
// And now for the content
|
2010-02-10 04:13:43 +00:00
|
|
|
$wgOut->setFeedAppendQuery( $this->getFeedQuery() );
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $wgAllowCategorizedRecentChanges ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$this->filterByCategories( $rows, $opts );
|
2006-01-09 14:20:26 +00:00
|
|
|
}
|
2005-09-06 18:43:45 +00:00
|
|
|
|
2007-12-01 09:48:40 +00:00
|
|
|
$showWatcherCount = $wgRCShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' );
|
|
|
|
|
$watcherCache = array();
|
|
|
|
|
|
2008-06-17 08:24:00 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
|
2008-11-28 23:06:25 +00:00
|
|
|
$counter = 1;
|
|
|
|
|
$list = ChangesList::newFromUser( $wgUser );
|
|
|
|
|
|
|
|
|
|
$s = $list->beginRecentChangesList();
|
|
|
|
|
foreach( $rows as $obj ) {
|
2008-12-20 08:36:14 +00:00
|
|
|
if( $limit == 0 ) break;
|
2008-11-28 23:06:25 +00:00
|
|
|
$rc = RecentChange::newFromRow( $obj );
|
|
|
|
|
$rc->counter = $counter++;
|
2008-12-20 08:36:14 +00:00
|
|
|
# Check if the page has been updated since the last visit
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $wgShowUpdatedMarker && !empty($obj->wl_notificationtimestamp) ) {
|
|
|
|
|
$rc->notificationtimestamp = ($obj->rc_timestamp >= $obj->wl_notificationtimestamp);
|
2008-12-20 08:36:14 +00:00
|
|
|
} else {
|
|
|
|
|
$rc->notificationtimestamp = false; // Default
|
2008-11-28 23:06:25 +00:00
|
|
|
}
|
2008-12-20 08:36:14 +00:00
|
|
|
# Check the number of users watching the page
|
2008-11-28 23:06:25 +00:00
|
|
|
$rc->numberofWatchingusers = 0; // Default
|
|
|
|
|
if( $showWatcherCount && $obj->rc_namespace >= 0 ) {
|
|
|
|
|
if( !isset($watcherCache[$obj->rc_namespace][$obj->rc_title]) ) {
|
|
|
|
|
$watcherCache[$obj->rc_namespace][$obj->rc_title] =
|
|
|
|
|
$dbr->selectField( 'watchlist',
|
|
|
|
|
'COUNT(*)',
|
|
|
|
|
array(
|
|
|
|
|
'wl_namespace' => $obj->rc_namespace,
|
|
|
|
|
'wl_title' => $obj->rc_title,
|
|
|
|
|
),
|
|
|
|
|
__METHOD__ . '-watchers' );
|
2004-12-18 03:47:11 +00:00
|
|
|
}
|
2008-11-28 23:06:25 +00:00
|
|
|
$rc->numberofWatchingusers = $watcherCache[$obj->rc_namespace][$obj->rc_title];
|
2004-03-19 05:31:18 +00:00
|
|
|
}
|
2009-02-08 15:55:32 +00:00
|
|
|
$s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ), $counter );
|
2008-11-28 23:06:25 +00:00
|
|
|
--$limit;
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2004-11-25 13:47:17 +00:00
|
|
|
$s .= $list->endRecentChangesList();
|
2004-03-19 05:31:18 +00:00
|
|
|
$wgOut->addHTML( $s );
|
2003-04-14 23:10:40 +00:00
|
|
|
}
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2010-02-10 04:13:43 +00:00
|
|
|
/**
|
|
|
|
|
* Get the query string to append to feed link URLs.
|
|
|
|
|
* This is overridden by RCL to add the target parameter
|
|
|
|
|
*/
|
|
|
|
|
public function getFeedQuery() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Return the text to be displayed above the changes
|
|
|
|
|
*
|
|
|
|
|
* @param $opts FormOptions
|
|
|
|
|
* @return String: XHTML
|
|
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
public function doHeader( $opts ) {
|
2009-08-04 10:59:35 +00:00
|
|
|
global $wgScript, $wgOut;
|
2008-06-26 19:12:52 +00:00
|
|
|
|
|
|
|
|
$this->setTopText( $wgOut, $opts );
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$defaults = $opts->getAllValues();
|
|
|
|
|
$nondefaults = $opts->getChangedValues();
|
2010-03-04 13:19:06 +00:00
|
|
|
$opts->consumeValues( array( 'namespace', 'invert', 'tagfilter',
|
|
|
|
|
'categories', 'categories_any' ) );
|
2008-06-17 08:24:00 +00:00
|
|
|
|
|
|
|
|
$panel = array();
|
2008-06-26 19:12:52 +00:00
|
|
|
$panel[] = $this->optionsPanel( $defaults, $nondefaults );
|
2008-07-02 02:31:05 +00:00
|
|
|
$panel[] = '<hr />';
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
$extraOpts = $this->getExtraOptions( $opts );
|
2008-08-28 07:14:33 +00:00
|
|
|
$extraOptsCount = count( $extraOpts );
|
|
|
|
|
$count = 0;
|
|
|
|
|
$submit = ' ' . Xml::submitbutton( wfMsg( 'allpagessubmit' ) );
|
2008-06-17 08:24:00 +00:00
|
|
|
|
2008-08-28 07:14:33 +00:00
|
|
|
$out = Xml::openElement( 'table', array( 'class' => 'mw-recentchanges-table' ) );
|
2008-11-28 23:06:25 +00:00
|
|
|
foreach( $extraOpts as $optionRow ) {
|
2008-08-28 07:14:33 +00:00
|
|
|
# Add submit button to the last row only
|
|
|
|
|
++$count;
|
|
|
|
|
$addSubmit = $count === $extraOptsCount ? $submit : '';
|
|
|
|
|
|
2008-06-17 08:24:00 +00:00
|
|
|
$out .= Xml::openElement( 'tr' );
|
2008-11-28 23:06:25 +00:00
|
|
|
if( is_array( $optionRow ) ) {
|
2008-08-28 07:14:33 +00:00
|
|
|
$out .= Xml::tags( 'td', array( 'class' => 'mw-label' ), $optionRow[0] );
|
|
|
|
|
$out .= Xml::tags( 'td', array( 'class' => 'mw-input' ), $optionRow[1] . $addSubmit );
|
2008-06-17 08:24:00 +00:00
|
|
|
} else {
|
2008-08-28 07:14:33 +00:00
|
|
|
$out .= Xml::tags( 'td', array( 'class' => 'mw-input', 'colspan' => 2 ), $optionRow . $addSubmit );
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
|
|
|
|
$out .= Xml::closeElement( 'tr' );
|
|
|
|
|
}
|
|
|
|
|
$out .= Xml::closeElement( 'table' );
|
|
|
|
|
|
|
|
|
|
$unconsumed = $opts->getUnconsumedValues();
|
2008-11-28 23:06:25 +00:00
|
|
|
foreach( $unconsumed as $key => $value ) {
|
2008-06-17 08:24:00 +00:00
|
|
|
$out .= Xml::hidden( $key, $value );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$t = $this->getTitle();
|
|
|
|
|
$out .= Xml::hidden( 'title', $t->getPrefixedText() );
|
|
|
|
|
$form = Xml::tags( 'form', array( 'action' => $wgScript ), $out );
|
|
|
|
|
$panel[] = $form;
|
|
|
|
|
$panelString = implode( "\n", $panel );
|
|
|
|
|
|
2008-07-02 02:31:05 +00:00
|
|
|
$wgOut->addHTML(
|
2008-08-27 19:49:09 +00:00
|
|
|
Xml::fieldset( wfMsg( 'recentchanges-legend' ), $panelString, array( 'class' => 'rcoptions' ) )
|
2008-07-02 02:31:05 +00:00
|
|
|
);
|
2008-06-26 19:12:52 +00:00
|
|
|
|
2009-08-04 10:59:35 +00:00
|
|
|
$wgOut->addHTML( ChangesList::flagLegend() );
|
2009-08-02 22:15:55 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
$this->setBottomText( $wgOut, $opts );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get options to be displayed in a form
|
|
|
|
|
*
|
|
|
|
|
* @param $opts FormOptions
|
2010-07-03 21:09:25 +00:00
|
|
|
* @return Array
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
|
|
|
|
function getExtraOptions( $opts ){
|
|
|
|
|
$extraOpts = array();
|
|
|
|
|
$extraOpts['namespace'] = $this->namespaceFilterForm( $opts );
|
|
|
|
|
|
|
|
|
|
global $wgAllowCategorizedRecentChanges;
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $wgAllowCategorizedRecentChanges ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$extraOpts['category'] = $this->categoryFilterForm( $opts );
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-30 23:24:29 +00:00
|
|
|
$tagFilter = ChangeTags::buildTagFilterSelector( $opts['tagfilter'] );
|
|
|
|
|
if ( count($tagFilter) )
|
|
|
|
|
$extraOpts['tagfilter'] = $tagFilter;
|
2009-01-28 19:08:18 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
wfRunHooks( 'SpecialRecentChangesPanel', array( &$extraOpts, $opts ) );
|
|
|
|
|
return $extraOpts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Send the text to be displayed above the options
|
|
|
|
|
*
|
|
|
|
|
* @param $out OutputPage
|
|
|
|
|
* @param $opts FormOptions
|
|
|
|
|
*/
|
2008-08-06 17:35:19 +00:00
|
|
|
function setTopText( OutputPage $out, FormOptions $opts ){
|
2008-06-26 19:12:52 +00:00
|
|
|
$out->addWikiText( wfMsgForContentNoTrans( 'recentchangestext' ) );
|
2008-06-17 08:24:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-06-26 19:12:52 +00:00
|
|
|
* Send the text to be displayed after the options, for use in
|
|
|
|
|
* Recentchangeslinked
|
|
|
|
|
*
|
|
|
|
|
* @param $out OutputPage
|
|
|
|
|
* @param $opts FormOptions
|
|
|
|
|
*/
|
2008-08-06 17:35:19 +00:00
|
|
|
function setBottomText( OutputPage $out, FormOptions $opts ){}
|
2008-06-26 19:12:52 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates the choose namespace selection
|
|
|
|
|
*
|
|
|
|
|
* @param $opts FormOptions
|
2010-07-03 21:09:25 +00:00
|
|
|
* @return String
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
protected function namespaceFilterForm( FormOptions $opts ) {
|
2008-12-14 19:14:21 +00:00
|
|
|
$nsSelect = Xml::namespaceSelector( $opts['namespace'], '' );
|
2008-06-17 08:24:00 +00:00
|
|
|
$nsLabel = Xml::label( wfMsg('namespace'), 'namespace' );
|
|
|
|
|
$invert = Xml::checkLabel( wfMsg('invert'), 'invert', 'nsinvert', $opts['invert'] );
|
|
|
|
|
return array( $nsLabel, "$nsSelect $invert" );
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Create a input to filter changes by categories
|
|
|
|
|
*
|
|
|
|
|
* @param $opts FormOptions
|
2010-07-03 21:09:25 +00:00
|
|
|
* @return Array
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
2008-06-17 08:24:00 +00:00
|
|
|
protected function categoryFilterForm( FormOptions $opts ) {
|
|
|
|
|
list( $label, $input ) = Xml::inputLabelSep( wfMsg('rc_categories'),
|
|
|
|
|
'categories', 'mw-categories', false, $opts['categories'] );
|
|
|
|
|
|
|
|
|
|
$input .= ' ' . Xml::checkLabel( wfMsg('rc_categories_any'),
|
|
|
|
|
'categories_any', 'mw-categories_any', $opts['categories_any'] );
|
|
|
|
|
|
|
|
|
|
return array( $label, $input );
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Filter $rows by categories set in $opts
|
|
|
|
|
*
|
2010-07-03 21:09:25 +00:00
|
|
|
* @param $rows Array of database rows
|
2008-06-26 19:12:52 +00:00
|
|
|
* @param $opts FormOptions
|
|
|
|
|
*/
|
|
|
|
|
function filterByCategories( &$rows, FormOptions $opts ) {
|
2010-03-04 15:42:17 +00:00
|
|
|
$categories = array_map( 'trim', explode( '|' , $opts['categories'] ) );
|
2008-06-26 19:12:52 +00:00
|
|
|
|
2010-03-04 15:42:17 +00:00
|
|
|
if( !count( $categories ) ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
# Filter categories
|
|
|
|
|
$cats = array();
|
2008-11-28 23:06:25 +00:00
|
|
|
foreach( $categories as $cat ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$cat = trim( $cat );
|
2010-03-04 15:42:17 +00:00
|
|
|
if( $cat == '' ) continue;
|
2008-06-26 19:12:52 +00:00
|
|
|
$cats[] = $cat;
|
2006-01-09 14:20:26 +00:00
|
|
|
}
|
2008-06-26 19:12:52 +00:00
|
|
|
|
|
|
|
|
# Filter articles
|
|
|
|
|
$articles = array();
|
|
|
|
|
$a2r = array();
|
2010-03-04 15:42:17 +00:00
|
|
|
$rowsarr = array();
|
2008-11-28 23:06:25 +00:00
|
|
|
foreach( $rows AS $k => $r ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$nt = Title::makeTitle( $r->rc_namespace, $r->rc_title );
|
|
|
|
|
$id = $nt->getArticleID();
|
2008-11-28 23:06:25 +00:00
|
|
|
if( $id == 0 ) continue; # Page might have been deleted...
|
2010-03-04 15:42:17 +00:00
|
|
|
if( !in_array( $id, $articles ) ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$articles[] = $id;
|
|
|
|
|
}
|
2010-03-04 15:42:17 +00:00
|
|
|
if( !isset( $a2r[$id] ) ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$a2r[$id] = array();
|
|
|
|
|
}
|
|
|
|
|
$a2r[$id][] = $k;
|
2010-03-04 15:42:17 +00:00
|
|
|
$rowsarr[$k] = $r;
|
2006-01-09 14:20:26 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
# Shortcut?
|
2010-03-04 15:42:17 +00:00
|
|
|
if( !count( $articles ) || !count( $cats ) )
|
2008-06-26 19:12:52 +00:00
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
# Look up
|
2010-03-04 15:42:17 +00:00
|
|
|
$c = new Categoryfinder;
|
2008-06-26 19:12:52 +00:00
|
|
|
$c->seed( $articles, $cats, $opts['categories_any'] ? "OR" : "AND" ) ;
|
|
|
|
|
$match = $c->run();
|
|
|
|
|
|
|
|
|
|
# Filter
|
|
|
|
|
$newrows = array();
|
2008-11-28 23:06:25 +00:00
|
|
|
foreach( $match AS $id ) {
|
|
|
|
|
foreach( $a2r[$id] AS $rev ) {
|
2008-06-26 19:12:52 +00:00
|
|
|
$k = $rev;
|
2010-03-04 15:42:17 +00:00
|
|
|
$newrows[$k] = $rowsarr[$k];
|
2008-06-26 19:12:52 +00:00
|
|
|
}
|
2004-12-12 04:13:19 +00:00
|
|
|
}
|
2008-06-26 19:12:52 +00:00
|
|
|
$rows = $newrows;
|
2004-12-12 04:13:19 +00:00
|
|
|
}
|
2003-04-14 23:10:40 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Makes change an option link which carries all the other options
|
2010-07-03 21:09:25 +00:00
|
|
|
*
|
|
|
|
|
* @param $title Title
|
|
|
|
|
* @param $override Array: options to override
|
|
|
|
|
* @param $options Array: current options
|
|
|
|
|
* @param $active Boolean: whether to show the link in bold
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
|
|
|
|
function makeOptionsLink( $title, $override, $options, $active = false ) {
|
2008-06-27 11:43:39 +00:00
|
|
|
global $wgUser;
|
2008-06-26 19:12:52 +00:00
|
|
|
$sk = $wgUser->getSkin();
|
2008-11-01 23:20:25 +00:00
|
|
|
$params = $override + $options;
|
2009-04-13 12:39:12 +00:00
|
|
|
if ( $active ) {
|
|
|
|
|
return $sk->link( $this->getTitle(), '<strong>' . htmlspecialchars( $title ) . '</strong>',
|
|
|
|
|
array(), $params, array( 'known' ) );
|
|
|
|
|
} else {
|
|
|
|
|
return $sk->link( $this->getTitle(), htmlspecialchars( $title ), array() , $params, array( 'known' ) );
|
|
|
|
|
}
|
2006-04-05 18:31:58 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
/**
|
|
|
|
|
* Creates the options panel.
|
2010-07-03 21:09:25 +00:00
|
|
|
*
|
|
|
|
|
* @param $defaults Array
|
|
|
|
|
* @param $nondefaults Array
|
2008-06-26 19:12:52 +00:00
|
|
|
*/
|
|
|
|
|
function optionsPanel( $defaults, $nondefaults ) {
|
|
|
|
|
global $wgLang, $wgUser, $wgRCLinkLimits, $wgRCLinkDays;
|
|
|
|
|
|
|
|
|
|
$options = $nondefaults + $defaults;
|
|
|
|
|
|
2008-10-29 15:47:58 +00:00
|
|
|
$note = '';
|
2009-01-25 00:19:01 +00:00
|
|
|
if( !wfEmptyMsg( 'rclegend', wfMsg('rclegend') ) ) {
|
2009-01-25 23:41:30 +00:00
|
|
|
$note .= '<div class="mw-rclegend">' . wfMsgExt( 'rclegend', array('parseinline') ) . "</div>\n";
|
2009-01-25 00:19:01 +00:00
|
|
|
}
|
2008-10-29 15:47:58 +00:00
|
|
|
if( $options['from'] ) {
|
|
|
|
|
$note .= wfMsgExt( 'rcnotefrom', array( 'parseinline' ),
|
2008-10-29 15:35:18 +00:00
|
|
|
$wgLang->formatNum( $options['limit'] ),
|
2009-06-01 21:11:23 +00:00
|
|
|
$wgLang->timeanddate( $options['from'], true ),
|
|
|
|
|
$wgLang->date( $options['from'], true ),
|
|
|
|
|
$wgLang->time( $options['from'], true ) ) . '<br />';
|
2008-10-29 15:47:58 +00:00
|
|
|
}
|
2008-10-29 15:35:18 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
# Sort data for display and make sure it's unique after we've added user data.
|
|
|
|
|
$wgRCLinkLimits[] = $options['limit'];
|
|
|
|
|
$wgRCLinkDays[] = $options['days'];
|
2008-08-11 16:24:51 +00:00
|
|
|
sort( $wgRCLinkLimits );
|
|
|
|
|
sort( $wgRCLinkDays );
|
|
|
|
|
$wgRCLinkLimits = array_unique( $wgRCLinkLimits );
|
|
|
|
|
$wgRCLinkDays = array_unique( $wgRCLinkDays );
|
2008-06-26 19:12:52 +00:00
|
|
|
|
|
|
|
|
// limit links
|
|
|
|
|
foreach( $wgRCLinkLimits as $value ) {
|
|
|
|
|
$cl[] = $this->makeOptionsLink( $wgLang->formatNum( $value ),
|
|
|
|
|
array( 'limit' => $value ), $nondefaults, $value == $options['limit'] ) ;
|
|
|
|
|
}
|
2009-02-09 17:48:41 +00:00
|
|
|
$cl = $wgLang->pipeList( $cl );
|
2005-05-03 18:30:46 +00:00
|
|
|
|
2008-06-26 19:12:52 +00:00
|
|
|
// day links, reset 'from' to none
|
|
|
|
|
foreach( $wgRCLinkDays as $value ) {
|
|
|
|
|
$dl[] = $this->makeOptionsLink( $wgLang->formatNum( $value ),
|
|
|
|
|
array( 'days' => $value, 'from' => '' ), $nondefaults, $value == $options['days'] ) ;
|
|
|
|
|
}
|
2009-02-09 17:48:41 +00:00
|
|
|
$dl = $wgLang->pipeList( $dl );
|
2008-06-26 19:12:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// show/hide links
|
2008-08-11 16:24:51 +00:00
|
|
|
$showhide = array( wfMsg( 'show' ), wfMsg( 'hide' ) );
|
2008-06-26 19:12:52 +00:00
|
|
|
$minorLink = $this->makeOptionsLink( $showhide[1-$options['hideminor']],
|
|
|
|
|
array( 'hideminor' => 1-$options['hideminor'] ), $nondefaults);
|
|
|
|
|
$botLink = $this->makeOptionsLink( $showhide[1-$options['hidebots']],
|
|
|
|
|
array( 'hidebots' => 1-$options['hidebots'] ), $nondefaults);
|
|
|
|
|
$anonsLink = $this->makeOptionsLink( $showhide[ 1 - $options['hideanons'] ],
|
|
|
|
|
array( 'hideanons' => 1 - $options['hideanons'] ), $nondefaults );
|
|
|
|
|
$liuLink = $this->makeOptionsLink( $showhide[1-$options['hideliu']],
|
|
|
|
|
array( 'hideliu' => 1-$options['hideliu'] ), $nondefaults);
|
|
|
|
|
$patrLink = $this->makeOptionsLink( $showhide[1-$options['hidepatrolled']],
|
|
|
|
|
array( 'hidepatrolled' => 1-$options['hidepatrolled'] ), $nondefaults);
|
|
|
|
|
$myselfLink = $this->makeOptionsLink( $showhide[1-$options['hidemyself']],
|
|
|
|
|
array( 'hidemyself' => 1-$options['hidemyself'] ), $nondefaults);
|
|
|
|
|
|
|
|
|
|
$links[] = wfMsgHtml( 'rcshowhideminor', $minorLink );
|
|
|
|
|
$links[] = wfMsgHtml( 'rcshowhidebots', $botLink );
|
|
|
|
|
$links[] = wfMsgHtml( 'rcshowhideanons', $anonsLink );
|
|
|
|
|
$links[] = wfMsgHtml( 'rcshowhideliu', $liuLink );
|
|
|
|
|
if( $wgUser->useRCPatrol() )
|
|
|
|
|
$links[] = wfMsgHtml( 'rcshowhidepatr', $patrLink );
|
|
|
|
|
$links[] = wfMsgHtml( 'rcshowhidemine', $myselfLink );
|
2009-02-09 17:48:41 +00:00
|
|
|
$hl = $wgLang->pipeList( $links );
|
2008-06-26 19:12:52 +00:00
|
|
|
|
|
|
|
|
// show from this onward link
|
|
|
|
|
$now = $wgLang->timeanddate( wfTimestampNow(), true );
|
2008-08-11 16:24:51 +00:00
|
|
|
$tl = $this->makeOptionsLink( $now, array( 'from' => wfTimestampNow() ), $nondefaults );
|
2008-06-26 19:12:52 +00:00
|
|
|
|
2008-08-11 16:24:51 +00:00
|
|
|
$rclinks = wfMsgExt( 'rclinks', array( 'parseinline', 'replaceafter' ),
|
2008-06-26 19:12:52 +00:00
|
|
|
$cl, $dl, $hl );
|
2008-08-11 16:24:51 +00:00
|
|
|
$rclistfrom = wfMsgExt( 'rclistfrom', array( 'parseinline', 'replaceafter' ), $tl );
|
2008-10-29 15:47:58 +00:00
|
|
|
return "{$note}$rclinks<br />$rclistfrom";
|
2005-05-03 18:30:46 +00:00
|
|
|
}
|
2008-06-26 19:12:52 +00:00
|
|
|
}
|