MediaWiki  master
SpecialPageFactory.php
Go to the documentation of this file.
1 <?php
26 
27 use Hooks;
28 use IContextSource;
29 use Language;
32 use Profiler;
33 use RequestContext;
34 use SpecialPage;
35 use Title;
36 use User;
37 use Wikimedia\ObjectFactory;
38 
68  private const CORE_LIST = [
69  // Maintenance Reports
70  'BrokenRedirects' => \SpecialBrokenRedirects::class,
71  'Deadendpages' => \SpecialDeadendPages::class,
72  'DoubleRedirects' => \SpecialDoubleRedirects::class,
73  'Longpages' => \SpecialLongPages::class,
74  'Ancientpages' => \SpecialAncientPages::class,
75  'Lonelypages' => \SpecialLonelyPages::class,
76  'Fewestrevisions' => \SpecialFewestRevisions::class,
77  'Withoutinterwiki' => \SpecialWithoutInterwiki::class,
78  'Protectedpages' => \SpecialProtectedpages::class,
79  'Protectedtitles' => \SpecialProtectedtitles::class,
80  'Shortpages' => \SpecialShortPages::class,
81  'Uncategorizedcategories' => \SpecialUncategorizedCategories::class,
82  'Uncategorizedimages' => \SpecialUncategorizedImages::class,
83  'Uncategorizedpages' => \SpecialUncategorizedPages::class,
84  'Uncategorizedtemplates' => \SpecialUncategorizedTemplates::class,
85  'Unusedcategories' => \SpecialUnusedCategories::class,
86  'Unusedimages' => \SpecialUnusedImages::class,
87  'Unusedtemplates' => \SpecialUnusedTemplates::class,
88  'Unwatchedpages' => \SpecialUnwatchedPages::class,
89  'Wantedcategories' => \SpecialWantedCategories::class,
90  'Wantedfiles' => \WantedFilesPage::class,
91  'Wantedpages' => \WantedPagesPage::class,
92  'Wantedtemplates' => \SpecialWantedTemplates::class,
93 
94  // List of pages
95  'Allpages' => \SpecialAllPages::class,
96  'Prefixindex' => \SpecialPrefixindex::class,
97  'Categories' => \SpecialCategories::class,
98  'Listredirects' => \SpecialListRedirects::class,
99  'PagesWithProp' => \SpecialPagesWithProp::class,
100  'TrackingCategories' => \SpecialTrackingCategories::class,
101 
102  // Authentication
103  'Userlogin' => \SpecialUserLogin::class,
104  'Userlogout' => \SpecialUserLogout::class,
105  'CreateAccount' => \SpecialCreateAccount::class,
106  'LinkAccounts' => \SpecialLinkAccounts::class,
107  'UnlinkAccounts' => \SpecialUnlinkAccounts::class,
108  'ChangeCredentials' => \SpecialChangeCredentials::class,
109  'RemoveCredentials' => \SpecialRemoveCredentials::class,
110 
111  // Users and rights
112  'Activeusers' => \SpecialActiveUsers::class,
113  'Block' => \SpecialBlock::class,
114  'Unblock' => \SpecialUnblock::class,
115  'BlockList' => \SpecialBlockList::class,
116  'AutoblockList' => \SpecialAutoblockList::class,
117  'ChangePassword' => \SpecialChangePassword::class,
118  'BotPasswords' => \SpecialBotPasswords::class,
119  'PasswordReset' => \SpecialPasswordReset::class,
120  'DeletedContributions' => \SpecialDeletedContributions::class,
121  'Preferences' => \SpecialPreferences::class,
122  'ResetTokens' => \SpecialResetTokens::class,
123  'Contributions' => \SpecialContributions::class,
124  'Listgrouprights' => \SpecialListGroupRights::class,
125  'Listgrants' => \SpecialListGrants::class,
126  'Listusers' => \SpecialListUsers::class,
127  'Listadmins' => \SpecialListAdmins::class,
128  'Listbots' => \SpecialListBots::class,
129  'Userrights' => \UserrightsPage::class,
130  'EditWatchlist' => [
131  'class' => \SpecialEditWatchlist::class,
132  'services' => [
133  'WatchedItemStore'
134  ]
135  ],
136  'PasswordPolicies' => \SpecialPasswordPolicies::class,
137 
138  // Recent changes and logs
139  'Newimages' => \SpecialNewFiles::class,
140  'Log' => \SpecialLog::class,
141  'Watchlist' => \SpecialWatchlist::class,
142  'Newpages' => \SpecialNewpages::class,
143  'Recentchanges' => \SpecialRecentChanges::class,
144  'Recentchangeslinked' => \SpecialRecentChangesLinked::class,
145  'Tags' => \SpecialTags::class,
146 
147  // Media reports and uploads
148  'Listfiles' => \SpecialListFiles::class,
149  'Filepath' => \SpecialFilepath::class,
150  'MediaStatistics' => \SpecialMediaStatistics::class,
151  'MIMEsearch' => \SpecialMIMESearch::class,
152  'FileDuplicateSearch' => \SpecialFileDuplicateSearch::class,
153  'Upload' => \SpecialUpload::class,
154  'UploadStash' => \SpecialUploadStash::class,
155  'ListDuplicatedFiles' => \SpecialListDuplicatedFiles::class,
156 
157  // Data and tools
158  'ApiSandbox' => \SpecialApiSandbox::class,
159  'Statistics' => \SpecialStatistics::class,
160  'Allmessages' => \SpecialAllMessages::class,
161  'Version' => \SpecialVersion::class,
162  'Lockdb' => \SpecialLockdb::class,
163  'Unlockdb' => \SpecialUnlockdb::class,
164 
165  // Redirecting special pages
166  'LinkSearch' => \SpecialLinkSearch::class,
167  'Randompage' => \RandomPage::class,
168  'RandomInCategory' => \SpecialRandomInCategory::class,
169  'Randomredirect' => \SpecialRandomredirect::class,
170  'Randomrootpage' => \SpecialRandomrootpage::class,
171  'GoToInterwiki' => \SpecialGoToInterwiki::class,
172 
173  // High use pages
174  'Mostlinkedcategories' => \SpecialMostLinkedCategories::class,
175  'Mostimages' => \MostimagesPage::class,
176  'Mostinterwikis' => \SpecialMostInterwikis::class,
177  'Mostlinked' => \SpecialMostLinked::class,
178  'Mostlinkedtemplates' => \SpecialMostLinkedTemplates::class,
179  'Mostcategories' => \SpecialMostCategories::class,
180  'Mostrevisions' => \SpecialMostRevisions::class,
181 
182  // Page tools
183  'ComparePages' => \SpecialComparePages::class,
184  'Export' => \SpecialExport::class,
185  'Import' => \SpecialImport::class,
186  'Undelete' => \SpecialUndelete::class,
187  'Whatlinkshere' => \SpecialWhatLinksHere::class,
188  'MergeHistory' => \SpecialMergeHistory::class,
189  'ExpandTemplates' => \SpecialExpandTemplates::class,
190 
191  // Other
192  'Booksources' => \SpecialBookSources::class,
193 
194  // Unlisted / redirects
195  'ApiHelp' => \SpecialApiHelp::class,
196  'Blankpage' => \SpecialBlankpage::class,
197  'Diff' => \SpecialDiff::class,
198  'EditPage' => \SpecialEditPage::class,
199  'EditTags' => [
200  'class' => \SpecialEditTags::class,
201  'services' => [
202  'PermissionManager',
203  ],
204  ],
205  'Emailuser' => \SpecialEmailUser::class,
206  'Movepage' => \MovePageForm::class,
207  'Mycontributions' => \SpecialMycontributions::class,
208  'MyLanguage' => \SpecialMyLanguage::class,
209  'Mypage' => \SpecialMypage::class,
210  'Mytalk' => \SpecialMytalk::class,
211  'PageHistory' => \SpecialPageHistory::class,
212  'PageInfo' => \SpecialPageInfo::class,
213  'Purge' => \SpecialPurge::class,
214  'Myuploads' => \SpecialMyuploads::class,
215  'AllMyUploads' => \SpecialAllMyUploads::class,
216  'NewSection' => \SpecialNewSection::class,
217  'PermanentLink' => \SpecialPermanentLink::class,
218  'Redirect' => \SpecialRedirect::class,
219  'Revisiondelete' => [
220  'class' => \SpecialRevisionDelete::class,
221  'services' => [
222  'PermissionManager',
223  ],
224  ],
225  'RunJobs' => \SpecialRunJobs::class,
226  'Specialpages' => \SpecialSpecialpages::class,
227  'PageData' => \SpecialPageData::class,
228  ];
229 
231  private $list;
232 
234  private $aliases;
235 
237  private $options;
238 
240  private $contLang;
241 
243  private $objectFactory;
244 
249  public const CONSTRUCTOR_OPTIONS = [
250  'ContentHandlerUseDB',
251  'DisableInternalSearch',
252  'EmailAuthentication',
253  'EnableEmail',
254  'EnableJavaScriptTest',
255  'EnableSpecialMute',
256  'PageLanguageUseDB',
257  'SpecialPages',
258  ];
259 
265  public function __construct(
268  ObjectFactory $objectFactory
269  ) {
270  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
271  $this->options = $options;
272  $this->contLang = $contLang;
273  $this->objectFactory = $objectFactory;
274  }
275 
282  public function getNames() : array {
283  return array_keys( $this->getPageList() );
284  }
285 
291  private function getPageList() : array {
292  if ( !is_array( $this->list ) ) {
293  $this->list = self::CORE_LIST;
294 
295  if ( !$this->options->get( 'DisableInternalSearch' ) ) {
296  $this->list['Search'] = \SpecialSearch::class;
297  }
298 
299  if ( $this->options->get( 'EmailAuthentication' ) ) {
300  $this->list['Confirmemail'] = \SpecialConfirmEmail::class;
301  $this->list['Invalidateemail'] = \SpecialEmailInvalidate::class;
302  }
303 
304  if ( $this->options->get( 'EnableEmail' ) ) {
305  $this->list['ChangeEmail'] = \SpecialChangeEmail::class;
306  }
307 
308  if ( $this->options->get( 'EnableJavaScriptTest' ) ) {
309  $this->list['JavaScriptTest'] = \SpecialJavaScriptTest::class;
310  }
311 
312  if ( $this->options->get( 'EnableSpecialMute' ) ) {
313  $this->list['Mute'] = \SpecialMute::class;
314  }
315 
316  if ( $this->options->get( 'PageLanguageUseDB' ) ) {
317  $this->list['PageLanguage'] = \SpecialPageLanguage::class;
318  }
319 
320  if ( $this->options->get( 'ContentHandlerUseDB' ) ) {
321  $this->list['ChangeContentModel'] = [
322  'class' => \SpecialChangeContentModel::class,
323  'services' => [
324  'ContentHandlerFactory',
325  ],
326  ];
327  }
328 
329  // Add extension special pages
330  $this->list = array_merge( $this->list, $this->options->get( 'SpecialPages' ) );
331 
332  // This hook can be used to disable unwanted core special pages
333  // or conditionally register special pages.
334  Hooks::run( 'SpecialPage_initList', [ &$this->list ] );
335 
336  }
337 
338  return $this->list;
339  }
340 
347  private function getAliasList() : array {
348  if ( $this->aliases === null ) {
349  $aliases = $this->contLang->getSpecialPageAliases();
350  $pageList = $this->getPageList();
351 
352  $this->aliases = [];
353  $keepAlias = [];
354 
355  // Force every canonical name to be an alias for itself.
356  foreach ( $pageList as $name => $stuff ) {
357  $caseFoldedAlias = $this->contLang->caseFold( $name );
358  $this->aliases[$caseFoldedAlias] = $name;
359  $keepAlias[$caseFoldedAlias] = 'canonical';
360  }
361 
362  // Check for $aliases being an array since Language::getSpecialPageAliases can return null
363  if ( is_array( $aliases ) ) {
364  foreach ( $aliases as $realName => $aliasList ) {
365  $aliasList = array_values( $aliasList );
366  foreach ( $aliasList as $i => $alias ) {
367  $caseFoldedAlias = $this->contLang->caseFold( $alias );
368 
369  if ( isset( $this->aliases[$caseFoldedAlias] ) &&
370  $realName === $this->aliases[$caseFoldedAlias]
371  ) {
372  // Ignore same-realName conflicts
373  continue;
374  }
375 
376  if ( !isset( $keepAlias[$caseFoldedAlias] ) ) {
377  $this->aliases[$caseFoldedAlias] = $realName;
378  if ( !$i ) {
379  $keepAlias[$caseFoldedAlias] = 'first';
380  }
381  } elseif ( !$i ) {
382  wfWarn( "First alias '$alias' for $realName conflicts with " .
383  "{$keepAlias[$caseFoldedAlias]} alias for " .
384  $this->aliases[$caseFoldedAlias]
385  );
386  }
387  }
388  }
389  }
390  }
391 
392  return $this->aliases;
393  }
394 
403  public function resolveAlias( $alias ) {
404  $bits = explode( '/', $alias, 2 );
405 
406  $caseFoldedAlias = $this->contLang->caseFold( $bits[0] );
407  $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
408  $aliases = $this->getAliasList();
409  if ( !isset( $aliases[$caseFoldedAlias] ) ) {
410  return [ null, null ];
411  }
412  $name = $aliases[$caseFoldedAlias];
413  $par = $bits[1] ?? null; // T4087
414 
415  return [ $name, $par ];
416  }
417 
424  public function exists( $name ) {
425  list( $title, /*...*/ ) = $this->resolveAlias( $name );
426 
427  $specialPageList = $this->getPageList();
428  return isset( $specialPageList[$title] );
429  }
430 
437  public function getPage( $name ) {
438  list( $realName, /*...*/ ) = $this->resolveAlias( $name );
439 
440  $specialPageList = $this->getPageList();
441 
442  if ( isset( $specialPageList[$realName] ) ) {
443  $rec = $specialPageList[$realName];
444 
445  if ( $rec instanceof SpecialPage ) {
446  wfDeprecated(
447  "a SpecialPage instance (for $realName) in " .
448  '$wgSpecialPages or from the SpecialPage_initList hook',
449  '1.34'
450  );
451 
452  $page = $rec; // XXX: we should deep clone here
453  } elseif ( is_array( $rec ) || is_string( $rec ) || is_callable( $rec ) ) {
454  $page = $this->objectFactory->createObject(
455  $rec,
456  [
457  'allowClassName' => true,
458  'allowCallable' => true
459  ]
460  );
461  } else {
462  $page = null;
463  }
464 
465  if ( $page instanceof SpecialPage ) {
466  return $page;
467  }
468 
469  // It's not a classname, nor a callback, nor a legacy constructor array,
470  // nor a special page object. Give up.
471  wfLogWarning( "Cannot instantiate special page $realName: bad spec!" );
472  }
473 
474  return null;
475  }
476 
485  public function getUsablePages( User $user ) : array {
486  $pages = [];
487  foreach ( $this->getPageList() as $name => $rec ) {
488  $page = $this->getPage( $name );
489  if ( $page ) { // not null
490  $page->setContext( RequestContext::getMain() );
491  if ( $page->isListed()
492  && ( !$page->isRestricted() || $page->userCanExecute( $user ) )
493  ) {
494  $pages[$name] = $page;
495  }
496  }
497  }
498 
499  return $pages;
500  }
501 
507  public function getRegularPages() : array {
508  $pages = [];
509  foreach ( $this->getPageList() as $name => $rec ) {
510  $page = $this->getPage( $name );
511  if ( $page && $page->isListed() && !$page->isRestricted() ) {
512  $pages[$name] = $page;
513  }
514  }
515 
516  return $pages;
517  }
518 
526  public function getRestrictedPages( User $user ) : array {
527  $pages = [];
528  foreach ( $this->getPageList() as $name => $rec ) {
529  $page = $this->getPage( $name );
530  if ( $page
531  && $page->isListed()
532  && $page->isRestricted()
533  && $page->userCanExecute( $user )
534  ) {
535  $pages[$name] = $page;
536  }
537  }
538 
539  return $pages;
540  }
541 
557  public function executePath( Title &$title, IContextSource &$context, $including = false,
558  LinkRenderer $linkRenderer = null
559  ) {
560  // @todo FIXME: Redirects broken due to this call
561  $bits = explode( '/', $title->getDBkey(), 2 );
562  $name = $bits[0];
563  $par = $bits[1] ?? null; // T4087
564 
565  $page = $this->getPage( $name );
566  if ( !$page ) {
567  $context->getOutput()->setArticleRelated( false );
568  $context->getOutput()->setRobotPolicy( 'noindex,nofollow' );
569 
570  global $wgSend404Code;
571  if ( $wgSend404Code ) {
572  $context->getOutput()->setStatusCode( 404 );
573  }
574 
575  $context->getOutput()->showErrorPage( 'nosuchspecialpage', 'nospecialpagetext' );
576 
577  return false;
578  }
579 
580  if ( !$including ) {
581  // Narrow DB query expectations for this HTTP request
582  $trxLimits = $context->getConfig()->get( 'TrxProfilerLimits' );
583  $trxProfiler = Profiler::instance()->getTransactionProfiler();
584  if ( $context->getRequest()->wasPosted() && !$page->doesWrites() ) {
585  $trxProfiler->setExpectations( $trxLimits['POST-nonwrite'], __METHOD__ );
586  $context->getRequest()->markAsSafeRequest();
587  }
588  }
589 
590  // Page exists, set the context
591  $page->setContext( $context );
592 
593  if ( !$including ) {
594  // Redirect to canonical alias for GET commands
595  // Not for POST, we'd lose the post data, so it's best to just distribute
596  // the request. Such POST requests are possible for old extensions that
597  // generate self-links without being aware that their default name has
598  // changed.
599  if ( $name != $page->getLocalName() && !$context->getRequest()->wasPosted() ) {
600  $query = $context->getRequest()->getQueryValues();
601  unset( $query['title'] );
602  $title = $page->getPageTitle( $par );
603  $url = $title->getFullURL( $query );
604  $context->getOutput()->redirect( $url );
605 
606  return $title;
607  }
608 
609  // @phan-suppress-next-line PhanUndeclaredMethod
610  $context->setTitle( $page->getPageTitle( $par ) );
611  } elseif ( !$page->isIncludable() ) {
612  return false;
613  }
614 
615  $page->including( $including );
616  if ( $linkRenderer ) {
617  $page->setLinkRenderer( $linkRenderer );
618  }
619 
620  // Execute special page
621  $page->run( $par );
622 
623  return true;
624  }
625 
641  public function capturePath(
642  Title $title, IContextSource $context, LinkRenderer $linkRenderer = null
643  ) {
644  global $wgTitle, $wgOut, $wgRequest, $wgUser, $wgLang;
645  $main = RequestContext::getMain();
646 
647  // Save current globals and main context
648  $glob = [
649  'title' => $wgTitle,
650  'output' => $wgOut,
651  'request' => $wgRequest,
652  'user' => $wgUser,
653  'language' => $wgLang,
654  ];
655  $ctx = [
656  'title' => $main->getTitle(),
657  'output' => $main->getOutput(),
658  'request' => $main->getRequest(),
659  'user' => $main->getUser(),
660  'language' => $main->getLanguage(),
661  ];
662  if ( $main->canUseWikiPage() ) {
663  $ctx['wikipage'] = $main->getWikiPage();
664  }
665 
666  // Override
667  $wgTitle = $title;
670  $wgUser = $context->getUser();
672  $main->setTitle( $title );
673  $main->setOutput( $context->getOutput() );
674  $main->setRequest( $context->getRequest() );
675  $main->setUser( $context->getUser() );
676  $main->setLanguage( $context->getLanguage() );
677 
678  // The useful part
679  $ret = $this->executePath( $title, $context, true, $linkRenderer );
680 
681  // Restore old globals and context
682  $wgTitle = $glob['title'];
683  $wgOut = $glob['output'];
684  $wgRequest = $glob['request'];
685  $wgUser = $glob['user'];
686  $wgLang = $glob['language'];
687  $main->setTitle( $ctx['title'] );
688  $main->setOutput( $ctx['output'] );
689  $main->setRequest( $ctx['request'] );
690  $main->setUser( $ctx['user'] );
691  $main->setLanguage( $ctx['language'] );
692  if ( isset( $ctx['wikipage'] ) ) {
693  $main->setWikiPage( $ctx['wikipage'] );
694  }
695 
696  return $ret;
697  }
698 
706  public function getLocalNameFor( $name, $subpage = false ) {
707  $aliases = $this->contLang->getSpecialPageAliases();
708  $aliasList = $this->getAliasList();
709 
710  // Find the first alias that maps back to $name
711  if ( isset( $aliases[$name] ) ) {
712  $found = false;
713  foreach ( $aliases[$name] as $alias ) {
714  $caseFoldedAlias = $this->contLang->caseFold( $alias );
715  $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
716  if ( isset( $aliasList[$caseFoldedAlias] ) &&
717  $aliasList[$caseFoldedAlias] === $name
718  ) {
719  $name = $alias;
720  $found = true;
721  break;
722  }
723  }
724  if ( !$found ) {
725  wfWarn( "Did not find a usable alias for special page '$name'. " .
726  "It seems all defined aliases conflict?" );
727  }
728  } else {
729  // Check if someone misspelled the correct casing
730  if ( is_array( $aliases ) ) {
731  foreach ( $aliases as $n => $values ) {
732  if ( strcasecmp( $name, $n ) === 0 ) {
733  wfWarn( "Found alias defined for $n when searching for " .
734  "special page aliases for $name. Case mismatch?" );
735  return $this->getLocalNameFor( $n, $subpage );
736  }
737  }
738  }
739 
740  wfWarn( "Did not find alias for special page '$name'. " .
741  "Perhaps no aliases are defined for it?" );
742  }
743 
744  if ( $subpage !== false && $subpage !== null ) {
745  // Make sure it's in dbkey form
746  $subpage = str_replace( ' ', '_', $subpage );
747  $name = "$name/$subpage";
748  }
749 
750  return $this->contLang->ucfirst( $name );
751  }
752 
759  public function getTitleForAlias( $alias ) {
760  list( $name, $subpage ) = $this->resolveAlias( $alias );
761  if ( $name != null ) {
762  return SpecialPage::getTitleFor( $name, $subpage );
763  }
764 
765  return null;
766  }
767 }
768 
770 class_alias( SpecialPageFactory::class, 'MediaWiki\\Special\\SpecialPageFactory' );
$wgSend404Code
$wgSend404Code
Some web hosts attempt to rewrite all responses with a 404 (not found) status code,...
Definition: DefaultSettings.php:3542
MediaWiki\SpecialPage\SpecialPageFactory\executePath
executePath(Title &$title, IContextSource &$context, $including=false, LinkRenderer $linkRenderer=null)
Execute a special page path.
Definition: SpecialPageFactory.php:557
MediaWiki\SpecialPage\SpecialPageFactory\getUsablePages
getUsablePages(User $user)
Return categorised listable special pages which are available for the current user,...
Definition: SpecialPageFactory.php:485
MediaWiki\SpecialPage\SpecialPageFactory\$options
ServiceOptions $options
Definition: SpecialPageFactory.php:237
Profiler\instance
static instance()
Singleton.
Definition: Profiler.php:63
MediaWiki\SpecialPage\SpecialPageFactory\CORE_LIST
const CORE_LIST
List of special page names to the subclass of SpecialPage which handles them.
Definition: SpecialPageFactory.php:68
MediaWiki\Linker\LinkRenderer
Class that generates HTML links for pages.
Definition: LinkRenderer.php:41
MediaWiki\SpecialPage\SpecialPageFactory
Factory for handling the special page list and generating SpecialPage objects.
Definition: SpecialPageFactory.php:64
MediaWiki\SpecialPage\SpecialPageFactory\resolveAlias
resolveAlias( $alias)
Given a special page name with a possible subpage, return an array where the first element is the spe...
Definition: SpecialPageFactory.php:403
MediaWiki\SpecialPage\SpecialPageFactory\getRestrictedPages
getRestrictedPages(User $user)
Return categorised listable special pages which are available for the current user,...
Definition: SpecialPageFactory.php:526
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:83
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1079
$wgTitle
if(isset( $_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] !='') $wgTitle
Definition: api.php:59
MediaWiki\SpecialPage\SpecialPageFactory\getLocalNameFor
getLocalNameFor( $name, $subpage=false)
Get the local name for a specified canonical name.
Definition: SpecialPageFactory.php:706
MediaWiki\SpecialPage\SpecialPageFactory\$list
array $list
Special page name => class name.
Definition: SpecialPageFactory.php:231
MediaWiki\SpecialPage\SpecialPageFactory\$contLang
Language $contLang
Definition: SpecialPageFactory.php:240
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:25
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Definition: GlobalFunctions.php:1045
Profiler
Profiler base class that defines the interface and some shared functionality.
Definition: Profiler.php:33
$wgLang
$wgLang
Definition: Setup.php:852
$title
$title
Definition: testCompression.php:36
RequestContext
Group all the pieces relevant to the context of a request into one instance.
Definition: RequestContext.php:34
MediaWiki\SpecialPage\SpecialPageFactory\getNames
getNames()
Returns a list of canonical special page names.
Definition: SpecialPageFactory.php:282
MediaWiki\SpecialPage\SpecialPageFactory\exists
exists( $name)
Check if a given name exist as a special page or as a special page alias.
Definition: SpecialPageFactory.php:424
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:37
MediaWiki\SpecialPage\SpecialPageFactory\getRegularPages
getRegularPages()
Return categorised listable special pages for all users.
Definition: SpecialPageFactory.php:507
MediaWiki\SpecialPage\SpecialPageFactory\$objectFactory
ObjectFactory $objectFactory
Definition: SpecialPageFactory.php:243
IContextSource\getUser
getUser()
MediaWiki\SpecialPage\SpecialPageFactory\getPage
getPage( $name)
Find the object with a given name and return it (or NULL)
Definition: SpecialPageFactory.php:437
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:451
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:53
Title
Represents a title within MediaWiki.
Definition: Title.php:42
MediaWiki\SpecialPage\SpecialPageFactory\capturePath
capturePath(Title $title, IContextSource $context, LinkRenderer $linkRenderer=null)
Just like executePath() but will override global variables and execute the page in "inclusion" mode.
Definition: SpecialPageFactory.php:641
IContextSource\getConfig
getConfig()
Get the site configuration.
IContextSource\getRequest
getRequest()
wfWarn
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
Definition: GlobalFunctions.php:1066
MediaWiki\SpecialPage\SpecialPageFactory\__construct
__construct(ServiceOptions $options, Language $contLang, ObjectFactory $objectFactory)
Definition: SpecialPageFactory.php:265
MediaWiki\SpecialPage\SpecialPageFactory\getTitleForAlias
getTitleForAlias( $alias)
Get a title for a given alias.
Definition: SpecialPageFactory.php:759
$wgRequest
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:719
MediaWiki\$context
IContextSource $context
Definition: MediaWiki.php:37
$wgOut
$wgOut
Definition: Setup.php:857
MediaWiki\SpecialPage\SpecialPageFactory\$aliases
array $aliases
Definition: SpecialPageFactory.php:234
MediaWiki\SpecialPage\SpecialPageFactory\getAliasList
getAliasList()
Initialise and return the list of special page aliases.
Definition: SpecialPageFactory.php:347
MediaWiki\SpecialPage\SpecialPageFactory\getPageList
getPageList()
Get the special page list as an array.
Definition: SpecialPageFactory.php:291
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:52
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
MediaWiki\SpecialPage
Definition: SpecialPageFactory.php:25
IContextSource\getOutput
getOutput()
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:39
Hooks
Hooks class.
Definition: Hooks.php:34
IContextSource\getLanguage
getLanguage()
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:62