MediaWiki  1.23.8
ChangesListSpecialPage.php
Go to the documentation of this file.
1 <?php
30 abstract class ChangesListSpecialPage extends SpecialPage {
32  protected $rcSubpage;
33 
35  protected $rcOptions;
36 
38  protected $customFilters;
39 
45  public function execute( $subpage ) {
46  $this->rcSubpage = $subpage;
47 
48  $this->setHeaders();
49  $this->outputHeader();
50  $this->addModules();
51 
52  $rows = $this->getRows();
53  $opts = $this->getOptions();
54  if ( $rows === false ) {
55  if ( !$this->including() ) {
56  $this->doHeader( $opts, 0 );
57  }
58 
59  return;
60  }
61 
62  $batch = new LinkBatch;
63  foreach ( $rows as $row ) {
64  $batch->add( NS_USER, $row->rc_user_text );
65  $batch->add( NS_USER_TALK, $row->rc_user_text );
66  $batch->add( $row->rc_namespace, $row->rc_title );
67  }
68  $batch->execute();
69 
70  $this->webOutput( $rows, $opts );
71 
72  $rows->free();
73  }
74 
80  public function getRows() {
81  $opts = $this->getOptions();
82  $conds = $this->buildMainQueryConds( $opts );
83 
84  return $this->doMainQuery( $conds, $opts );
85  }
86 
92  public function getOptions() {
93  if ( $this->rcOptions === null ) {
94  $this->rcOptions = $this->setup( $this->rcSubpage );
95  }
96 
97  return $this->rcOptions;
98  }
99 
107  public function setup( $parameters ) {
108  $opts = $this->getDefaultOptions();
109  foreach ( $this->getCustomFilters() as $key => $params ) {
110  $opts->add( $key, $params['default'] );
111  }
112 
113  $opts = $this->fetchOptionsFromRequest( $opts );
114 
115  // Give precedence to subpage syntax
116  if ( $parameters !== null ) {
117  $this->parseParameters( $parameters, $opts );
118  }
119 
120  $this->validateOptions( $opts );
121 
122  return $opts;
123  }
124 
131  public function getDefaultOptions() {
132  $opts = new FormOptions();
133 
134  $opts->add( 'hideminor', false );
135  $opts->add( 'hidebots', false );
136  $opts->add( 'hideanons', false );
137  $opts->add( 'hideliu', false );
138  $opts->add( 'hidepatrolled', false );
139  $opts->add( 'hidemyself', false );
140 
141  $opts->add( 'namespace', '', FormOptions::INTNULL );
142  $opts->add( 'invert', false );
143  $opts->add( 'associated', false );
144 
145  return $opts;
146  }
147 
153  protected function getCustomFilters() {
154  if ( $this->customFilters === null ) {
155  $this->customFilters = array();
156  wfRunHooks( 'ChangesListSpecialPageFilters', array( $this, &$this->customFilters ) );
157  }
158 
159  return $this->customFilters;
160  }
161 
170  protected function fetchOptionsFromRequest( $opts ) {
171  $opts->fetchValuesFromRequest( $this->getRequest() );
172 
173  return $opts;
174  }
175 
182  public function parseParameters( $par, FormOptions $opts ) {
183  // nothing by default
184  }
185 
191  public function validateOptions( FormOptions $opts ) {
192  // nothing by default
193  }
194 
201  public function buildMainQueryConds( FormOptions $opts ) {
202  $dbr = $this->getDB();
203  $user = $this->getUser();
204  $conds = array();
205 
206  // It makes no sense to hide both anons and logged-in users. When this occurs, try a guess on
207  // what the user meant and either show only bots or force anons to be shown.
208  $botsonly = false;
209  $hideanons = $opts['hideanons'];
210  if ( $opts['hideanons'] && $opts['hideliu'] ) {
211  if ( $opts['hidebots'] ) {
212  $hideanons = false;
213  } else {
214  $botsonly = true;
215  }
216  }
217 
218  // Toggles
219  if ( $opts['hideminor'] ) {
220  $conds['rc_minor'] = 0;
221  }
222  if ( $opts['hidebots'] ) {
223  $conds['rc_bot'] = 0;
224  }
225  if ( $user->useRCPatrol() && $opts['hidepatrolled'] ) {
226  $conds['rc_patrolled'] = 0;
227  }
228  if ( $botsonly ) {
229  $conds['rc_bot'] = 1;
230  } else {
231  if ( $opts['hideliu'] ) {
232  $conds[] = 'rc_user = 0';
233  }
234  if ( $hideanons ) {
235  $conds[] = 'rc_user != 0';
236  }
237  }
238  if ( $opts['hidemyself'] ) {
239  if ( $user->getId() ) {
240  $conds[] = 'rc_user != ' . $dbr->addQuotes( $user->getId() );
241  } else {
242  $conds[] = 'rc_user_text != ' . $dbr->addQuotes( $user->getName() );
243  }
244  }
245 
246  // Namespace filtering
247  if ( $opts['namespace'] !== '' ) {
248  $selectedNS = $dbr->addQuotes( $opts['namespace'] );
249  $operator = $opts['invert'] ? '!=' : '=';
250  $boolean = $opts['invert'] ? 'AND' : 'OR';
251 
252  // Namespace association (bug 2429)
253  if ( !$opts['associated'] ) {
254  $condition = "rc_namespace $operator $selectedNS";
255  } else {
256  // Also add the associated namespace
257  $associatedNS = $dbr->addQuotes(
258  MWNamespace::getAssociated( $opts['namespace'] )
259  );
260  $condition = "(rc_namespace $operator $selectedNS "
261  . $boolean
262  . " rc_namespace $operator $associatedNS)";
263  }
264 
265  $conds[] = $condition;
266  }
267 
268  return $conds;
269  }
270 
278  public function doMainQuery( $conds, $opts ) {
279  $tables = array( 'recentchanges' );
280  $fields = RecentChange::selectFields();
281  $query_options = array();
282  $join_conds = array();
283 
285  $tables,
286  $fields,
287  $conds,
288  $join_conds,
289  $query_options,
290  ''
291  );
292 
293  if ( !wfRunHooks( 'ChangesListSpecialPageQuery',
294  array( $this->getName(), &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) )
295  ) {
296  return false;
297  }
298 
299  $dbr = $this->getDB();
300 
301  return $dbr->select(
302  $tables,
303  $fields,
304  $conds,
305  __METHOD__,
306  $query_options,
307  $join_conds
308  );
309  }
310 
316  protected function getDB() {
317  return wfGetDB( DB_SLAVE );
318  }
319 
326  public function webOutput( $rows, $opts ) {
327  if ( !$this->including() ) {
328  $this->outputFeedLinks();
329  $this->doHeader( $opts, $rows->numRows() );
330  }
331 
332  $this->outputChangesList( $rows, $opts );
333  }
334 
338  public function outputFeedLinks() {
339  // nothing by default
340  }
341 
348  abstract public function outputChangesList( $rows, $opts );
349 
356  public function doHeader( $opts, $numRows ) {
357  $this->setTopText( $opts );
358 
359  // @todo Lots of stuff should be done here.
360 
361  $this->setBottomText( $opts );
362  }
363 
370  function setTopText( FormOptions $opts ) {
371  // nothing by default
372  }
373 
380  function setBottomText( FormOptions $opts ) {
381  // nothing by default
382  }
383 
392  function getExtraOptions( $opts ) {
393  return array();
394  }
395 
404  public static function makeLegend( IContextSource $context ) {
405  global $wgRecentChangesFlags;
406  $user = $context->getUser();
407  # The legend showing what the letters and stuff mean
408  $legend = Xml::openElement( 'dl' ) . "\n";
409  # Iterates through them and gets the messages for both letter and tooltip
410  $legendItems = $wgRecentChangesFlags;
411  if ( !$user->useRCPatrol() ) {
412  unset( $legendItems['unpatrolled'] );
413  }
414  foreach ( $legendItems as $key => $legendInfo ) { # generate items of the legend
415  $label = $legendInfo['title'];
416  $letter = $legendInfo['letter'];
417  $cssClass = isset( $legendInfo['class'] ) ? $legendInfo['class'] : $key;
418 
419  $legend .= Xml::element( 'dt',
420  array( 'class' => $cssClass ), $context->msg( $letter )->text()
421  ) . "\n";
422  if ( $key === 'newpage' ) {
423  $legend .= Xml::openElement( 'dd' );
424  $legend .= $context->msg( $label )->escaped();
425  $legend .= ' ' . $context->msg( 'recentchanges-legend-newpage' )->parse();
426  $legend .= Xml::closeElement( 'dd' ) . "\n";
427  } else {
428  $legend .= Xml::element( 'dd', array(),
429  $context->msg( $label )->text()
430  ) . "\n";
431  }
432  }
433  # (+-123)
434  $legend .= Xml::tags( 'dt',
435  array( 'class' => 'mw-plusminus-pos' ),
436  $context->msg( 'recentchanges-legend-plusminus' )->parse()
437  ) . "\n";
438  $legend .= Xml::element(
439  'dd',
440  array( 'class' => 'mw-changeslist-legend-plusminus' ),
441  $context->msg( 'recentchanges-label-plusminus' )->text()
442  ) . "\n";
443  $legend .= Xml::closeElement( 'dl' ) . "\n";
444 
445  # Collapsibility
446  $legend =
447  '<div class="mw-changeslist-legend">' .
448  $context->msg( 'recentchanges-legend-heading' )->parse() .
449  '<div class="mw-collapsible-content">' . $legend . '</div>' .
450  '</div>';
451 
452  return $legend;
453  }
454 
458  protected function addModules() {
459  $out = $this->getOutput();
460  // Styles and behavior for the legend box (see makeLegend())
461  $out->addModuleStyles( 'mediawiki.special.changeslist.legend' );
462  $out->addModules( 'mediawiki.special.changeslist.legend.js' );
463  }
464 
465  protected function getGroupName() {
466  return 'changes';
467  }
468 }
ChangesListSpecialPage\getExtraOptions
getExtraOptions( $opts)
Get options to be displayed in a form.
Definition: ChangesListSpecialPage.php:389
of
globals txt Globals are evil The original MediaWiki code relied on globals for processing context far too often MediaWiki development since then has been a story of slowly moving context out of global variables and into objects Storing processing context in object member variables allows those objects to be reused in a much more flexible way Consider the elegance of
Definition: globals.txt:10
php
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
Definition: skin.txt:62
LinkBatch
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:30
Xml\tags
static tags( $element, $attribs=null, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:131
$tables
namespace and then decline to actually register it RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist & $tables
Definition: hooks.txt:815
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:535
ChangesListSpecialPage\execute
execute( $subpage)
Main execution point.
Definition: ChangesListSpecialPage.php:42
wfGetDB
& wfGetDB( $db, $groups=array(), $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3659
ChangesListSpecialPage\parseParameters
parseParameters( $par, FormOptions $opts)
Process $par and put options found in $opts.
Definition: ChangesListSpecialPage.php:179
FormOptions\INTNULL
const INTNULL
Integer type or null, maps to WebRequest::getIntOrNull() This is useful for the namespace selector.
Definition: FormOptions.php:54
ChangesListSpecialPage
Special page which uses a ChangesList to show query results.
Definition: ChangesListSpecialPage.php:30
$params
$params
Definition: styleTest.css.php:40
IContextSource\msg
msg()
Get a Message object with context set.
ChangesListSpecialPage\fetchOptionsFromRequest
fetchOptionsFromRequest( $opts)
Fetch values for a FormOptions object from the WebRequest associated with this instance.
Definition: ChangesListSpecialPage.php:167
SpecialPage\getName
getName()
Get the name of this Special Page.
Definition: SpecialPage.php:139
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:109
ChangesListSpecialPage\doHeader
doHeader( $opts, $numRows)
Set the text to be displayed above the changes.
Definition: ChangesListSpecialPage.php:353
ChangesListSpecialPage\makeLegend
static makeLegend(IContextSource $context)
Return the legend displayed within the fieldset.
Definition: ChangesListSpecialPage.php:401
$dbr
$dbr
Definition: testCompression.php:48
ChangesListSpecialPage\webOutput
webOutput( $rows, $opts)
Send output to the OutputPage object, only called if not used feeds.
Definition: ChangesListSpecialPage.php:323
$out
$out
Definition: UtfNormalGenerate.php:167
ChangeTags\modifyDisplayQuery
static modifyDisplayQuery(&$tables, &$fields, &$conds, &$join_conds, &$options, $filter_tag=false)
Applies all tags-related changes to a query.
Definition: ChangeTags.php:202
ChangesListSpecialPage\doMainQuery
doMainQuery( $conds, $opts)
Process the query.
Definition: ChangesListSpecialPage.php:275
ChangesListSpecialPage\getRows
getRows()
Get the database result for this special page instance.
Definition: ChangesListSpecialPage.php:77
ChangesListSpecialPage\outputFeedLinks
outputFeedLinks()
Output feed links.
Definition: ChangesListSpecialPage.php:335
ChangesListSpecialPage\outputChangesList
outputChangesList( $rows, $opts)
Build and output the actual changes list.
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:39
wfRunHooks
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:4010
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
Definition: SpecialPage.php:352
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:545
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
ChangesListSpecialPage\$rcOptions
FormOptions $rcOptions
Definition: ChangesListSpecialPage.php:33
NS_USER_TALK
const NS_USER_TALK
Definition: Defines.php:82
ChangesListSpecialPage\buildMainQueryConds
buildMainQueryConds(FormOptions $opts)
Return an array of conditions depending of options set in $opts.
Definition: ChangesListSpecialPage.php:198
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:33
ChangesListSpecialPage\setup
setup( $parameters)
Create a FormOptions object with options as specified by the user.
Definition: ChangesListSpecialPage.php:104
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:525
IContextSource\getUser
getUser()
Get the User object.
ChangesListSpecialPage\getCustomFilters
getCustomFilters()
Get custom show/hide filters.
Definition: ChangesListSpecialPage.php:150
$user
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
Definition: hooks.txt:237
ChangesListSpecialPage\addModules
addModules()
Add page-specific modules.
Definition: ChangesListSpecialPage.php:455
IContextSource
Interface for objects which can provide a context on request.
Definition: IContextSource.php:29
ChangesListSpecialPage\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: ChangesListSpecialPage.php:462
ChangesListSpecialPage\getDefaultOptions
getDefaultOptions()
Get a FormOptions object containing the default options.
Definition: ChangesListSpecialPage.php:128
DB_SLAVE
const DB_SLAVE
Definition: Defines.php:55
RecentChange\selectFields
static selectFields()
Return the list of recentchanges fields that should be selected to create a new recentchanges object.
Definition: RecentChange.php:151
Xml\closeElement
static closeElement( $element)
Shortcut to close an XML element.
Definition: Xml.php:118
ChangesListSpecialPage\getDB
getDB()
Return a DatabaseBase object for reading.
Definition: ChangesListSpecialPage.php:313
as
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
Definition: distributors.txt:9
NS_USER
const NS_USER
Definition: Defines.php:81
ChangesListSpecialPage\$rcSubpage
string $rcSubpage
Definition: ChangesListSpecialPage.php:31
$batch
$batch
Definition: linkcache.txt:23
FormOptions
Helper class to keep track of options when mixing links and form elements.
Definition: FormOptions.php:35
ChangesListSpecialPage\setBottomText
setBottomText(FormOptions $opts)
Send the text to be displayed after the options.
Definition: ChangesListSpecialPage.php:377
ChangesListSpecialPage\validateOptions
validateOptions(FormOptions $opts)
Validate a FormOptions object generated by getDefaultOptions() with values already populated.
Definition: ChangesListSpecialPage.php:188
ChangesListSpecialPage\getOptions
getOptions()
Get the current FormOptions for this request.
Definition: ChangesListSpecialPage.php:89
MWNamespace\getAssociated
static getAssociated( $index)
Get the associated namespace.
Definition: Namespace.php:151
SpecialPage\outputHeader
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
Definition: SpecialPage.php:443
SpecialPage\including
including( $x=null)
Whether the special page is being evaluated via transclusion.
Definition: SpecialPage.php:207
ChangesListSpecialPage\$customFilters
array $customFilters
Definition: ChangesListSpecialPage.php:35
ChangesListSpecialPage\setTopText
setTopText(FormOptions $opts)
Send the text to be displayed before the options.
Definition: ChangesListSpecialPage.php:367