MediaWiki  master
SpecialWhatLinksHere.php
Go to the documentation of this file.
1 <?php
29 
37  protected $opts;
38 
39  protected $selfTitle;
40 
42  protected $target;
43 
45  private $loadBalancer;
46 
49 
52 
55 
58 
60  private $namespaceInfo;
61 
62  protected $limits = [ 20, 50, 100, 250, 500 ];
63 
72  public function __construct(
79  ) {
80  parent::__construct( 'Whatlinkshere' );
81  $this->loadBalancer = $loadBalancer;
82  $this->linkBatchFactory = $linkBatchFactory;
83  $this->permissionManager = $permissionManager;
84  $this->contentHandlerFactory = $contentHandlerFactory;
85  $this->searchEngineFactory = $searchEngineFactory;
86  $this->namespaceInfo = $namespaceInfo;
87  }
88 
89  public function execute( $par ) {
90  $out = $this->getOutput();
91 
92  $this->setHeaders();
93  $this->outputHeader();
94  $this->addHelpLink( 'Help:What links here' );
95 
96  $opts = new FormOptions();
97 
98  $opts->add( 'target', '' );
99  $opts->add( 'namespace', '', FormOptions::INTNULL );
100  $opts->add( 'limit', $this->getConfig()->get( 'QueryPageDefaultLimit' ) );
101  $opts->add( 'from', 0 );
102  $opts->add( 'back', 0 );
103  $opts->add( 'hideredirs', false );
104  $opts->add( 'hidetrans', false );
105  $opts->add( 'hidelinks', false );
106  $opts->add( 'hideimages', false );
107  $opts->add( 'invert', false );
108 
110  $opts->validateIntBounds( 'limit', 0, 5000 );
111 
112  // Give precedence to subpage syntax
113  if ( $par !== null ) {
114  $opts->setValue( 'target', $par );
115  }
116 
117  // Bind to member variable
118  $this->opts = $opts;
119 
120  $this->target = Title::newFromText( $opts->getValue( 'target' ) );
121  if ( !$this->target ) {
122  if ( !$this->including() ) {
123  $out->addHTML( $this->whatlinkshereForm() );
124  }
125 
126  return;
127  }
128 
129  $this->getSkin()->setRelevantTitle( $this->target );
130 
131  $this->selfTitle = $this->getPageTitle( $this->target->getPrefixedDBkey() );
132 
133  $out->setPageTitle( $this->msg( 'whatlinkshere-title', $this->target->getPrefixedText() ) );
134  $out->addBacklinkSubtitle( $this->target );
135  $this->showIndirectLinks(
136  0,
137  $this->target,
138  $opts->getValue( 'limit' ),
139  $opts->getValue( 'from' ),
140  $opts->getValue( 'back' )
141  );
142  }
143 
151  private function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) {
152  $out = $this->getOutput();
153  $dbr = $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA );
154 
155  $hidelinks = $this->opts->getValue( 'hidelinks' );
156  $hideredirs = $this->opts->getValue( 'hideredirs' );
157  $hidetrans = $this->opts->getValue( 'hidetrans' );
158  $hideimages = $target->getNamespace() !== NS_FILE || $this->opts->getValue( 'hideimages' );
159 
160  // For historical reasons `pagelinks` always contains an entry for the redirect target.
161  // So we only need to query `redirect` if `pagelinks` isn't being queried.
162  $fetchredirs = $hidelinks && !$hideredirs;
163 
164  // Build query conds in concert for all four tables...
165  $conds = [];
166  $conds['redirect'] = [
167  'rd_namespace' => $target->getNamespace(),
168  'rd_title' => $target->getDBkey(),
169  ];
170  $conds['pagelinks'] = [
171  'pl_namespace' => $target->getNamespace(),
172  'pl_title' => $target->getDBkey(),
173  ];
174  $conds['templatelinks'] = [
175  'tl_namespace' => $target->getNamespace(),
176  'tl_title' => $target->getDBkey(),
177  ];
178  $conds['imagelinks'] = [
179  'il_to' => $target->getDBkey(),
180  ];
181 
182  $namespace = $this->opts->getValue( 'namespace' );
183  if ( is_int( $namespace ) ) {
184  $invert = $this->opts->getValue( 'invert' );
185  if ( $invert ) {
186  // Select all namespaces except for the specified one.
187  // This allows the database to use the *_from_namespace index. (T241837)
188  $namespaces = array_diff(
189  $this->namespaceInfo->getValidNamespaces(), [ $namespace ] );
190  } else {
191  $namespaces = $namespace;
192  }
193  $conds['redirect']['page_namespace'] = $namespaces;
194  $conds['pagelinks']['pl_from_namespace'] = $namespaces;
195  $conds['templatelinks']['tl_from_namespace'] = $namespaces;
196  $conds['imagelinks']['il_from_namespace'] = $namespaces;
197  }
198 
199  if ( $from ) {
200  $conds['redirect'][] = "rd_from >= $from";
201  $conds['templatelinks'][] = "tl_from >= $from";
202  $conds['pagelinks'][] = "pl_from >= $from";
203  $conds['imagelinks'][] = "il_from >= $from";
204  }
205 
206  if ( $hideredirs ) {
207  // For historical reasons `pagelinks` always contains an entry for the redirect target.
208  // So we hide that link when $hideredirs is set. There's unfortunately no way to tell when a
209  // redirect's content also links to the target.
210  $conds['pagelinks']['rd_from'] = null;
211  }
212 
213  $queryFunc = function ( IDatabase $dbr, $table, $fromCol ) use (
214  $conds, $target, $limit
215  ) {
216  // Read an extra row as an at-end check
217  $queryLimit = $limit + 1;
218  $on = [
219  "rd_from = $fromCol",
220  'rd_title' => $target->getDBkey(),
221  'rd_interwiki = ' . $dbr->addQuotes( '' ) . ' OR rd_interwiki IS NULL'
222  ];
223  $on['rd_namespace'] = $target->getNamespace();
224  // Inner LIMIT is 2X in case of stale backlinks with wrong namespaces
225  $subQuery = $dbr->newSelectQueryBuilder()
226  ->table( $table )
227  ->fields( [ $fromCol, 'rd_from', 'rd_fragment' ] )
228  ->conds( $conds[$table] )
229  ->orderBy( $fromCol )
230  ->limit( 2 * $queryLimit )
231  ->leftJoin( 'redirect', 'redirect', $on )
232  ->join( 'page', 'page', "$fromCol = page_id" );
233 
234  return $dbr->newSelectQueryBuilder()
235  ->table( $subQuery, 'temp_backlink_range' )
236  ->join( 'page', 'page', "$fromCol = page_id" )
237  ->fields( [ 'page_id', 'page_namespace', 'page_title',
238  'rd_from', 'rd_fragment', 'page_is_redirect' ] )
239  ->orderBy( 'page_id' )
240  ->limit( $queryLimit )
241  ->caller( __CLASS__ . '::showIndirectLinks' )
242  ->fetchResultSet();
243  };
244 
245  if ( $fetchredirs ) {
246  $rdRes = $dbr->select(
247  [ 'redirect', 'page' ],
248  [ 'page_id', 'page_namespace', 'page_title', 'rd_from', 'rd_fragment', 'page_is_redirect' ],
249  $conds['redirect'],
250  __METHOD__,
251  [ 'ORDER BY' => 'rd_from', 'LIMIT' => $limit + 1 ],
252  [ 'page' => [ 'JOIN', 'rd_from = page_id' ] ]
253  );
254  }
255 
256  if ( !$hidelinks ) {
257  $plRes = $queryFunc( $dbr, 'pagelinks', 'pl_from' );
258  }
259 
260  if ( !$hidetrans ) {
261  $tlRes = $queryFunc( $dbr, 'templatelinks', 'tl_from' );
262  }
263 
264  if ( !$hideimages ) {
265  $ilRes = $queryFunc( $dbr, 'imagelinks', 'il_from' );
266  }
267 
268  if ( ( !$fetchredirs || !$rdRes->numRows() )
269  && ( $hidelinks || !$plRes->numRows() )
270  && ( $hidetrans || !$tlRes->numRows() )
271  && ( $hideimages || !$ilRes->numRows() )
272  ) {
273  if ( $level == 0 && !$this->including() ) {
274  $out->addHTML( $this->whatlinkshereForm() );
275 
276  // Show filters only if there are links
277  if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
278  $out->addHTML( $this->getFilterPanel() );
279  }
280  $msgKey = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
281  $link = $this->getLinkRenderer()->makeLink(
282  $this->target,
283  null,
284  [],
285  $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
286  );
287 
288  $errMsg = $this->msg( $msgKey )
289  ->params( $this->target->getPrefixedText() )
290  ->rawParams( $link )
291  ->parseAsBlock();
292  $out->addHTML( $errMsg );
293  $out->setStatusCode( 404 );
294  }
295 
296  return;
297  }
298 
299  // Read the rows into an array and remove duplicates
300  // templatelinks comes third so that the templatelinks row overwrites the
301  // pagelinks/redirect row, so we get (inclusion) rather than nothing
302  $rows = [];
303  if ( $fetchredirs ) {
304  foreach ( $rdRes as $row ) {
305  $row->is_template = 0;
306  $row->is_image = 0;
307  $rows[$row->page_id] = $row;
308  }
309  }
310  if ( !$hidelinks ) {
311  foreach ( $plRes as $row ) {
312  $row->is_template = 0;
313  $row->is_image = 0;
314  $rows[$row->page_id] = $row;
315  }
316  }
317  if ( !$hidetrans ) {
318  foreach ( $tlRes as $row ) {
319  $row->is_template = 1;
320  $row->is_image = 0;
321  $rows[$row->page_id] = $row;
322  }
323  }
324  if ( !$hideimages ) {
325  foreach ( $ilRes as $row ) {
326  $row->is_template = 0;
327  $row->is_image = 1;
328  $rows[$row->page_id] = $row;
329  }
330  }
331 
332  // Sort by key and then change the keys to 0-based indices
333  ksort( $rows );
334  $rows = array_values( $rows );
335 
336  $numRows = count( $rows );
337 
338  // Work out the start and end IDs, for prev/next links
339  if ( $numRows > $limit ) {
340  // More rows available after these ones
341  // Get the ID from the last row in the result set
342  $nextId = $rows[$limit]->page_id;
343  // Remove undisplayed rows
344  $rows = array_slice( $rows, 0, $limit );
345  } else {
346  // No more rows after
347  $nextId = false;
348  }
349  $prevId = $from;
350 
351  // use LinkBatch to make sure, that all required data (associated with Titles)
352  // is loaded in one query
353  $lb = $this->linkBatchFactory->newLinkBatch();
354  foreach ( $rows as $row ) {
355  $lb->add( $row->page_namespace, $row->page_title );
356  }
357  $lb->execute();
358 
359  if ( $level == 0 && !$this->including() ) {
360  $out->addHTML( $this->whatlinkshereForm() );
361  $out->addHTML( $this->getFilterPanel() );
362 
363  $link = $this->getLinkRenderer()->makeLink(
364  $this->target,
365  null,
366  [],
367  $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
368  );
369 
370  $msg = $this->msg( 'linkshere' )
371  ->params( $this->target->getPrefixedText() )
372  ->rawParams( $link )
373  ->parseAsBlock();
374  $out->addHTML( $msg );
375 
376  $out->addWikiMsg( 'whatlinkshere-count', Message::numParam( count( $rows ) ) );
377 
378  $prevnext = $this->getPrevNext( $prevId, $nextId );
379  $out->addHTML( $prevnext );
380  }
381  $out->addHTML( $this->listStart( $level ) );
382  foreach ( $rows as $row ) {
383  $nt = Title::makeTitle( $row->page_namespace, $row->page_title );
384 
385  if ( $row->rd_from && $level < 2 ) {
386  $out->addHTML( $this->listItem( $row, $nt, $target, true ) );
387  $this->showIndirectLinks(
388  $level + 1,
389  $nt,
390  $this->getConfig()->get( 'MaxRedirectLinksRetrieved' )
391  );
392  $out->addHTML( Xml::closeElement( 'li' ) );
393  } else {
394  $out->addHTML( $this->listItem( $row, $nt, $target ) );
395  }
396  }
397 
398  $out->addHTML( $this->listEnd() );
399 
400  if ( $level == 0 && !$this->including() ) {
401  $out->addHTML( $prevnext );
402  }
403  }
404 
405  protected function listStart( $level ) {
406  return Xml::openElement( 'ul', ( $level ? [] : [ 'id' => 'mw-whatlinkshere-list' ] ) );
407  }
408 
409  protected function listItem( $row, $nt, $target, $notClose = false ) {
410  $dirmark = $this->getLanguage()->getDirMark();
411 
412  if ( $row->rd_from ) {
413  $query = [ 'redirect' => 'no' ];
414  } else {
415  $query = [];
416  }
417 
418  $link = $this->getLinkRenderer()->makeKnownLink(
419  $nt,
420  null,
421  $row->page_is_redirect ? [ 'class' => 'mw-redirect' ] : [],
422  $query
423  );
424 
425  // Display properties (redirect or template)
426  $propsText = '';
427  $props = [];
428  if ( (string)$row->rd_fragment !== '' ) {
429  $props[] = $this->msg( 'whatlinkshere-sectionredir' )
430  ->rawParams( $this->getLinkRenderer()->makeLink(
431  $target->createFragmentTarget( $row->rd_fragment ),
432  $row->rd_fragment
433  ) )->escaped();
434  } elseif ( $row->rd_from ) {
435  $props[] = $this->msg( 'isredirect' )->escaped();
436  }
437  if ( $row->is_template ) {
438  $props[] = $this->msg( 'istemplate' )->escaped();
439  }
440  if ( $row->is_image ) {
441  $props[] = $this->msg( 'isimage' )->escaped();
442  }
443 
444  $this->getHookRunner()->onWhatLinksHereProps( $row, $nt, $target, $props );
445 
446  if ( count( $props ) ) {
447  $propsText = $this->msg( 'parentheses' )
448  ->rawParams( $this->getLanguage()->semicolonList( $props ) )->escaped();
449  }
450 
451  # Space for utilities links, with a what-links-here link provided
452  $wlhLink = $this->wlhLink(
453  $nt,
454  $this->msg( 'whatlinkshere-links' )->text(),
455  $this->msg( 'editlink' )->text()
456  );
457  $wlh = Xml::wrapClass(
458  $this->msg( 'parentheses' )->rawParams( $wlhLink )->escaped(),
459  'mw-whatlinkshere-tools'
460  );
461 
462  return $notClose ?
463  Xml::openElement( 'li' ) . "$link $propsText $dirmark $wlh\n" :
464  Xml::tags( 'li', null, "$link $propsText $dirmark $wlh" ) . "\n";
465  }
466 
467  protected function listEnd() {
468  return Xml::closeElement( 'ul' );
469  }
470 
471  protected function wlhLink( Title $target, $text, $editText ) {
472  static $title = null;
473  if ( $title === null ) {
474  $title = $this->getPageTitle();
475  }
476 
477  $linkRenderer = $this->getLinkRenderer();
478 
479  // always show a "<- Links" link
480  $links = [
481  'links' => $linkRenderer->makeKnownLink(
482  $title,
483  $text,
484  [],
485  [ 'target' => $target->getPrefixedText() ]
486  ),
487  ];
488 
489  // if the page is editable, add an edit link
490  if (
491  // check user permissions
492  $this->permissionManager->userHasRight( $this->getUser(), 'edit' ) &&
493  // check, if the content model is editable through action=edit
494  $this->contentHandlerFactory->getContentHandler( $target->getContentModel() )
495  ->supportsDirectEditing()
496  ) {
497  $links['edit'] = $linkRenderer->makeKnownLink(
498  $target,
499  $editText,
500  [],
501  [ 'action' => 'edit' ]
502  );
503  }
504 
505  // build the links html
506  return $this->getLanguage()->pipeList( $links );
507  }
508 
509  private function makeSelfLink( $text, $query ) {
510  return $this->getLinkRenderer()->makeKnownLink(
511  $this->selfTitle,
512  $text,
513  [],
514  $query
515  );
516  }
517 
518  private function getPrevNext( $prevId, $nextId ) {
519  $currentLimit = $this->opts->getValue( 'limit' );
520  $prev = $this->msg( 'whatlinkshere-prev' )->numParams( $currentLimit )->text();
521  $next = $this->msg( 'whatlinkshere-next' )->numParams( $currentLimit )->text();
522 
523  $changed = $this->opts->getChangedValues();
524  unset( $changed['target'] ); // Already in the request title
525 
526  if ( $prevId != 0 ) {
527  $overrides = [ 'from' => $this->opts->getValue( 'back' ) ];
528  $prev = Message::rawParam( $this->makeSelfLink( $prev, array_merge( $changed, $overrides ) ) );
529  }
530  if ( $nextId != 0 ) {
531  $overrides = [ 'from' => $nextId, 'back' => $prevId ];
532  $next = Message::rawParam( $this->makeSelfLink( $next, array_merge( $changed, $overrides ) ) );
533  }
534 
535  $limitLinks = [];
536  $lang = $this->getLanguage();
537  foreach ( $this->limits as $limit ) {
538  $prettyLimit = $lang->formatNum( $limit );
539  $overrides = [ 'limit' => $limit ];
540  $limitLinks[] = $this->makeSelfLink( $prettyLimit, array_merge( $changed, $overrides ) );
541  }
542 
543  $nums = $lang->pipeList( $limitLinks );
544 
545  return $this->msg( 'viewprevnext' )->params( $prev, $next )->rawParams( $nums )->escaped();
546  }
547 
548  private function whatlinkshereForm() {
549  // We get nicer value from the title object
550  $this->opts->consumeValue( 'target' );
551  // Reset these for new requests
552  $this->opts->consumeValues( [ 'back', 'from' ] );
553 
554  $target = $this->target ? $this->target->getPrefixedText() : '';
555  $namespace = $this->opts->consumeValue( 'namespace' );
556  $nsinvert = $this->opts->consumeValue( 'invert' );
557 
558  # Build up the form
559  $f = Xml::openElement( 'form', [ 'action' => wfScript() ] );
560 
561  # Values that should not be forgotten
562  $f .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
563  foreach ( $this->opts->getUnconsumedValues() as $name => $value ) {
564  $f .= Html::hidden( $name, $value );
565  }
566 
567  $f .= Xml::fieldset( $this->msg( 'whatlinkshere' )->text() );
568 
569  # Target input (.mw-searchInput enables suggestions)
570  $f .= Xml::inputLabel( $this->msg( 'whatlinkshere-page' )->text(), 'target',
571  'mw-whatlinkshere-target', 40, $target, [ 'class' => 'mw-searchInput' ] );
572 
573  $f .= ' ';
574 
575  # Namespace selector
577  [
578  'selected' => $namespace,
579  'all' => '',
580  'label' => $this->msg( 'namespace' )->text(),
581  'in-user-lang' => true,
582  ], [
583  'name' => 'namespace',
584  'id' => 'namespace',
585  'class' => 'namespaceselector',
586  ]
587  );
588 
589  $f .= "\u{00A0}" .
591  $this->msg( 'invert' )->text(),
592  'invert',
593  'nsinvert',
594  $nsinvert,
595  [ 'title' => $this->msg( 'tooltip-whatlinkshere-invert' )->text() ]
596  );
597 
598  $f .= ' ';
599 
600  # Submit
601  $f .= Xml::submitButton( $this->msg( 'whatlinkshere-submit' )->text() );
602 
603  # Close
604  $f .= Xml::closeElement( 'fieldset' ) . Xml::closeElement( 'form' ) . "\n";
605 
606  return $f;
607  }
608 
614  private function getFilterPanel() {
615  $show = $this->msg( 'show' )->text();
616  $hide = $this->msg( 'hide' )->text();
617 
618  $changed = $this->opts->getChangedValues();
619  unset( $changed['target'] ); // Already in the request title
620 
621  $links = [];
622  $types = [ 'hidetrans', 'hidelinks', 'hideredirs' ];
623  if ( $this->target->getNamespace() === NS_FILE ) {
624  $types[] = 'hideimages';
625  }
626 
627  // Combined message keys: 'whatlinkshere-hideredirs', 'whatlinkshere-hidetrans',
628  // 'whatlinkshere-hidelinks', 'whatlinkshere-hideimages'
629  // To be sure they will be found by grep
630  foreach ( $types as $type ) {
631  $chosen = $this->opts->getValue( $type );
632  $msg = $chosen ? $show : $hide;
633  $overrides = [ $type => !$chosen ];
634  $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
635  $this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped();
636  }
637 
638  return Xml::fieldset(
639  $this->msg( 'whatlinkshere-filters' )->text(),
640  $this->getLanguage()->pipeList( $links )
641  );
642  }
643 
652  public function prefixSearchSubpages( $search, $limit, $offset ) {
653  return $this->prefixSearchString( $search, $limit, $offset, $this->searchEngineFactory );
654  }
655 
656  protected function getGroupName() {
657  return 'pagetools';
658  }
659 }
SpecialPage\$linkRenderer
LinkRenderer null $linkRenderer
Definition: SpecialPage.php:79
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:742
Message\numParam
static numParam( $num)
Definition: Message.php:1038
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:900
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:361
SpecialWhatLinksHere\$limits
$limits
Definition: SpecialWhatLinksHere.php:62
SpecialWhatLinksHere\listEnd
listEnd()
Definition: SpecialWhatLinksHere.php:467
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:788
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
FormOptions\getValue
getValue( $name)
Get the value for the given option name.
Definition: FormOptions.php:182
SpecialWhatLinksHere\$linkBatchFactory
LinkBatchFactory $linkBatchFactory
Definition: SpecialWhatLinksHere.php:48
FormOptions\INTNULL
const INTNULL
Integer type or null, maps to WebRequest::getIntOrNull() This is useful for the namespace selector.
Definition: FormOptions.php:55
Title\getPrefixedText
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:1884
SearchEngineFactory
Factory class for SearchEngine.
Definition: SearchEngineFactory.php:13
SpecialWhatLinksHere\$searchEngineFactory
SearchEngineFactory $searchEngineFactory
Definition: SpecialWhatLinksHere.php:57
SpecialWhatLinksHere\whatlinkshereForm
whatlinkshereForm()
Definition: SpecialWhatLinksHere.php:548
SpecialPage\getSkin
getSkin()
Shortcut to get the skin being used for this instance.
Definition: SpecialPage.php:808
SpecialWhatLinksHere\prefixSearchSubpages
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
Definition: SpecialWhatLinksHere.php:652
IncludableSpecialPage
Shortcut to construct an includable special page.
Definition: IncludableSpecialPage.php:29
FormOptions\validateIntBounds
validateIntBounds( $name, $min, $max)
Definition: FormOptions.php:255
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:818
FormOptions\fetchValuesFromRequest
fetchValuesFromRequest(WebRequest $r, $optionKeys=null)
Fetch values for all options (or selected options) from the given WebRequest, making them available f...
Definition: FormOptions.php:346
Xml\openElement
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:110
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
$dbr
$dbr
Definition: testCompression.php:54
Xml\fieldset
static fieldset( $legend=false, $content=false, $attribs=[])
Shortcut for creating fieldsets.
Definition: Xml.php:618
SpecialPage\prefixSearchString
prefixSearchString( $search, $limit, $offset, SearchEngineFactory $searchEngineFactory=null)
Perform a regular substring search for prefixSearchSubpages.
Definition: SpecialPage.php:575
FormOptions\add
add( $name, $default, $type=self::AUTO)
Add an option to be handled by this FormOptions instance.
Definition: FormOptions.php:83
SpecialPage\addHelpLink
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Definition: SpecialPage.php:936
Xml\wrapClass
static wrapClass( $text, $class, $tag='span', $attribs=[])
Shortcut to make a specific element with a class attribute.
Definition: Xml.php:268
Title\getDBkey
getDBkey()
Get the main part with underscores.
Definition: Title.php:1057
SpecialPage\getHookRunner
getHookRunner()
Definition: SpecialPage.php:1083
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:866
SpecialWhatLinksHere\$loadBalancer
ILoadBalancer $loadBalancer
Definition: SpecialWhatLinksHere.php:45
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2533
Title\getNamespace
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:1066
SpecialWhatLinksHere\getPrevNext
getPrevNext( $prevId, $nextId)
Definition: SpecialWhatLinksHere.php:518
SpecialWhatLinksHere\wlhLink
wlhLink(Title $target, $text, $editText)
Definition: SpecialWhatLinksHere.php:471
MediaWiki\Cache\LinkBatchFactory
Definition: LinkBatchFactory.php:38
SpecialWhatLinksHere\showIndirectLinks
showIndirectLinks( $level, $target, $limit, $from=0, $back=0)
Definition: SpecialWhatLinksHere.php:151
SpecialWhatLinksHere
Implements Special:Whatlinkshere.
Definition: SpecialWhatLinksHere.php:35
$title
$title
Definition: testCompression.php:38
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!...
Definition: SpecialPage.php:616
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:624
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
FormOptions\setValue
setValue( $name, $value, $force=false)
Use to set the value of an option.
Definition: FormOptions.php:165
Title\createFragmentTarget
createFragmentTarget( $fragment)
Creates a new Title for a different fragment of the same page.
Definition: Title.php:1830
Html\hidden
static hidden( $name, $value, array $attribs=[])
Convenience function to produce an input element with type=hidden.
Definition: Html.php:825
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:51
SpecialWhatLinksHere\$namespaceInfo
NamespaceInfo $namespaceInfo
Definition: SpecialWhatLinksHere.php:60
MediaWiki\Content\IContentHandlerFactory
Definition: IContentHandlerFactory.php:10
Html\namespaceSelector
static namespaceSelector(array $params=[], array $selectAttribs=[])
Build a drop-down box for selecting a namespace.
Definition: Html.php:917
Message\rawParam
static rawParam( $raw)
Definition: Message.php:1027
Xml\tags
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:132
SpecialWhatLinksHere\execute
execute( $par)
Default execute method Checks user permissions.
Definition: SpecialWhatLinksHere.php:89
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:778
SpecialWhatLinksHere\__construct
__construct(ILoadBalancer $loadBalancer, LinkBatchFactory $linkBatchFactory, PermissionManager $permissionManager, IContentHandlerFactory $contentHandlerFactory, SearchEngineFactory $searchEngineFactory, NamespaceInfo $namespaceInfo)
Definition: SpecialWhatLinksHere.php:72
Title\getContentModel
getContentModel( $flags=0)
Get the page's content model id, see the CONTENT_MODEL_XXX constants.
Definition: Title.php:1078
SpecialWhatLinksHere\makeSelfLink
makeSelfLink( $text, $query)
Definition: SpecialWhatLinksHere.php:509
SpecialWhatLinksHere\$selfTitle
$selfTitle
Definition: SpecialWhatLinksHere.php:39
SpecialWhatLinksHere\$permissionManager
PermissionManager $permissionManager
Definition: SpecialWhatLinksHere.php:51
SpecialWhatLinksHere\listItem
listItem( $row, $nt, $target, $notClose=false)
Definition: SpecialWhatLinksHere.php:409
SpecialWhatLinksHere\$target
Title $target
Definition: SpecialWhatLinksHere.php:42
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:1016
Title
Represents a title within MediaWiki.
Definition: Title.php:46
SpecialWhatLinksHere\listStart
listStart( $level)
Definition: SpecialWhatLinksHere.php:405
Xml\closeElement
static closeElement( $element)
Shortcut to close an XML element.
Definition: Xml.php:119
SpecialWhatLinksHere\$contentHandlerFactory
IContentHandlerFactory $contentHandlerFactory
Definition: SpecialWhatLinksHere.php:54
SpecialWhatLinksHere\getFilterPanel
getFilterPanel()
Create filter panel.
Definition: SpecialWhatLinksHere.php:614
NamespaceInfo
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Definition: NamespaceInfo.php:35
FormOptions
Helper class to keep track of options when mixing links and form elements.
Definition: FormOptions.php:35
NS_FILE
const NS_FILE
Definition: Defines.php:69
Xml\inputLabel
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:386
SpecialWhatLinksHere\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialWhatLinksHere.php:656
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:707
SpecialPage\including
including( $x=null)
Whether the special page is being evaluated via transclusion.
Definition: SpecialPage.php:265
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
SpecialWhatLinksHere\$opts
FormOptions $opts
Definition: SpecialWhatLinksHere.php:37
Xml\submitButton
static submitButton( $value, $attribs=[])
Convenience function to build an HTML submit button When $wgUseMediaWikiUIEverywhere is true it will ...
Definition: Xml.php:465
Xml\checkLabel
static checkLabel( $label, $name, $id, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox with a label.
Definition: Xml.php:425
$type
$type
Definition: testCompression.php:52