Go to the documentation of this file.
32 parent::__construct(
$name, $restriction );
43 $feedFormat = $this->
getRequest()->getVal(
'feed' );
44 if ( !$this->
including() && $feedFormat ) {
46 $query[
'feedformat'] = $feedFormat ===
'atom' ?
'atom' :
'rss';
56 if ( $lastmod ===
false ) {
69 $opts = parent::getDefaultOptions();
72 $opts->add(
'days',
$user->getIntOption(
'rcdays' ) );
73 $opts->add(
'limit',
$user->getIntOption(
'rclimit' ) );
74 $opts->add(
'from',
'' );
76 $opts->add(
'hideminor',
$user->getBoolOption(
'hideminor' ) );
77 $opts->add(
'hidebots',
true );
78 $opts->add(
'hideanons',
false );
79 $opts->add(
'hideliu',
false );
80 $opts->add(
'hidepatrolled',
$user->getBoolOption(
'hidepatrolled' ) );
81 $opts->add(
'hidemyself',
false );
83 $opts->add(
'categories',
'' );
84 $opts->add(
'categories_any',
false );
85 $opts->add(
'tagfilter',
'' );
96 if ( $this->customFilters ===
null ) {
97 $this->customFilters = parent::getCustomFilters();
98 wfRunHooks(
'SpecialRecentChangesFilters',
array( $this, &$this->customFilters ),
'1.23' );
111 $bits = preg_split(
'/\s*,\s*/', trim( $par ) );
112 foreach ( $bits
as $bit ) {
113 if (
'hidebots' === $bit ) {
114 $opts[
'hidebots'] =
true;
116 if (
'bots' === $bit ) {
117 $opts[
'hidebots'] =
false;
119 if (
'hideminor' === $bit ) {
120 $opts[
'hideminor'] =
true;
122 if (
'minor' === $bit ) {
123 $opts[
'hideminor'] =
false;
125 if (
'hideliu' === $bit ) {
126 $opts[
'hideliu'] =
true;
128 if (
'hidepatrolled' === $bit ) {
129 $opts[
'hidepatrolled'] =
true;
131 if (
'hideanons' === $bit ) {
132 $opts[
'hideanons'] =
true;
134 if (
'hidemyself' === $bit ) {
135 $opts[
'hidemyself'] =
true;
138 if ( is_numeric( $bit ) ) {
139 $opts[
'limit'] = $bit;
143 if ( preg_match(
'/^limit=(\d+)$/', $bit, $m ) ) {
144 $opts[
'limit'] = $m[1];
146 if ( preg_match(
'/^days=(\d+)$/', $bit, $m ) ) {
147 $opts[
'days'] = $m[1];
149 if ( preg_match(
'/^namespace=(\d+)$/', $bit, $m ) ) {
150 $opts[
'namespace'] = $m[1];
157 parent::validateOptions( $opts );
168 $conds = parent::buildMainQueryConds( $opts );
171 $cutoff_unixtime = time() - ( $opts[
'days'] * 86400 );
172 $cutoff_unixtime = $cutoff_unixtime - ( $cutoff_unixtime % 86400 );
173 $cutoff =
$dbr->timestamp( $cutoff_unixtime );
175 $fromValid = preg_match(
'/^[0-9]{14}$/', $opts[
'from'] );
177 $cutoff =
$dbr->timestamp( $opts[
'from'] );
179 $opts->
reset(
'from' );
182 $conds[] =
'rc_timestamp >= ' .
$dbr->addQuotes( $cutoff );
195 global $wgAllowCategorizedRecentChanges;
202 $query_options =
array();
203 $join_conds =
array();
206 if (
$user->getId() &&
$user->isAllowed(
'viewmywatchlist' ) ) {
208 $fields[] =
'wl_user';
209 $fields[] =
'wl_notificationtimestamp';
210 $join_conds[
'watchlist'] =
array(
'LEFT JOIN',
array(
211 'wl_user' =>
$user->getId(),
213 'wl_namespace=rc_namespace'
217 if (
$user->isAllowed(
'rollback' ) ) {
219 $fields[] =
'page_latest';
220 $join_conds[
'page'] =
array(
'LEFT JOIN',
'rc_cur_id=page_id' );
232 if ( !
wfRunHooks(
'SpecialRecentChangesQuery',
233 array( &$conds, &
$tables, &$join_conds, $opts, &$query_options, &$fields ),
241 $rows =
$dbr->select(
246 array(
'ORDER BY' =>
'rc_timestamp DESC',
'LIMIT' => $opts[
'limit'] ) + $query_options,
251 if ( $wgAllowCategorizedRecentChanges ) {
273 $query[
'action'] =
'feedrecentchanges';
274 if (
$query[
'limit'] > $wgFeedLimit ) {
275 $query[
'limit'] = $wgFeedLimit;
288 global $wgRCShowWatchingUsers, $wgShowUpdatedMarker;
292 $showWatcherCount = $wgRCShowWatchingUsers
293 && $this->
getUser()->getOption(
'shownumberswatching' );
294 $watcherCache =
array();
300 $list->initChangesListRows( $rows );
302 $rclistOutput = $list->beginRecentChangesList();
303 foreach ( $rows
as $obj ) {
308 $rc->counter = $counter++;
309 # Check if the page has been updated since the last visit
310 if ( $wgShowUpdatedMarker && !empty( $obj->wl_notificationtimestamp ) ) {
311 $rc->notificationtimestamp = ( $obj->rc_timestamp >= $obj->wl_notificationtimestamp );
313 $rc->notificationtimestamp =
false;
315 # Check the number of users watching the page
316 $rc->numberofWatchingusers = 0;
317 if ( $showWatcherCount && $obj->rc_namespace >= 0 ) {
318 if ( !isset( $watcherCache[$obj->rc_namespace][$obj->rc_title] ) ) {
319 $watcherCache[$obj->rc_namespace][$obj->rc_title] =
324 'wl_namespace' => $obj->rc_namespace,
325 'wl_title' => $obj->rc_title,
327 __METHOD__ .
'-watchers'
330 $rc->numberofWatchingusers = $watcherCache[$obj->rc_namespace][$obj->rc_title];
333 $changeLine = $list->recentChangesLine( $rc, !empty( $obj->wl_user ), $counter );
334 if ( $changeLine !==
false ) {
335 $rclistOutput .= $changeLine;
339 $rclistOutput .= $list->endRecentChangesList();
341 if ( $rows->numRows() === 0 ) {
343 '<div class="mw-changeslist-empty">' .
344 $this->
msg(
'recentchanges-noresult' )->parse() .
348 $this->
getOutput()->addHTML( $rclistOutput );
363 $defaults = $opts->getAllValues();
364 $nondefaults = $opts->getChangedValues();
368 $panel[] = $this->
optionsPanel( $defaults, $nondefaults );
372 $extraOptsCount = count( $extraOpts );
374 $submit =
' ' . Xml::submitbutton( $this->
msg(
'allpagessubmit' )->
text() );
377 foreach ( $extraOpts
as $name => $optionRow ) {
378 # Add submit button to the last row only
380 $addSubmit = (
$count === $extraOptsCount ) ? $submit :
'';
383 if ( is_array( $optionRow ) ) {
386 array(
'class' =>
'mw-label mw-' .
$name .
'-label' ),
391 array(
'class' =>
'mw-input' ),
392 $optionRow[1] . $addSubmit
397 array(
'class' =>
'mw-input',
'colspan' => 2 ),
398 $optionRow . $addSubmit
405 $unconsumed = $opts->getUnconsumedValues();
406 foreach ( $unconsumed
as $key =>
$value ) {
414 $panelString = implode(
"\n", $panel );
418 $this->
msg(
'recentchanges-legend' )->
text(),
420 array(
'class' =>
'rcoptions' )
435 $message = $this->
msg(
'recentchangestext' )->inContentLanguage();
436 if ( !$message->isDisabled() ) {
440 "\n" . $message->plain() .
"\n"
455 $opts->consumeValues(
array(
456 'namespace',
'invert',
'associated',
'tagfilter',
'categories',
'categories_any'
459 $extraOpts =
array();
462 global $wgAllowCategorizedRecentChanges;
463 if ( $wgAllowCategorizedRecentChanges ) {
468 if ( count( $tagFilter ) ) {
469 $extraOpts[
'tagfilter'] = $tagFilter;
473 if ( $this->
getName() ===
'Recentchanges' ) {
474 wfRunHooks(
'SpecialRecentChangesPanel',
array( &$extraOpts, $opts ) );
484 parent::addModules();
486 $out->addModules(
'mediawiki.special.recentchanges' );
498 $lastmod =
$dbr->selectField(
'recentchanges',
'MAX(rc_timestamp)',
false, __METHOD__ );
511 array(
'selected' => $opts[
'namespace'],
'all' =>
'' ),
512 array(
'name' =>
'namespace',
'id' =>
'namespace' )
516 $this->
msg(
'invert' )->
text(),
'invert',
'nsinvert',
518 array(
'title' => $this->
msg(
'tooltip-invert' )->
text() )
521 $this->
msg(
'namespace_association' )->
text(),
'associated',
'nsassociated',
523 array(
'title' => $this->
msg(
'tooltip-namespace_association' )->
text() )
526 return array( $nsLabel,
"$nsSelect $invert $associated" );
537 'categories',
'mw-categories',
false, $opts[
'categories'] );
540 'categories_any',
'mw-categories_any', $opts[
'categories_any'] );
542 return array( $label, $input );
552 $categories = array_map(
'trim', explode(
'|', $opts[
'categories'] ) );
554 if ( !count( $categories ) ) {
560 foreach ( $categories
as $cat ) {
572 foreach ( $rows
as $k => $r ) {
574 $id = $nt->getArticleID();
576 continue; #
Page might have been deleted...
578 if ( !in_array( $id, $articles ) ) {
581 if ( !isset( $a2r[$id] ) ) {
589 if ( !count( $articles ) || !count( $cats ) ) {
595 $c->
seed( $articles, $cats, $opts[
'categories_any'] ?
'OR' :
'AND' );
600 foreach ( $match
as $id ) {
601 foreach ( $a2r[$id]
as $rev ) {
603 $newrows[$k] = $rowsarr[$k];
630 $text = htmlspecialchars(
$title );
632 $text =
'<strong>' . $text .
'</strong>';
646 global $wgRCLinkLimits, $wgRCLinkDays;
648 $options = $nondefaults + $defaults;
651 $msg = $this->
msg(
'rclegend' );
652 if ( !$msg->isDisabled() ) {
653 $note .=
'<div class="mw-rclegend">' . $msg->parse() .
"</div>\n";
659 $note .= $this->
msg(
'rcnotefrom' )->numParams(
$options[
'limit'] )->params(
662 $lang->userTime(
$options[
'from'],
$user ) )->parse() .
'<br />';
665 # Sort data for display and make sure it's unique after we've added user data.
666 $linkLimits = $wgRCLinkLimits;
669 $linkLimits = array_unique( $linkLimits );
671 $linkDays = $wgRCLinkDays;
674 $linkDays = array_unique( $linkDays );
682 $cl = $lang->pipeList( $cl );
690 $dl = $lang->pipeList( $dl );
694 'hideminor' =>
'rcshowhideminor',
695 'hidebots' =>
'rcshowhidebots',
696 'hideanons' =>
'rcshowhideanons',
697 'hideliu' =>
'rcshowhideliu',
698 'hidepatrolled' =>
'rcshowhidepatr',
699 'hidemyself' =>
'rcshowhidemine'
702 $showhide =
array(
'show',
'hide' );
705 $filters[$key] =
$params[
'msg'];
708 if ( !
$user->useRCPatrol() ) {
709 unset( $filters[
'hidepatrolled'] );
713 foreach ( $filters
as $key => $msg ) {
718 $linkMessage = $this->
msg( $msg .
'-' . $showhide[1 -
$options[$key]] );
721 if ( !$linkMessage->exists() ) {
722 $linkMessage = $this->
msg( $showhide[1 -
$options[$key]] );
727 $links[] = $this->
msg( $msg )->rawParams(
$link )->escaped();
735 $rclinks = $this->
msg(
'rclinks' )->rawParams( $cl, $dl, $lang->pipeList( $links ) )
738 $this->
msg(
'rclistfrom' )->rawParams( $now, $timenow, $datenow )->parse(),
743 return "{$note}$rclinks<br />$rclistfrom";
static checkLabel( $label, $name, $id, $checked=false, $attribs=array())
Convenience function to build an HTML checkbox with a label.
getPageTitle( $subpage=false)
Get a self-referential title object.
static & makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Abstract class for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
parseParameters( $par, FormOptions $opts)
Process $par and put options found in $opts.
static newFromContext(IContextSource $context)
Fetch an appropriate changes list class for the specified context Some users might want to use an enh...
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
static tags( $element, $attribs=null, $contents)
Same as Xml::element(), but does not escape contents.
namespace and then decline to actually register it RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist & $tables
getOutput()
Get the OutputPage being used for this instance.
optionsPanel( $defaults, $nondefaults)
Creates the options panel.
filterByCategories(&$rows, FormOptions $opts)
Filter $rows by categories set in $opts.
namespaceFilterForm(FormOptions $opts)
Creates the choose namespace selection.
validateOptions(FormOptions $opts)
Validate a FormOptions object generated by getDefaultOptions() with values already populated.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
usually copyright or history_copyright This message must be in HTML not wikitext $subpages will be ignored and the rest of subPageSubtitle() will run. 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink' whether MediaWiki currently thinks this is a CSS JS page Hooks may change this value to override the return value of Title::isCssOrJsPage(). 'TitleIsAlwaysKnown' whether MediaWiki currently thinks this page is known isMovable() always returns false. $title whether MediaWiki currently thinks this page is movable Hooks may change this value to override the return value of Title::isMovable(). 'TitleIsWikitextPage' whether MediaWiki currently thinks this is a wikitext page Hooks may change this value to override the return value of Title::isWikitextPage() 'TitleMove' use UploadVerification and UploadVerifyFile instead $form
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
__construct( $name='Recentchanges', $restriction='')
Special page which uses a ChangesList to show query results.
outputChangesList( $rows, $opts)
Build and output the actual changes list.
The "Categoryfinder" class takes a list of articles, creates an internal representation of all their ...
seed( $article_ids, $categories, $mode='AND')
Initializes the instance.
getCustomFilters()
Get custom show/hide filters.
static hidden( $name, $value, $attribs=array())
Convenience function to produce an input element with type=hidden.
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
getLanguage()
Shortcut to get user's language.
isIncludable()
Whether it's allowed to transclude the special page via {{Special:Foo/params}}.
getName()
Get the name of this Special Page.
set to $title object and return false for a match for latest after cache objects are set use the ContentHandler facility to handle CSS and JavaScript for highlighting & $link
static openElement( $element, $attribs=null)
This opens an XML element.
static linkKnown( $target, $html=null, $customAttribs=array(), $query=array(), $options=array( 'known', 'noclasses'))
Identical to link(), except $options defaults to 'known'.
static makeLegend(IContextSource $context)
Return the legend displayed within the fieldset.
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
addModules()
Add page-specific modules.
addFeedLinks( $params)
Adds RSS/atom links.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
getFeedQuery()
Get URL query parameters for action=feedrecentchanges API feed of current recent changes view.
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
getUser()
Shortcut to get the User executing this instance.
when a variable name is used in a it is silently declared as a new masking the global
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
execute( $subpage)
Main execution point.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
getContext()
Gets the context this SpecialPage is executed in.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
presenting them properly to the user as errors is done by the caller $title
Allows to change the fields on the form that will be generated $name
buildMainQueryConds(FormOptions $opts)
Return an array of conditions depending of options set in $opts.
msg()
Wrapper around wfMessage that sets the current context.
static inputLabelSep( $label, $name, $id, $size=false, $value=false, $attribs=array())
Same as Xml::inputLabel() but return input and label in an array.
getDefaultOptions()
Get a FormOptions object containing the default options.
getRequest()
Get the WebRequest being used for this instance.
A special page that lists last changes made to the wiki.
categoryFilterForm(FormOptions $opts)
Create a input to filter changes by categories.
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
setTopText(FormOptions $opts)
Send the text to be displayed above the options.
doHeader( $opts, $numRows)
Set the text to be displayed above the changes.
static selectFields()
Return the list of recentchanges fields that should be selected to create a new recentchanges object.
static closeElement( $element)
Shortcut to close an XML element.
getExtraOptions( $opts)
Get options to be displayed in a form.
getDB()
Return a DatabaseBase object for reading.
outputFeedLinks()
Output feed links.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
static namespaceSelector(array $params=array(), array $selectAttribs=array())
Build a drop-down box for selecting a namespace.
static rawElement( $element, $attribs=array(), $contents='')
Returns an HTML element in a string.
doMainQuery( $conds, $opts)
Process the query.
static label( $label, $id, $attribs=array())
Convenience function to build an HTML form label.
return true to allow those checks to and false if checking is done use this to change the tables headers temp or archived zone change it to an object instance and return false override the list derivative used the name of the old file when set the default code will be skipped add a value to it if you want to add a cookie that have to vary cache options can modify $query
setBottomText(FormOptions $opts)
Send the text to be displayed after the options.
getOptions()
Get the current FormOptions for this request.
including( $x=null)
Whether the special page is being evaluated via transclusion.
checkLastModified()
Get last modified date, for client caching Don't use this if we are using the patrol feature,...
static fieldset( $legend=false, $content=false, $attribs=array())
Shortcut for creating fieldsets.
makeOptionsLink( $title, $override, $options, $active=false)
Makes change an option link which carries all the other options.