MediaWiki  master
SpecialWhatlinkshere.php
Go to the documentation of this file.
1 <?php
25 
33  protected $opts;
34 
35  protected $selfTitle;
36 
38  protected $target;
39 
40  protected $limits = [ 20, 50, 100, 250, 500 ];
41 
42  public function __construct() {
43  parent::__construct( 'Whatlinkshere' );
44  }
45 
46  function execute( $par ) {
47  $out = $this->getOutput();
48 
49  $this->setHeaders();
50  $this->outputHeader();
51  $this->addHelpLink( 'Help:What links here' );
52 
53  $opts = new FormOptions();
54 
55  $opts->add( 'target', '' );
56  $opts->add( 'namespace', '', FormOptions::INTNULL );
57  $opts->add( 'limit', $this->getConfig()->get( 'QueryPageDefaultLimit' ) );
58  $opts->add( 'from', 0 );
59  $opts->add( 'back', 0 );
60  $opts->add( 'hideredirs', false );
61  $opts->add( 'hidetrans', false );
62  $opts->add( 'hidelinks', false );
63  $opts->add( 'hideimages', false );
64  $opts->add( 'invert', false );
65 
67  $opts->validateIntBounds( 'limit', 0, 5000 );
68 
69  // Give precedence to subpage syntax
70  if ( $par !== null ) {
71  $opts->setValue( 'target', $par );
72  }
73 
74  // Bind to member variable
75  $this->opts = $opts;
76 
77  $this->target = Title::newFromText( $opts->getValue( 'target' ) );
78  if ( !$this->target ) {
79  if ( !$this->including() ) {
80  $out->addHTML( $this->whatlinkshereForm() );
81  }
82 
83  return;
84  }
85 
86  $this->getSkin()->setRelevantTitle( $this->target );
87 
88  $this->selfTitle = $this->getPageTitle( $this->target->getPrefixedDBkey() );
89 
90  $out->setPageTitle( $this->msg( 'whatlinkshere-title', $this->target->getPrefixedText() ) );
91  $out->addBacklinkSubtitle( $this->target );
92  $this->showIndirectLinks(
93  0,
94  $this->target,
95  $opts->getValue( 'limit' ),
96  $opts->getValue( 'from' ),
97  $opts->getValue( 'back' )
98  );
99  }
100 
108  function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) {
109  $out = $this->getOutput();
110  $dbr = wfGetDB( DB_REPLICA );
111 
112  $hidelinks = $this->opts->getValue( 'hidelinks' );
113  $hideredirs = $this->opts->getValue( 'hideredirs' );
114  $hidetrans = $this->opts->getValue( 'hidetrans' );
115  $hideimages = $target->getNamespace() != NS_FILE || $this->opts->getValue( 'hideimages' );
116 
117  $fetchlinks = ( !$hidelinks || !$hideredirs );
118 
119  // Build query conds in concert for all three tables...
120  $conds['pagelinks'] = [
121  'pl_namespace' => $target->getNamespace(),
122  'pl_title' => $target->getDBkey(),
123  ];
124  $conds['templatelinks'] = [
125  'tl_namespace' => $target->getNamespace(),
126  'tl_title' => $target->getDBkey(),
127  ];
128  $conds['imagelinks'] = [
129  'il_to' => $target->getDBkey(),
130  ];
131 
132  $namespace = $this->opts->getValue( 'namespace' );
133  $invert = $this->opts->getValue( 'invert' );
134  $nsComparison = ( $invert ? '!= ' : '= ' ) . $dbr->addQuotes( $namespace );
135  if ( is_int( $namespace ) ) {
136  $conds['pagelinks'][] = "pl_from_namespace $nsComparison";
137  $conds['templatelinks'][] = "tl_from_namespace $nsComparison";
138  $conds['imagelinks'][] = "il_from_namespace $nsComparison";
139  }
140 
141  if ( $from ) {
142  $conds['templatelinks'][] = "tl_from >= $from";
143  $conds['pagelinks'][] = "pl_from >= $from";
144  $conds['imagelinks'][] = "il_from >= $from";
145  }
146 
147  if ( $hideredirs ) {
148  $conds['pagelinks']['rd_from'] = null;
149  } elseif ( $hidelinks ) {
150  $conds['pagelinks'][] = 'rd_from is NOT NULL';
151  }
152 
153  $queryFunc = function ( IDatabase $dbr, $table, $fromCol ) use (
154  $conds, $target, $limit
155  ) {
156  // Read an extra row as an at-end check
157  $queryLimit = $limit + 1;
158  $on = [
159  "rd_from = $fromCol",
160  'rd_title' => $target->getDBkey(),
161  'rd_interwiki = ' . $dbr->addQuotes( '' ) . ' OR rd_interwiki IS NULL'
162  ];
163  $on['rd_namespace'] = $target->getNamespace();
164  // Inner LIMIT is 2X in case of stale backlinks with wrong namespaces
165  $subQuery = $dbr->buildSelectSubquery(
166  [ $table, 'redirect', 'page' ],
167  [ $fromCol, 'rd_from' ],
168  $conds[$table],
169  __CLASS__ . '::showIndirectLinks',
170  // Force JOIN order per T106682 to avoid large filesorts
171  [ 'ORDER BY' => $fromCol, 'LIMIT' => 2 * $queryLimit, 'STRAIGHT_JOIN' ],
172  [
173  'page' => [ 'INNER JOIN', "$fromCol = page_id" ],
174  'redirect' => [ 'LEFT JOIN', $on ]
175  ]
176  );
177  return $dbr->select(
178  [ 'page', 'temp_backlink_range' => $subQuery ],
179  [ 'page_id', 'page_namespace', 'page_title', 'rd_from', 'page_is_redirect' ],
180  [],
181  __CLASS__ . '::showIndirectLinks',
182  [ 'ORDER BY' => 'page_id', 'LIMIT' => $queryLimit ],
183  [ 'page' => [ 'INNER JOIN', "$fromCol = page_id" ] ]
184  );
185  };
186 
187  if ( $fetchlinks ) {
188  $plRes = $queryFunc( $dbr, 'pagelinks', 'pl_from' );
189  }
190 
191  if ( !$hidetrans ) {
192  $tlRes = $queryFunc( $dbr, 'templatelinks', 'tl_from' );
193  }
194 
195  if ( !$hideimages ) {
196  $ilRes = $queryFunc( $dbr, 'imagelinks', 'il_from' );
197  }
198 
199  if ( ( !$fetchlinks || !$plRes->numRows() )
200  && ( $hidetrans || !$tlRes->numRows() )
201  && ( $hideimages || !$ilRes->numRows() )
202  ) {
203  if ( 0 == $level ) {
204  if ( !$this->including() ) {
205  $out->addHTML( $this->whatlinkshereForm() );
206 
207  // Show filters only if there are links
208  if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
209  $out->addHTML( $this->getFilterPanel() );
210  }
211  $msgKey = is_int( $namespace ) ? 'nolinkshere-ns-2' : 'nolinkshere-2';
212  $link = $this->getLinkRenderer()->makeKnownLink(
213  $this->target,
214  null,
215  [],
216  $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
217  );
218 
219  $errMsg = $this->msg( $msgKey )->rawParams( $link )->parseAsBlock();
220  $out->addHTML( $errMsg );
221  $out->setStatusCode( 404 );
222  }
223  }
224 
225  return;
226  }
227 
228  // Read the rows into an array and remove duplicates
229  // templatelinks comes second so that the templatelinks row overwrites the
230  // pagelinks row, so we get (inclusion) rather than nothing
231  if ( $fetchlinks ) {
232  foreach ( $plRes as $row ) {
233  $row->is_template = 0;
234  $row->is_image = 0;
235  $rows[$row->page_id] = $row;
236  }
237  }
238  if ( !$hidetrans ) {
239  foreach ( $tlRes as $row ) {
240  $row->is_template = 1;
241  $row->is_image = 0;
242  $rows[$row->page_id] = $row;
243  }
244  }
245  if ( !$hideimages ) {
246  foreach ( $ilRes as $row ) {
247  $row->is_template = 0;
248  $row->is_image = 1;
249  $rows[$row->page_id] = $row;
250  }
251  }
252 
253  // Sort by key and then change the keys to 0-based indices
254  ksort( $rows );
255  $rows = array_values( $rows );
256 
257  $numRows = count( $rows );
258 
259  // Work out the start and end IDs, for prev/next links
260  if ( $numRows > $limit ) {
261  // More rows available after these ones
262  // Get the ID from the last row in the result set
263  $nextId = $rows[$limit]->page_id;
264  // Remove undisplayed rows
265  $rows = array_slice( $rows, 0, $limit );
266  } else {
267  // No more rows after
268  $nextId = false;
269  }
270  $prevId = $from;
271 
272  // use LinkBatch to make sure, that all required data (associated with Titles)
273  // is loaded in one query
274  $lb = new LinkBatch();
275  foreach ( $rows as $row ) {
276  $lb->add( $row->page_namespace, $row->page_title );
277  }
278  $lb->execute();
279 
280  if ( $level == 0 ) {
281  if ( !$this->including() ) {
282  $out->addHTML( $this->whatlinkshereForm() );
283  $out->addHTML( $this->getFilterPanel() );
284 
285  $link = $this->getLinkRenderer()->makeKnownLink(
286  $this->target,
287  null,
288  [],
289  $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
290  );
291 
292  $msg = $this->msg( 'linkshere-2' )->rawParams( $link )->parseAsBlock();
293  $out->addHTML( $msg );
294 
295  $prevnext = $this->getPrevNext( $prevId, $nextId );
296  $out->addHTML( $prevnext );
297  }
298  }
299  $out->addHTML( $this->listStart( $level ) );
300  foreach ( $rows as $row ) {
301  $nt = Title::makeTitle( $row->page_namespace, $row->page_title );
302 
303  if ( $row->rd_from && $level < 2 ) {
304  $out->addHTML( $this->listItem( $row, $nt, $target, true ) );
305  $this->showIndirectLinks(
306  $level + 1,
307  $nt,
308  $this->getConfig()->get( 'MaxRedirectLinksRetrieved' )
309  );
310  $out->addHTML( Xml::closeElement( 'li' ) );
311  } else {
312  $out->addHTML( $this->listItem( $row, $nt, $target ) );
313  }
314  }
315 
316  $out->addHTML( $this->listEnd() );
317 
318  if ( $level == 0 ) {
319  if ( !$this->including() ) {
320  $out->addHTML( $prevnext );
321  }
322  }
323  }
324 
325  protected function listStart( $level ) {
326  return Xml::openElement( 'ul', ( $level ? [] : [ 'id' => 'mw-whatlinkshere-list' ] ) );
327  }
328 
329  protected function listItem( $row, $nt, $target, $notClose = false ) {
330  $dirmark = $this->getLanguage()->getDirMark();
331 
332  # local message cache
333  static $msgcache = null;
334  if ( $msgcache === null ) {
335  static $msgs = [ 'isredirect', 'istemplate', 'semicolon-separator',
336  'whatlinkshere-links', 'isimage', 'editlink' ];
337  $msgcache = [];
338  foreach ( $msgs as $msg ) {
339  $msgcache[$msg] = $this->msg( $msg )->escaped();
340  }
341  }
342 
343  if ( $row->rd_from ) {
344  $query = [ 'redirect' => 'no' ];
345  } else {
346  $query = [];
347  }
348 
349  $link = $this->getLinkRenderer()->makeKnownLink(
350  $nt,
351  null,
352  $row->page_is_redirect ? [ 'class' => 'mw-redirect' ] : [],
353  $query
354  );
355 
356  // Display properties (redirect or template)
357  $propsText = '';
358  $props = [];
359  if ( $row->rd_from ) {
360  $props[] = $msgcache['isredirect'];
361  }
362  if ( $row->is_template ) {
363  $props[] = $msgcache['istemplate'];
364  }
365  if ( $row->is_image ) {
366  $props[] = $msgcache['isimage'];
367  }
368 
369  Hooks::run( 'WhatLinksHereProps', [ $row, $nt, $target, &$props ] );
370 
371  if ( count( $props ) ) {
372  $propsText = $this->msg( 'parentheses' )
373  ->rawParams( implode( $msgcache['semicolon-separator'], $props ) )->escaped();
374  }
375 
376  # Space for utilities links, with a what-links-here link provided
377  $wlhLink = $this->wlhLink( $nt, $msgcache['whatlinkshere-links'], $msgcache['editlink'] );
378  $wlh = Xml::wrapClass(
379  $this->msg( 'parentheses' )->rawParams( $wlhLink )->escaped(),
380  'mw-whatlinkshere-tools'
381  );
382 
383  return $notClose ?
384  Xml::openElement( 'li' ) . "$link $propsText $dirmark $wlh\n" :
385  Xml::tags( 'li', null, "$link $propsText $dirmark $wlh" ) . "\n";
386  }
387 
388  protected function listEnd() {
389  return Xml::closeElement( 'ul' );
390  }
391 
392  protected function wlhLink( Title $target, $text, $editText ) {
393  static $title = null;
394  if ( $title === null ) {
395  $title = $this->getPageTitle();
396  }
397 
398  $linkRenderer = $this->getLinkRenderer();
399 
400  if ( $text !== null ) {
401  $text = new HtmlArmor( $text );
402  }
403 
404  // always show a "<- Links" link
405  $links = [
406  'links' => $linkRenderer->makeKnownLink(
407  $title,
408  $text,
409  [],
410  [ 'target' => $target->getPrefixedText() ]
411  ),
412  ];
413 
414  // if the page is editable, add an edit link
415  if (
416  // check user permissions
417  $this->getUser()->isAllowed( 'edit' ) &&
418  // check, if the content model is editable through action=edit
419  ContentHandler::getForTitle( $target )->supportsDirectEditing()
420  ) {
421  if ( $editText !== null ) {
422  $editText = new HtmlArmor( $editText );
423  }
424 
425  $links['edit'] = $linkRenderer->makeKnownLink(
426  $target,
427  $editText,
428  [],
429  [ 'action' => 'edit' ]
430  );
431  }
432 
433  // build the links html
434  return $this->getLanguage()->pipeList( $links );
435  }
436 
437  function makeSelfLink( $text, $query ) {
438  if ( $text !== null ) {
439  $text = new HtmlArmor( $text );
440  }
441 
442  return $this->getLinkRenderer()->makeKnownLink(
443  $this->selfTitle,
444  $text,
445  [],
446  $query
447  );
448  }
449 
450  function getPrevNext( $prevId, $nextId ) {
451  $currentLimit = $this->opts->getValue( 'limit' );
452  $prev = $this->msg( 'whatlinkshere-prev' )->numParams( $currentLimit )->escaped();
453  $next = $this->msg( 'whatlinkshere-next' )->numParams( $currentLimit )->escaped();
454 
455  $changed = $this->opts->getChangedValues();
456  unset( $changed['target'] ); // Already in the request title
457 
458  if ( 0 != $prevId ) {
459  $overrides = [ 'from' => $this->opts->getValue( 'back' ) ];
460  $prev = $this->makeSelfLink( $prev, array_merge( $changed, $overrides ) );
461  }
462  if ( 0 != $nextId ) {
463  $overrides = [ 'from' => $nextId, 'back' => $prevId ];
464  $next = $this->makeSelfLink( $next, array_merge( $changed, $overrides ) );
465  }
466 
467  $limitLinks = [];
468  $lang = $this->getLanguage();
469  foreach ( $this->limits as $limit ) {
470  $prettyLimit = htmlspecialchars( $lang->formatNum( $limit ) );
471  $overrides = [ 'limit' => $limit ];
472  $limitLinks[] = $this->makeSelfLink( $prettyLimit, array_merge( $changed, $overrides ) );
473  }
474 
475  $nums = $lang->pipeList( $limitLinks );
476 
477  return $this->msg( 'viewprevnext' )->rawParams( $prev, $next, $nums )->escaped();
478  }
479 
480  function whatlinkshereForm() {
481  // We get nicer value from the title object
482  $this->opts->consumeValue( 'target' );
483  // Reset these for new requests
484  $this->opts->consumeValues( [ 'back', 'from' ] );
485 
486  $target = $this->target ? $this->target->getPrefixedText() : '';
487  $namespace = $this->opts->consumeValue( 'namespace' );
488  $nsinvert = $this->opts->consumeValue( 'invert' );
489 
490  # Build up the form
491  $f = Xml::openElement( 'form', [ 'action' => wfScript() ] );
492 
493  # Values that should not be forgotten
494  $f .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
495  foreach ( $this->opts->getUnconsumedValues() as $name => $value ) {
496  $f .= Html::hidden( $name, $value );
497  }
498 
499  $f .= Xml::fieldset( $this->msg( 'whatlinkshere' )->text() );
500 
501  # Target input (.mw-searchInput enables suggestions)
502  $f .= Xml::inputLabel( $this->msg( 'whatlinkshere-page' )->text(), 'target',
503  'mw-whatlinkshere-target', 40, $target, [ 'class' => 'mw-searchInput' ] );
504 
505  $f .= ' ';
506 
507  # Namespace selector
509  [
510  'selected' => $namespace,
511  'all' => '',
512  'label' => $this->msg( 'namespace' )->text()
513  ], [
514  'name' => 'namespace',
515  'id' => 'namespace',
516  'class' => 'namespaceselector',
517  ]
518  );
519 
520  $f .= '&#160;' .
522  $this->msg( 'invert' )->text(),
523  'invert',
524  'nsinvert',
525  $nsinvert,
526  [ 'title' => $this->msg( 'tooltip-whatlinkshere-invert' )->text() ]
527  );
528 
529  $f .= ' ';
530 
531  # Submit
532  $f .= Xml::submitButton( $this->msg( 'whatlinkshere-submit' )->text() );
533 
534  # Close
535  $f .= Xml::closeElement( 'fieldset' ) . Xml::closeElement( 'form' ) . "\n";
536 
537  return $f;
538  }
539 
545  function getFilterPanel() {
546  $show = $this->msg( 'show' )->escaped();
547  $hide = $this->msg( 'hide' )->escaped();
548 
549  $changed = $this->opts->getChangedValues();
550  unset( $changed['target'] ); // Already in the request title
551 
552  $links = [];
553  $types = [ 'hidetrans', 'hidelinks', 'hideredirs' ];
554  if ( $this->target->getNamespace() == NS_FILE ) {
555  $types[] = 'hideimages';
556  }
557 
558  // Combined message keys: 'whatlinkshere-hideredirs', 'whatlinkshere-hidetrans',
559  // 'whatlinkshere-hidelinks', 'whatlinkshere-hideimages'
560  // To be sure they will be found by grep
561  foreach ( $types as $type ) {
562  $chosen = $this->opts->getValue( $type );
563  $msg = $chosen ? $show : $hide;
564  $overrides = [ $type => !$chosen ];
565  $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
566  $this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped();
567  }
568 
569  return Xml::fieldset(
570  $this->msg( 'whatlinkshere-filters' )->text(),
571  $this->getLanguage()->pipeList( $links )
572  );
573  }
574 
583  public function prefixSearchSubpages( $search, $limit, $offset ) {
584  return $this->prefixSearchString( $search, $limit, $offset );
585  }
586 
587  protected function getGroupName() {
588  return 'pagetools';
589  }
590 }
wlhLink(Title $target, $text, $editText)
Helper class to keep track of options when mixing links and form elements.
Definition: FormOptions.php:35
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g.with the RejectParserCacheValue hook) because MediaWiki won't do it for you.&$defaults also a ContextSource after deleting those rows but within the same transaction $rows
Definition: hooks.txt:2636
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:790
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1623
wfScript($script= 'index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
setValue($name, $value, $force=false)
Use to set the value of an option.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
const INTNULL
Integer type or null, maps to WebRequest::getIntOrNull() This is useful for the namespace selector...
Definition: FormOptions.php:54
getPrevNext($prevId, $nextId)
buildSelectSubquery($table, $vars, $conds= '', $fname=__METHOD__, $options=[], $join_conds=[])
Equivalent to IDatabase::selectSQLText() except wraps the result in Subqyery.
if(!isset($args[0])) $lang
static hidden($name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
Definition: Html.php:790
addQuotes($s)
Adds quotes and backslashes.
$value
getFilterPanel()
Create filter panel.
static inputLabel($label, $name, $id, $size=false, $value=false, $attribs=[])
Convenience function to build an HTML text input field with a label.
Definition: Xml.php:381
including($x=null)
Whether the special page is being evaluated via transclusion.
getOutput()
Get the OutputPage being used for this instance.
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:1625
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:273
static submitButton($value, $attribs=[])
Convenience function to build an HTML submit button When $wgUseMediaWikiUIEverywhere is true it will ...
Definition: Xml.php:460
addHelpLink($to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
outputHeader($summaryMessageKey= '')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
fetchValuesFromRequest(WebRequest $r, $optionKeys=null)
Fetch values for all options (or selected options) from the given WebRequest, making them available f...
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:3038
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:34
static fieldset($legend=false, $content=false, $attribs=[])
Shortcut for creating fieldsets.
Definition: Xml.php:610
static closeElement($element)
Shortcut to close an XML element.
Definition: Xml.php:118
Shortcut to construct an includable special page.
getDBkey()
Get the main part with underscores.
Definition: Title.php:947
static wrapClass($text, $class, $tag= 'span', $attribs=[])
Shortcut to make a specific element with a class attribute.
Definition: Xml.php:263
getValue($name)
Get the value for the given option name.
static openElement($element, $attribs=null)
This opens an XML element.
Definition: Xml.php:109
getSkin()
Shortcut to get the skin being used for this instance.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes! ...
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:941
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:970
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
Definition: design.txt:12
msg($key)
Wrapper around wfMessage that sets the current context.
const NS_FILE
Definition: Defines.php:71
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
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
add($name, $default, $type=self::AUTO)
Add an option to be handled by this FormOptions instance.
Definition: FormOptions.php:81
validateIntBounds($name, $min, $max)
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
static tags($element, $attribs=null, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:131
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
getUser()
Shortcut to get the User executing this instance.
getConfig()
Shortcut to get main config object.
select($table, $vars, $conds= '', $fname=__METHOD__, $options=[], $join_conds=[])
Execute a SELECT query constructed using the various parameters provided.
showIndirectLinks($level, $target, $limit, $from=0, $back=0)
getLanguage()
Shortcut to get user's language.
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
static checkLabel($label, $name, $id, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox with a label.
Definition: Xml.php:420
const DB_REPLICA
Definition: defines.php:25
getRequest()
Get the WebRequest being used for this instance.
prefixSearchString($search, $limit, $offset)
Perform a regular substring search for prefixSearchSubpages.
static makeTitle($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:534
Implements Special:Whatlinkshere.
listItem($row, $nt, $target, $notClose=false)
prefixSearchSubpages($search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
getPageTitle($subpage=false)
Get a self-referential title object.
MediaWiki Linker LinkRenderer null $linkRenderer
Definition: SpecialPage.php:66
static namespaceSelector(array $params=[], array $selectAttribs=[])
Build a drop-down box for selecting a namespace.
Definition: Html.php:878