23
23
$opts->add( 'limit', (int)$wgUser->getOption( 'rclimit' ) );
24
24
$opts->add( 'from', '' );
26
$opts->add( 'hideminor', (bool)$wgUser->getOption( 'hideminor' ) );
26
$opts->add( 'hideminor', $wgUser->getBoolOption( 'hideminor' ) );
27
27
$opts->add( 'hidebots', true );
28
28
$opts->add( 'hideanons', false );
29
29
$opts->add( 'hideliu', false );
30
$opts->add( 'hidepatrolled', false );
30
$opts->add( 'hidepatrolled', $wgUser->getBoolOption( 'hidepatrolled' ) );
31
31
$opts->add( 'hidemyself', false );
33
33
$opts->add( 'namespace', '', FormOptions::INTNULL );
54
55
$this->parseParameters( $parameters, $opts );
57
$opts->validateIntBounds( 'limit', 0, 5000 );
58
$opts->validateIntBounds( 'limit', 0, 500 );
66
67
public function feedSetup() {
67
68
global $wgFeedLimit, $wgRequest;
68
69
$opts = $this->getDefaultOptions();
69
$opts->fetchValuesFromRequest( $wgRequest, array( 'days', 'limit', 'hideminor' ) );
70
# Feed is cached on limit,hideminor; other params would randomly not work
71
$opts->fetchValuesFromRequest( $wgRequest, array( 'limit', 'hideminor' ) );
70
72
$opts->validateIntBounds( 'limit', 0, $wgFeedLimit );
108
110
foreach( $rows as $row ) {
109
111
$batch->add( NS_USER, $row->rc_user_text );
110
112
$batch->add( NS_USER_TALK, $row->rc_user_text );
113
$batch->add( $row->rc_namespace, $row->rc_title );
112
115
$batch->execute();
117
$target = isset($opts['target']) ? $opts['target'] : ''; // RCL has targets
115
118
if( $feedFormat ) {
116
119
list( $feed, $feedObj ) = $this->getFeedObject( $feedFormat );
117
$feed->execute( $feedObj, $rows, $opts['limit'], $opts['hideminor'], $lastmod );
120
$feed->execute( $feedObj, $rows, $opts['limit'], $opts['hideminor'], $lastmod, $target );
119
122
$this->webOutput( $rows, $opts );
274
278
$namespace = $opts['namespace'];
275
279
$invert = $opts['invert'];
281
$join_conds = array();
277
283
// JOIN on watchlist for users
279
285
$tables[] = 'watchlist';
280
$join_conds = array( 'watchlist' => array('LEFT JOIN',
281
"wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace") );
286
$join_conds['watchlist'] = array('LEFT JOIN',
287
"wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace");
289
if ($wgUser->isAllowed("rollback")) {
291
$join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
295
// Fields are * in this case, so let the function modify an empty array to keep it happy.
296
ChangeTags::modifyDisplayQuery( $tables,
284
304
wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) );
286
306
// Is there either one namespace selected or excluded?
307
// Tag filtering also has a better index.
287
308
// Also, if this is "all" or main namespace, just use timestamp index.
288
if( is_null($namespace) || $invert || $namespace == NS_MAIN ) {
309
if( is_null($namespace) || $invert || $namespace == NS_MAIN || $opts['tagfilter'] ) {
289
310
$res = $dbr->select( $tables, '*', $conds, __METHOD__,
290
array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit,
291
'USE INDEX' => array('recentchanges' => 'rc_timestamp') ),
311
array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) +
293
314
// We have a new_namespace_time index! UNION over new=(0,1) and sort result set!
373
394
$rc->numberofWatchingusers = $watcherCache[$obj->rc_namespace][$obj->rc_title];
375
$s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ) );
396
$s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ), $counter );
378
399
$s .= $list->endRecentChangesList();
453
474
$extraOpts['category'] = $this->categoryFilterForm( $opts );
477
$tagFilter = ChangeTags::buildTagFilterSelector( $opts['tagfilter'] );
478
if ( count($tagFilter) )
479
$extraOpts['tagfilter'] = $tagFilter;
456
481
wfRunHooks( 'SpecialRecentChangesPanel', array( &$extraOpts, $opts ) );
457
482
return $extraOpts;
587
612
$options = $nondefaults + $defaults;
615
if( !wfEmptyMsg( 'rclegend', wfMsg('rclegend') ) ) {
616
$note .= '<div class="mw-rclegend">' . wfMsgExt( 'rclegend', array('parseinline') ) . "</div>\n";
590
618
if( $options['from'] ) {
591
619
$note .= wfMsgExt( 'rcnotefrom', array( 'parseinline' ),
592
620
$wgLang->formatNum( $options['limit'] ),
593
621
$wgLang->timeanddate( $options['from'], true ) ) . '<br />';
595
if( !wfEmptyMsg( 'rclegend', wfMsg('rclegend') ) ) {
596
$note .= wfMsgExt( 'rclegend', array('parseinline') ) . '<br />';
599
624
# Sort data for display and make sure it's unique after we've added user data.
600
625
$wgRCLinkLimits[] = $options['limit'];
609
634
$cl[] = $this->makeOptionsLink( $wgLang->formatNum( $value ),
610
635
array( 'limit' => $value ), $nondefaults, $value == $options['limit'] ) ;
612
$cl = implode( ' | ', $cl );
637
$cl = $wgLang->pipeList( $cl );
614
639
// day links, reset 'from' to none
615
640
foreach( $wgRCLinkDays as $value ) {
616
641
$dl[] = $this->makeOptionsLink( $wgLang->formatNum( $value ),
617
642
array( 'days' => $value, 'from' => '' ), $nondefaults, $value == $options['days'] ) ;
619
$dl = implode( ' | ', $dl );
644
$dl = $wgLang->pipeList( $dl );
622
647
// show/hide links
641
666
if( $wgUser->useRCPatrol() )
642
667
$links[] = wfMsgHtml( 'rcshowhidepatr', $patrLink );
643
668
$links[] = wfMsgHtml( 'rcshowhidemine', $myselfLink );
644
$hl = implode( ' | ', $links );
669
$hl = $wgLang->pipeList( $links );
646
671
// show from this onward link
647
672
$now = $wgLang->timeanddate( wfTimestampNow(), true );