MediaWiki 1.43.1
ApiQuerySiteinfo.php
Go to the documentation of this file.
1<?php
23namespace MediaWiki\Api;
24
51use Skin;
52use SkinFactory;
53use UploadBase;
58
65
66 private UserOptionsLookup $userOptionsLookup;
67 private UserGroupManager $userGroupManager;
68 private LanguageConverterFactory $languageConverterFactory;
69 private LanguageFactory $languageFactory;
70 private LanguageNameUtils $languageNameUtils;
71 private Language $contentLanguage;
72 private NamespaceInfo $namespaceInfo;
73 private InterwikiLookup $interwikiLookup;
74 private ParserFactory $parserFactory;
75 private MagicWordFactory $magicWordFactory;
76 private SpecialPageFactory $specialPageFactory;
77 private SkinFactory $skinFactory;
78 private ILoadBalancer $loadBalancer;
79 private ReadOnlyMode $readOnlyMode;
80 private UrlUtils $urlUtils;
81 private TempUserConfig $tempUserConfig;
82
83 public function __construct(
84 ApiQuery $query,
85 string $moduleName,
86 UserOptionsLookup $userOptionsLookup,
87 UserGroupManager $userGroupManager,
88 LanguageConverterFactory $languageConverterFactory,
89 LanguageFactory $languageFactory,
90 LanguageNameUtils $languageNameUtils,
91 Language $contentLanguage,
92 NamespaceInfo $namespaceInfo,
93 InterwikiLookup $interwikiLookup,
94 ParserFactory $parserFactory,
95 MagicWordFactory $magicWordFactory,
96 SpecialPageFactory $specialPageFactory,
97 SkinFactory $skinFactory,
98 ILoadBalancer $loadBalancer,
99 ReadOnlyMode $readOnlyMode,
100 UrlUtils $urlUtils,
101 TempUserConfig $tempUserConfig
102 ) {
103 parent::__construct( $query, $moduleName, 'si' );
104 $this->userOptionsLookup = $userOptionsLookup;
105 $this->userGroupManager = $userGroupManager;
106 $this->languageConverterFactory = $languageConverterFactory;
107 $this->languageFactory = $languageFactory;
108 $this->languageNameUtils = $languageNameUtils;
109 $this->contentLanguage = $contentLanguage;
110 $this->namespaceInfo = $namespaceInfo;
111 $this->interwikiLookup = $interwikiLookup;
112 $this->parserFactory = $parserFactory;
113 $this->magicWordFactory = $magicWordFactory;
114 $this->specialPageFactory = $specialPageFactory;
115 $this->skinFactory = $skinFactory;
116 $this->loadBalancer = $loadBalancer;
117 $this->readOnlyMode = $readOnlyMode;
118 $this->urlUtils = $urlUtils;
119 $this->tempUserConfig = $tempUserConfig;
120 }
121
122 public function execute() {
123 $params = $this->extractRequestParams();
124 $done = [];
125 foreach ( $params['prop'] as $p ) {
126 switch ( $p ) {
127 case 'general':
128 $fit = $this->appendGeneralInfo( $p );
129 break;
130 case 'namespaces':
131 $fit = $this->appendNamespaces( $p );
132 break;
133 case 'namespacealiases':
134 $fit = $this->appendNamespaceAliases( $p );
135 break;
136 case 'specialpagealiases':
137 $fit = $this->appendSpecialPageAliases( $p );
138 break;
139 case 'magicwords':
140 $fit = $this->appendMagicWords( $p );
141 break;
142 case 'interwikimap':
143 $fit = $this->appendInterwikiMap( $p, $params['filteriw'] );
144 break;
145 case 'dbrepllag':
146 $fit = $this->appendDbReplLagInfo( $p, $params['showalldb'] );
147 break;
148 case 'statistics':
149 $fit = $this->appendStatistics( $p );
150 break;
151 case 'usergroups':
152 $fit = $this->appendUserGroups( $p, $params['numberingroup'] );
153 break;
154 case 'autocreatetempuser':
155 $fit = $this->appendAutoCreateTempUser( $p );
156 break;
157 case 'clientlibraries':
158 $fit = $this->appendInstalledClientLibraries( $p );
159 break;
160 case 'libraries':
161 $fit = $this->appendInstalledLibraries( $p );
162 break;
163 case 'extensions':
164 $fit = $this->appendExtensions( $p );
165 break;
166 case 'fileextensions':
167 $fit = $this->appendFileExtensions( $p );
168 break;
169 case 'rightsinfo':
170 $fit = $this->appendRightsInfo( $p );
171 break;
172 case 'restrictions':
173 $fit = $this->appendRestrictions( $p );
174 break;
175 case 'languages':
176 $fit = $this->appendLanguages( $p );
177 break;
178 case 'languagevariants':
179 $fit = $this->appendLanguageVariants( $p );
180 break;
181 case 'skins':
182 $fit = $this->appendSkins( $p );
183 break;
184 case 'extensiontags':
185 $fit = $this->appendExtensionTags( $p );
186 break;
187 case 'functionhooks':
188 $fit = $this->appendFunctionHooks( $p );
189 break;
190 case 'showhooks':
191 $fit = $this->appendSubscribedHooks( $p );
192 break;
193 case 'variables':
194 $fit = $this->appendVariables( $p );
195 break;
196 case 'protocols':
197 $fit = $this->appendProtocols( $p );
198 break;
199 case 'defaultoptions':
200 $fit = $this->appendDefaultOptions( $p );
201 break;
202 case 'uploaddialog':
203 $fit = $this->appendUploadDialog( $p );
204 break;
205 case 'autopromote':
206 $fit = $this->appendAutoPromote( $p );
207 break;
208 case 'autopromoteonce':
209 $fit = $this->appendAutoPromoteOnce( $p );
210 break;
211 default:
212 ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" ); // @codeCoverageIgnore
213 }
214 if ( !$fit ) {
215 // Abuse siprop as a query-continue parameter
216 // and set it to all unprocessed props
217 $this->setContinueEnumParameter( 'prop', implode( '|',
218 array_diff( $params['prop'], $done ) ) );
219 break;
220 }
221 $done[] = $p;
222 }
223 }
224
225 protected function appendGeneralInfo( $property ) {
226 $config = $this->getConfig();
227 $mainPage = Title::newMainPage();
228 $logo = SkinModule::getAvailableLogos( $config, $this->getLanguage()->getCode() );
229
230 $data = [
231 'mainpage' => $mainPage->getPrefixedText(),
232 'base' => (string)$this->urlUtils->expand( $mainPage->getFullURL(), PROTO_CURRENT ),
233 'sitename' => $config->get( MainConfigNames::Sitename ),
234 'mainpageisdomainroot' => (bool)$config->get( MainConfigNames::MainPageIsDomainRoot ),
235
236 // A logo can either be a relative or an absolute path
237 // make sure we always return an absolute path
238 'logo' => (string)$this->urlUtils->expand( $logo['1x'], PROTO_RELATIVE ),
239
240 'generator' => 'MediaWiki ' . MW_VERSION,
241
242 'phpversion' => PHP_VERSION,
243 'phpsapi' => PHP_SAPI,
244 'dbtype' => $config->get( MainConfigNames::DBtype ),
245 'dbversion' => $this->getDB()->getServerVersion(),
246 ];
247
248 $allowFrom = [ '' ];
249 $allowException = true;
250 if ( !$config->get( MainConfigNames::AllowExternalImages ) ) {
251 $data['imagewhitelistenabled'] =
252 (bool)$config->get( MainConfigNames::EnableImageWhitelist );
253 $allowFrom = $config->get( MainConfigNames::AllowExternalImagesFrom );
254 $allowException = (bool)$allowFrom;
255 }
256 if ( $allowException ) {
257 $data['externalimages'] = (array)$allowFrom;
258 ApiResult::setIndexedTagName( $data['externalimages'], 'prefix' );
259 }
260
261 $data['langconversion'] = !$this->languageConverterFactory->isConversionDisabled();
262 $data['linkconversion'] = !$this->languageConverterFactory->isLinkConversionDisabled();
263 // For backwards compatibility (soft deprecated since MW 1.36)
264 $data['titleconversion'] = $data['linkconversion'];
265
266 $contLangConverter = $this->languageConverterFactory->getLanguageConverter( $this->contentLanguage );
267 if ( $this->contentLanguage->linkPrefixExtension() ) {
268 $linkPrefixCharset = $this->contentLanguage->linkPrefixCharset();
269 $data['linkprefixcharset'] = $linkPrefixCharset;
270 // For backwards compatibility
271 $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
272 } else {
273 $data['linkprefixcharset'] = '';
274 $data['linkprefix'] = '';
275 }
276
277 $data['linktrail'] = $this->contentLanguage->linkTrail() ?: '';
278
279 $data['legaltitlechars'] = Title::legalChars();
280 $data['invalidusernamechars'] = $config->get( MainConfigNames::InvalidUsernameCharacters );
281
282 $data['allunicodefixes'] = (bool)$config->get( MainConfigNames::AllUnicodeFixes );
283 $data['fixarabicunicode'] = true; // Config removed in 1.35, always true
284 $data['fixmalayalamunicode'] = true; // Config removed in 1.35, always true
285
286 $git = GitInfo::repo()->getHeadSHA1();
287 if ( $git ) {
288 $data['git-hash'] = $git;
289 $data['git-branch'] = GitInfo::repo()->getCurrentBranch();
290 }
291
292 // 'case-insensitive' option is reserved for future
293 $data['case'] =
294 $config->get( MainConfigNames::CapitalLinks ) ? 'first-letter' : 'case-sensitive';
295 $data['lang'] = $config->get( MainConfigNames::LanguageCode );
296
297 $data['fallback'] = [];
298 foreach ( $this->contentLanguage->getFallbackLanguages() as $code ) {
299 $data['fallback'][] = [ 'code' => $code ];
300 }
301 ApiResult::setIndexedTagName( $data['fallback'], 'lang' );
302
303 if ( $contLangConverter->hasVariants() ) {
304 $data['variants'] = [];
305 foreach ( $contLangConverter->getVariants() as $code ) {
306 $data['variants'][] = [
307 'code' => $code,
308 'name' => $this->contentLanguage->getVariantname( $code ),
309 ];
310 }
311 ApiResult::setIndexedTagName( $data['variants'], 'lang' );
312 }
313
314 $data['rtl'] = $this->contentLanguage->isRTL();
315 $data['fallback8bitEncoding'] = $this->contentLanguage->fallback8bitEncoding();
316
317 $data['readonly'] = $this->readOnlyMode->isReadOnly();
318 if ( $data['readonly'] ) {
319 $data['readonlyreason'] = $this->readOnlyMode->getReason();
320 }
321 $data['writeapi'] = true; // Deprecated since MW 1.32
322
323 $data['maxarticlesize'] = $config->get( MainConfigNames::MaxArticleSize ) * 1024;
324
325 $data['timezone'] = $config->get( MainConfigNames::Localtimezone );
326 $data['timeoffset'] = (int)( $config->get( MainConfigNames::LocalTZoffset ) );
327 $data['articlepath'] = $config->get( MainConfigNames::ArticlePath );
328 $data['scriptpath'] = $config->get( MainConfigNames::ScriptPath );
329 $data['script'] = $config->get( MainConfigNames::Script );
330 $data['variantarticlepath'] = $config->get( MainConfigNames::VariantArticlePath );
331 $data[ApiResult::META_BC_BOOLS][] = 'variantarticlepath';
332 $data['server'] = $config->get( MainConfigNames::Server );
333 $data['servername'] = $config->get( MainConfigNames::ServerName );
334 $data['wikiid'] = WikiMap::getCurrentWikiId();
335 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
336
337 $data['misermode'] = (bool)$config->get( MainConfigNames::MiserMode );
338
339 $data['uploadsenabled'] = UploadBase::isEnabled();
340 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
341 $data['minuploadchunksize'] = ApiUpload::getMinUploadChunkSize( $config );
342
343 $data['galleryoptions'] = $config->get( MainConfigNames::GalleryOptions );
344
345 $data['thumblimits'] = $config->get( MainConfigNames::ThumbLimits );
346 ApiResult::setArrayType( $data['thumblimits'], 'BCassoc' );
347 ApiResult::setIndexedTagName( $data['thumblimits'], 'limit' );
348 $data['imagelimits'] = [];
349 foreach ( $config->get( MainConfigNames::ImageLimits ) as $k => $limit ) {
350 $data['imagelimits'][$k] = [ 'width' => $limit[0], 'height' => $limit[1] ];
351 }
352 ApiResult::setArrayType( $data['imagelimits'], 'BCassoc' );
353 ApiResult::setIndexedTagName( $data['imagelimits'], 'limit' );
354
355 $favicon = $config->get( MainConfigNames::Favicon );
356 if ( $favicon ) {
357 // Expand any local path to full URL to improve API usability (T77093).
358 $data['favicon'] = (string)$this->urlUtils->expand( $favicon );
359 }
360
361 $data['centralidlookupprovider'] = $config->get( MainConfigNames::CentralIdLookupProvider );
362 $providerIds = array_keys( $config->get( MainConfigNames::CentralIdLookupProviders ) );
363 $data['allcentralidlookupproviders'] = $providerIds;
364
365 $data['interwikimagic'] = (bool)$config->get( MainConfigNames::InterwikiMagic );
366 $data['magiclinks'] = $config->get( MainConfigNames::EnableMagicLinks );
367
368 $data['categorycollation'] = $config->get( MainConfigNames::CategoryCollation );
369
370 $data['nofollowlinks'] = $config->get( MainConfigNames::NoFollowLinks );
371 $data['nofollownsexceptions'] = $config->get( MainConfigNames::NoFollowNsExceptions );
372 $data['nofollowdomainexceptions'] = $config->get( MainConfigNames::NoFollowDomainExceptions );
373 $data['externallinktarget'] = $config->get( MainConfigNames::ExternalLinkTarget );
374
375 $this->getHookRunner()->onAPIQuerySiteInfoGeneralInfo( $this, $data );
376
377 return $this->getResult()->addValue( 'query', $property, $data );
378 }
379
380 protected function appendNamespaces( $property ) {
381 $nsProtection = $this->getConfig()->get( MainConfigNames::NamespaceProtection );
382
383 $data = [ ApiResult::META_TYPE => 'assoc' ];
384 foreach ( $this->contentLanguage->getFormattedNamespaces() as $ns => $title ) {
385 $data[$ns] = [
386 'id' => (int)$ns,
387 'case' => $this->namespaceInfo->isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
388 ];
389 ApiResult::setContentValue( $data[$ns], 'name', $title );
390 $canonical = $this->namespaceInfo->getCanonicalName( $ns );
391
392 $data[$ns]['subpages'] = $this->namespaceInfo->hasSubpages( $ns );
393
394 if ( $canonical ) {
395 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
396 }
397
398 $data[$ns]['content'] = $this->namespaceInfo->isContent( $ns );
399 $data[$ns]['nonincludable'] = $this->namespaceInfo->isNonincludable( $ns );
400
401 $specificNs = $nsProtection[$ns] ?? '';
402 if ( is_array( $specificNs ) ) {
403 $specificNs = implode( "|", array_filter( $specificNs ) );
404 }
405 if ( $specificNs !== '' ) {
406 $data[$ns]['namespaceprotection'] = $specificNs;
407 }
408
409 $contentmodel = $this->namespaceInfo->getNamespaceContentModel( $ns );
410 if ( $contentmodel ) {
411 $data[$ns]['defaultcontentmodel'] = $contentmodel;
412 }
413 }
414
415 ApiResult::setArrayType( $data, 'assoc' );
416 ApiResult::setIndexedTagName( $data, 'ns' );
417
418 return $this->getResult()->addValue( 'query', $property, $data );
419 }
420
421 protected function appendNamespaceAliases( $property ) {
422 $aliases = $this->contentLanguage->getNamespaceAliases();
423 $namespaces = $this->contentLanguage->getNamespaces();
424 $data = [];
425 foreach ( $aliases as $title => $ns ) {
426 if ( $namespaces[$ns] == $title ) {
427 // Don't list duplicates
428 continue;
429 }
430 $item = [ 'id' => (int)$ns ];
431 ApiResult::setContentValue( $item, 'alias', strtr( $title, '_', ' ' ) );
432 $data[] = $item;
433 }
434
435 sort( $data );
436
437 ApiResult::setIndexedTagName( $data, 'ns' );
438
439 return $this->getResult()->addValue( 'query', $property, $data );
440 }
441
442 protected function appendSpecialPageAliases( $property ) {
443 $data = [];
444 $aliases = $this->contentLanguage->getSpecialPageAliases();
445 foreach ( $this->specialPageFactory->getNames() as $specialpage ) {
446 if ( isset( $aliases[$specialpage] ) ) {
447 $arr = [ 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] ];
448 ApiResult::setIndexedTagName( $arr['aliases'], 'alias' );
449 $data[] = $arr;
450 }
451 }
452 ApiResult::setIndexedTagName( $data, 'specialpage' );
453
454 return $this->getResult()->addValue( 'query', $property, $data );
455 }
456
457 protected function appendMagicWords( $property ) {
458 $data = [];
459 foreach ( $this->contentLanguage->getMagicWords() as $name => $aliases ) {
460 $caseSensitive = (bool)array_shift( $aliases );
461 $arr = [
462 'name' => $name,
463 'aliases' => $aliases,
464 'case-sensitive' => $caseSensitive,
465 ];
466 ApiResult::setIndexedTagName( $arr['aliases'], 'alias' );
467 $data[] = $arr;
468 }
469 ApiResult::setIndexedTagName( $data, 'magicword' );
470
471 return $this->getResult()->addValue( 'query', $property, $data );
472 }
473
474 protected function appendInterwikiMap( $property, $filter ) {
475 $local = $filter ? $filter === 'local' : null;
476
477 $params = $this->extractRequestParams();
478 $langCode = $params['inlanguagecode'] ?? '';
479 $interwikiMagic = $this->getConfig()->get( MainConfigNames::InterwikiMagic );
480
481 if ( $interwikiMagic ) {
482 $langNames = $this->languageNameUtils->getLanguageNames( $langCode );
483 }
484
485 $extraLangPrefixes = $this->getConfig()->get( MainConfigNames::ExtraInterlanguageLinkPrefixes );
486 $extraLangCodeMap = $this->getConfig()->get( MainConfigNames::InterlanguageLinkCodeMap );
487 $localInterwikis = $this->getConfig()->get( MainConfigNames::LocalInterwikis );
488 $data = [];
489
490 foreach ( $this->interwikiLookup->getAllPrefixes( $local ) as $row ) {
491 $prefix = $row['iw_prefix'];
492 $val = [];
493 $val['prefix'] = $prefix;
494 if ( $row['iw_local'] ?? false ) {
495 $val['local'] = true;
496 }
497 if ( $row['iw_trans'] ?? false ) {
498 $val['trans'] = true;
499 }
500
501 if ( $interwikiMagic && isset( $langNames[$prefix] ) ) {
502 $val['language'] = $langNames[$prefix];
503 $standard = LanguageCode::replaceDeprecatedCodes( $prefix );
504 if ( $standard !== $prefix ) {
505 # Note that even if this code is deprecated, it should
506 # only be remapped if extralanglink (set below) is false.
507 $val['deprecated'] = $standard;
508 }
509 $val['bcp47'] = LanguageCode::bcp47( $standard );
510 }
511 if ( in_array( $prefix, $localInterwikis ) ) {
512 $val['localinterwiki'] = true;
513 }
514 if ( $interwikiMagic && in_array( $prefix, $extraLangPrefixes ) ) {
515 $val['extralanglink'] = true;
516 $val['code'] = $extraLangCodeMap[$prefix] ?? $prefix;
517 $val['bcp47'] = LanguageCode::bcp47( $val['code'] );
518
519 $linktext = $this->msg( "interlanguage-link-$prefix" );
520 if ( !$linktext->isDisabled() ) {
521 $val['linktext'] = $linktext->text();
522 }
523
524 $sitename = $this->msg( "interlanguage-link-sitename-$prefix" );
525 if ( !$sitename->isDisabled() ) {
526 $val['sitename'] = $sitename->text();
527 }
528 }
529
530 $val['url'] = (string)$this->urlUtils->expand( $row['iw_url'], PROTO_CURRENT );
531 $val['protorel'] = str_starts_with( $row['iw_url'], '//' );
532 if ( ( $row['iw_wikiid'] ?? '' ) !== '' ) {
533 $val['wikiid'] = $row['iw_wikiid'];
534 }
535 if ( ( $row['iw_api'] ?? '' ) !== '' ) {
536 $val['api'] = $row['iw_api'];
537 }
538
539 $data[] = $val;
540 }
541
542 ApiResult::setIndexedTagName( $data, 'iw' );
543
544 return $this->getResult()->addValue( 'query', $property, $data );
545 }
546
547 protected function appendDbReplLagInfo( $property, $includeAll ) {
548 $data = [];
549 $showHostnames = $this->getConfig()->get( MainConfigNames::ShowHostnames );
550 if ( $includeAll ) {
551 if ( !$showHostnames ) {
552 $this->dieWithError( 'apierror-siteinfo-includealldenied', 'includeAllDenied' );
553 }
554
555 foreach ( $this->loadBalancer->getLagTimes() as $i => $lag ) {
556 $data[] = [
557 'host' => $this->loadBalancer->getServerName( $i ),
558 'lag' => $lag
559 ];
560 }
561 } else {
562 [ , $lag, $index ] = $this->loadBalancer->getMaxLag();
563 $data[] = [
564 'host' => $showHostnames ? $this->loadBalancer->getServerName( $index ) : '',
565 'lag' => $lag
566 ];
567 }
568
569 ApiResult::setIndexedTagName( $data, 'db' );
570
571 return $this->getResult()->addValue( 'query', $property, $data );
572 }
573
574 protected function appendStatistics( $property ) {
575 $data = [
576 'pages' => SiteStats::pages(),
577 'articles' => SiteStats::articles(),
578 'edits' => SiteStats::edits(),
579 'images' => SiteStats::images(),
580 'users' => SiteStats::users(),
581 'activeusers' => SiteStats::activeUsers(),
582 'admins' => SiteStats::numberingroup( 'sysop' ),
583 'jobs' => SiteStats::jobs(),
584 ];
585
586 $this->getHookRunner()->onAPIQuerySiteInfoStatisticsInfo( $data );
587
588 return $this->getResult()->addValue( 'query', $property, $data );
589 }
590
591 protected function appendUserGroups( $property, $numberInGroup ) {
592 $config = $this->getConfig();
593
594 $data = [];
595 $result = $this->getResult();
596 $allGroups = array_values( $this->userGroupManager->listAllGroups() );
597 foreach ( $config->get( MainConfigNames::GroupPermissions ) as $group => $permissions ) {
598 $arr = [
599 'name' => $group,
600 'rights' => array_keys( $permissions, true ),
601 ];
602
603 if ( $numberInGroup ) {
604 $autopromote = $config->get( MainConfigNames::Autopromote );
605
606 if ( $group == 'user' ) {
607 $arr['number'] = SiteStats::users();
608 // '*' and autopromote groups have no size
609 } elseif ( $group !== '*' && !isset( $autopromote[$group] ) ) {
610 $arr['number'] = SiteStats::numberingroup( $group );
611 }
612 }
613
614 $groupArr = [
615 'add' => $config->get( MainConfigNames::AddGroups ),
616 'remove' => $config->get( MainConfigNames::RemoveGroups ),
617 'add-self' => $config->get( MainConfigNames::GroupsAddToSelf ),
618 'remove-self' => $config->get( MainConfigNames::GroupsRemoveFromSelf )
619 ];
620
621 foreach ( $groupArr as $type => $rights ) {
622 if ( isset( $rights[$group] ) ) {
623 if ( $rights[$group] === true ) {
624 $groups = $allGroups;
625 } else {
626 $groups = array_intersect( $rights[$group], $allGroups );
627 }
628 if ( $groups ) {
629 $arr[$type] = $groups;
630 ApiResult::setArrayType( $arr[$type], 'BCarray' );
631 ApiResult::setIndexedTagName( $arr[$type], 'group' );
632 }
633 }
634 }
635
636 ApiResult::setIndexedTagName( $arr['rights'], 'permission' );
637 $data[] = $arr;
638 }
639
640 ApiResult::setIndexedTagName( $data, 'group' );
641
642 return $result->addValue( 'query', $property, $data );
643 }
644
645 protected function appendAutoCreateTempUser( $property ) {
646 $data = [ 'enabled' => $this->tempUserConfig->isEnabled() ];
647 if ( $this->tempUserConfig->isKnown() ) {
648 $data['matchPatterns'] = $this->tempUserConfig->getMatchPatterns();
649 }
650 return $this->getResult()->addValue( 'query', $property, $data );
651 }
652
653 protected function appendFileExtensions( $property ) {
654 $data = [];
655 foreach (
656 array_unique( $this->getConfig()->get( MainConfigNames::FileExtensions ) ) as $ext
657 ) {
658 $data[] = [ 'ext' => $ext ];
659 }
660 ApiResult::setIndexedTagName( $data, 'fe' );
661
662 return $this->getResult()->addValue( 'query', $property, $data );
663 }
664
665 protected function appendInstalledClientLibraries( $property ) {
666 $data = [];
667 foreach ( SpecialVersion::parseForeignResources() as $name => $info ) {
668 $data[] = [
669 // Can't use $name as it is version suffixed (as multiple versions
670 // of a library may exist, provided by different skins/extensions)
671 'name' => $info['name'],
672 'version' => $info['version'],
673 ];
674 }
675 ApiResult::setIndexedTagName( $data, 'library' );
676 return $this->getResult()->addValue( 'query', $property, $data );
677 }
678
679 protected function appendInstalledLibraries( $property ) {
680 $path = MW_INSTALL_PATH . '/vendor/composer/installed.json';
681 if ( !file_exists( $path ) ) {
682 return true;
683 }
684
685 $data = [];
686 $installed = new ComposerInstalled( $path );
687 foreach ( $installed->getInstalledDependencies() as $name => $info ) {
688 if ( str_starts_with( $info['type'], 'mediawiki-' ) ) {
689 // Skip any extensions or skins since they'll be listed
690 // in their proper section
691 continue;
692 }
693 $data[] = [
694 'name' => $name,
695 'version' => $info['version'],
696 ];
697 }
698 ApiResult::setIndexedTagName( $data, 'library' );
699
700 return $this->getResult()->addValue( 'query', $property, $data );
701 }
702
703 protected function appendExtensions( $property ) {
704 $data = [];
705 $credits = SpecialVersion::getCredits(
706 ExtensionRegistry::getInstance(),
707 $this->getConfig()
708 );
709 foreach ( $credits as $type => $extensions ) {
710 foreach ( $extensions as $ext ) {
711 $ret = [ 'type' => $type ];
712 if ( isset( $ext['name'] ) ) {
713 $ret['name'] = $ext['name'];
714 }
715 if ( isset( $ext['namemsg'] ) ) {
716 $ret['namemsg'] = $ext['namemsg'];
717 }
718 if ( isset( $ext['description'] ) ) {
719 $ret['description'] = $ext['description'];
720 }
721 if ( isset( $ext['descriptionmsg'] ) ) {
722 // Can be a string or [ key, param1, param2, ... ]
723 if ( is_array( $ext['descriptionmsg'] ) ) {
724 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
725 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
726 ApiResult::setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
727 } else {
728 $ret['descriptionmsg'] = $ext['descriptionmsg'];
729 }
730 }
731 if ( isset( $ext['author'] ) ) {
732 $ret['author'] = is_array( $ext['author'] ) ?
733 implode( ', ', $ext['author'] ) : $ext['author'];
734 }
735 if ( isset( $ext['url'] ) ) {
736 $ret['url'] = $ext['url'];
737 }
738 if ( isset( $ext['version'] ) ) {
739 $ret['version'] = $ext['version'];
740 }
741 if ( isset( $ext['path'] ) ) {
742 $extensionPath = dirname( $ext['path'] );
743 $gitInfo = new GitInfo( $extensionPath );
744 $vcsVersion = $gitInfo->getHeadSHA1();
745 if ( $vcsVersion !== false ) {
746 $ret['vcs-system'] = 'git';
747 $ret['vcs-version'] = $vcsVersion;
748 $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
749 $vcsDate = $gitInfo->getHeadCommitDate();
750 if ( $vcsDate !== false ) {
751 $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $vcsDate );
752 }
753 }
754
755 if ( ExtensionInfo::getLicenseFileNames( $extensionPath ) ) {
756 $ret['license-name'] = $ext['license-name'] ?? '';
757 $ret['license'] = SpecialPage::getTitleFor(
758 'Version',
759 "License/{$ext['name']}"
760 )->getLinkURL();
761 }
762
763 if ( ExtensionInfo::getAuthorsFileName( $extensionPath ) ) {
764 $ret['credits'] = SpecialPage::getTitleFor(
765 'Version',
766 "Credits/{$ext['name']}"
767 )->getLinkURL();
768 }
769 }
770 $data[] = $ret;
771 }
772 }
773
774 ApiResult::setIndexedTagName( $data, 'ext' );
775
776 return $this->getResult()->addValue( 'query', $property, $data );
777 }
778
779 protected function appendRightsInfo( $property ) {
780 $config = $this->getConfig();
781 $title = Title::newFromText( $config->get( MainConfigNames::RightsPage ) );
782 if ( $title ) {
783 $url = $this->urlUtils->expand( $title->getLinkURL(), PROTO_CURRENT );
784 } else {
785 $url = $config->get( MainConfigNames::RightsUrl );
786 }
787 $text = $config->get( MainConfigNames::RightsText ) ?? '';
788 if ( $text === '' && $title ) {
789 $text = $title->getPrefixedText();
790 }
791
792 $data = [
793 'url' => (string)$url,
794 'text' => (string)$text,
795 ];
796
797 return $this->getResult()->addValue( 'query', $property, $data );
798 }
799
800 protected function appendRestrictions( $property ) {
801 $config = $this->getConfig();
802 $data = [
803 'types' => $config->get( MainConfigNames::RestrictionTypes ),
804 'levels' => $config->get( MainConfigNames::RestrictionLevels ),
805 'cascadinglevels' => $config->get( MainConfigNames::CascadingRestrictionLevels ),
806 'semiprotectedlevels' => $config->get( MainConfigNames::SemiprotectedRestrictionLevels ),
807 ];
808
809 ApiResult::setArrayType( $data['types'], 'BCarray' );
810 ApiResult::setArrayType( $data['levels'], 'BCarray' );
811 ApiResult::setArrayType( $data['cascadinglevels'], 'BCarray' );
812 ApiResult::setArrayType( $data['semiprotectedlevels'], 'BCarray' );
813
814 ApiResult::setIndexedTagName( $data['types'], 'type' );
815 ApiResult::setIndexedTagName( $data['levels'], 'level' );
816 ApiResult::setIndexedTagName( $data['cascadinglevels'], 'level' );
817 ApiResult::setIndexedTagName( $data['semiprotectedlevels'], 'level' );
818
819 return $this->getResult()->addValue( 'query', $property, $data );
820 }
821
822 public function appendLanguages( $property ) {
823 $params = $this->extractRequestParams();
824 $langCode = $params['inlanguagecode'] ?? '';
825 $langNames = $this->languageNameUtils->getLanguageNames( $langCode );
826
827 $data = [];
828
829 foreach ( $langNames as $code => $name ) {
830 $lang = [
831 'code' => $code,
832 'bcp47' => LanguageCode::bcp47( $code ),
833 ];
834 ApiResult::setContentValue( $lang, 'name', $name );
835 $data[] = $lang;
836 }
837 ApiResult::setIndexedTagName( $data, 'lang' );
838
839 return $this->getResult()->addValue( 'query', $property, $data );
840 }
841
842 // Export information about which page languages will trigger
843 // language conversion. (T153341)
844 public function appendLanguageVariants( $property ) {
845 $langNames = $this->languageConverterFactory->isConversionDisabled() ? [] :
846 LanguageConverter::$languagesWithVariants;
847 sort( $langNames );
848
849 $data = [];
850 foreach ( $langNames as $langCode ) {
851 $lang = $this->languageFactory->getLanguage( $langCode );
852 $langConverter = $this->languageConverterFactory->getLanguageConverter( $lang );
853 if ( !$langConverter->hasVariants() ) {
854 // Only languages which have variants should be listed
855 continue;
856 }
857 $data[$langCode] = [];
858 ApiResult::setIndexedTagName( $data[$langCode], 'variant' );
859 ApiResult::setArrayType( $data[$langCode], 'kvp', 'code' );
860
861 $variants = $langConverter->getVariants();
862 sort( $variants );
863 foreach ( $variants as $v ) {
864 $data[$langCode][$v] = [
865 'fallbacks' => (array)$langConverter->getVariantFallbacks( $v ),
866 ];
868 $data[$langCode][$v]['fallbacks'], 'variant'
869 );
870 }
871 }
872 ApiResult::setIndexedTagName( $data, 'lang' );
873 ApiResult::setArrayType( $data, 'kvp', 'code' );
874
875 return $this->getResult()->addValue( 'query', $property, $data );
876 }
877
878 public function appendSkins( $property ) {
879 $data = [];
880 $allowed = $this->skinFactory->getAllowedSkins();
881 $default = Skin::normalizeKey( 'default' );
882
883 foreach ( $this->skinFactory->getInstalledSkins() as $name => $displayName ) {
884 $msg = $this->msg( "skinname-{$name}" );
885 $code = $this->getParameter( 'inlanguagecode' );
886 if ( $code && $this->languageNameUtils->isValidCode( $code ) ) {
887 $msg->inLanguage( $code );
888 } else {
889 $msg->inContentLanguage();
890 }
891 if ( $msg->exists() ) {
892 $displayName = $msg->text();
893 }
894 $skin = [ 'code' => $name ];
895 ApiResult::setContentValue( $skin, 'name', $displayName );
896 if ( !isset( $allowed[$name] ) ) {
897 $skin['unusable'] = true;
898 }
899 if ( $name === $default ) {
900 $skin['default'] = true;
901 }
902 $data[] = $skin;
903 }
904 ApiResult::setIndexedTagName( $data, 'skin' );
905
906 return $this->getResult()->addValue( 'query', $property, $data );
907 }
908
909 public function appendExtensionTags( $property ) {
910 $tags = array_map(
911 static function ( $item ) {
912 return "<$item>";
913 },
914 $this->parserFactory->getMainInstance()->getTags()
915 );
916 ApiResult::setArrayType( $tags, 'BCarray' );
917 ApiResult::setIndexedTagName( $tags, 't' );
918
919 return $this->getResult()->addValue( 'query', $property, $tags );
920 }
921
922 public function appendFunctionHooks( $property ) {
923 $hooks = $this->parserFactory->getMainInstance()->getFunctionHooks();
924 ApiResult::setArrayType( $hooks, 'BCarray' );
925 ApiResult::setIndexedTagName( $hooks, 'h' );
926
927 return $this->getResult()->addValue( 'query', $property, $hooks );
928 }
929
930 public function appendVariables( $property ) {
931 $variables = $this->magicWordFactory->getVariableIDs();
932 ApiResult::setArrayType( $variables, 'BCarray' );
933 ApiResult::setIndexedTagName( $variables, 'v' );
934
935 return $this->getResult()->addValue( 'query', $property, $variables );
936 }
937
938 public function appendProtocols( $property ) {
939 // Make a copy of the global so we don't try to set the _element key of it - T47130
940 $protocols = array_values( $this->getConfig()->get( MainConfigNames::UrlProtocols ) );
941 ApiResult::setArrayType( $protocols, 'BCarray' );
942 ApiResult::setIndexedTagName( $protocols, 'p' );
943
944 return $this->getResult()->addValue( 'query', $property, $protocols );
945 }
946
947 public function appendDefaultOptions( $property ) {
948 $options = $this->userOptionsLookup->getDefaultOptions( null );
949 $options[ApiResult::META_BC_BOOLS] = array_keys( $options );
950 return $this->getResult()->addValue( 'query', $property, $options );
951 }
952
953 public function appendUploadDialog( $property ) {
954 $config = $this->getConfig()->get( MainConfigNames::UploadDialog );
955 return $this->getResult()->addValue( 'query', $property, $config );
956 }
957
958 private function getAutoPromoteConds() {
959 $allowedConditions = [];
960 foreach ( get_defined_constants() as $constantName => $constantValue ) {
961 if ( strpos( $constantName, 'APCOND_' ) !== false ) {
962 $allowedConditions[$constantName] = $constantValue;
963 }
964 }
965 return $allowedConditions;
966 }
967
968 private function processAutoPromote( $input, $allowedConditions ) {
969 $data = [];
970 foreach ( $input as $groupName => $conditions ) {
971 $row = $this->recAutopromote( $conditions, $allowedConditions );
972 if ( !isset( $row[0] ) || is_string( $row ) ) {
973 $row = [ $row ];
974 }
975 $data[$groupName] = $row;
976 }
977 return $data;
978 }
979
980 private function appendAutoPromote( $property ) {
981 return $this->getResult()->addValue(
982 'query',
983 $property,
984 $this->processAutoPromote(
986 $this->getAutoPromoteConds()
987 )
988 );
989 }
990
991 private function appendAutoPromoteOnce( $property ) {
992 $allowedConditions = $this->getAutoPromoteConds();
993 $data = [];
994 foreach ( $this->getConfig()->get( MainConfigNames::AutopromoteOnce ) as $key => $value ) {
995 $data[$key] = $this->processAutoPromote( $value, $allowedConditions );
996 }
997 return $this->getResult()->addValue( 'query', $property, $data );
998 }
999
1005 private function recAutopromote( $cond, $allowedConditions ) {
1006 $config = [];
1007 // First, checks if $cond is an array
1008 if ( is_array( $cond ) ) {
1009 // Checks if $cond[0] is a valid operand
1010 if ( in_array( $cond[0], UserGroupManager::VALID_OPS, true ) ) {
1011 $config['operand'] = $cond[0];
1012 // Traversal checks conditions
1013 foreach ( array_slice( $cond, 1 ) as $value ) {
1014 $config[] = $this->recAutopromote( $value, $allowedConditions );
1015 }
1016 } elseif ( is_string( $cond[0] ) ) {
1017 // Returns $cond directly, if $cond[0] is a string
1018 $config = $cond;
1019 } else {
1020 // When $cond is equal to an APCOND_ constant value
1021 $params = array_slice( $cond, 1 );
1022 if ( $params === [ null ] ) {
1023 // Special casing for these conditions and their default of null,
1024 // to replace their values with $wgAutoConfirmCount/$wgAutoConfirmAge as appropriate
1025 if ( $cond[0] === APCOND_EDITCOUNT ) {
1027 } elseif ( $cond[0] === APCOND_AGE ) {
1028 $params = [ $this->getConfig()->get( MainConfigNames::AutoConfirmAge ) ];
1029 }
1030 }
1031 $config = [
1032 'condname' => array_search( $cond[0], $allowedConditions ),
1033 'params' => $params
1034 ];
1035 ApiResult::setIndexedTagName( $config, 'params' );
1036 }
1037 } elseif ( is_string( $cond ) ) {
1038 $config = $cond;
1039 } else {
1040 // When $cond is equal to an APCOND_ constant value
1041 $config = [
1042 'condname' => array_search( $cond, $allowedConditions ),
1043 'params' => []
1044 ];
1045 ApiResult::setIndexedTagName( $config, 'params' );
1046 }
1047
1048 return $config;
1049 }
1050
1051 public function appendSubscribedHooks( $property ) {
1052 $hookContainer = MediaWikiServices::getInstance()->getHookContainer();
1053 $hookNames = $hookContainer->getHookNames();
1054 sort( $hookNames );
1055
1056 $data = [];
1057 foreach ( $hookNames as $name ) {
1058 $arr = [
1059 'name' => $name,
1060 'subscribers' => $hookContainer->getHandlerDescriptions( $name ),
1061 ];
1062
1063 ApiResult::setArrayType( $arr['subscribers'], 'array' );
1064 ApiResult::setIndexedTagName( $arr['subscribers'], 's' );
1065 $data[] = $arr;
1066 }
1067
1068 ApiResult::setIndexedTagName( $data, 'hook' );
1069
1070 return $this->getResult()->addValue( 'query', $property, $data );
1071 }
1072
1073 public function getCacheMode( $params ) {
1074 // Messages for $wgExtraInterlanguageLinkPrefixes depend on user language
1076 in_array( 'interwikimap', $params['prop'] ?? [] )
1077 ) {
1078 return 'anon-public-user-private';
1079 }
1080
1081 return 'public';
1082 }
1083
1084 public function getAllowedParams() {
1085 return [
1086 'prop' => [
1087 ParamValidator::PARAM_DEFAULT => 'general',
1088 ParamValidator::PARAM_ISMULTI => true,
1089 ParamValidator::PARAM_TYPE => [
1090 'general',
1091 'namespaces',
1092 'namespacealiases',
1093 'specialpagealiases',
1094 'magicwords',
1095 'interwikimap',
1096 'dbrepllag',
1097 'statistics',
1098 'usergroups',
1099 'autocreatetempuser',
1100 'clientlibraries',
1101 'libraries',
1102 'extensions',
1103 'fileextensions',
1104 'rightsinfo',
1105 'restrictions',
1106 'languages',
1107 'languagevariants',
1108 'skins',
1109 'extensiontags',
1110 'functionhooks',
1111 'showhooks',
1112 'variables',
1113 'protocols',
1114 'defaultoptions',
1115 'uploaddialog',
1116 'autopromote',
1117 'autopromoteonce',
1118 ],
1120 ],
1121 'filteriw' => [
1122 ParamValidator::PARAM_TYPE => [
1123 'local',
1124 '!local',
1125 ]
1126 ],
1127 'showalldb' => false,
1128 'numberingroup' => false,
1129 'inlanguagecode' => null,
1130 ];
1131 }
1132
1133 protected function getExamplesMessages() {
1134 return [
1135 'action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics'
1136 => 'apihelp-query+siteinfo-example-simple',
1137 'action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local'
1138 => 'apihelp-query+siteinfo-example-interwiki',
1139 'action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb='
1140 => 'apihelp-query+siteinfo-example-replag',
1141 ];
1142 }
1143
1144 public function getHelpUrls() {
1145 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Siteinfo';
1146 }
1147}
1148
1150class_alias( ApiQuerySiteinfo::class, 'ApiQuerySiteinfo' );
const APCOND_AGE
Definition Defines.php:178
const PROTO_CURRENT
Definition Defines.php:209
const MW_VERSION
The running version of MediaWiki.
Definition Defines.php:37
const APCOND_EDITCOUNT
Definition Defines.php:177
const PROTO_RELATIVE
Definition Defines.php:206
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
$linkPrefixCharset
array $params
The job parameters.
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1577
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition ApiBase.php:795
getResult()
Get the result object.
Definition ApiBase.php:710
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:224
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
Definition ApiBase.php:1820
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:851
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
Definition ApiBase.php:973
This is a base class for all Query modules.
getDB()
Get the Query database connection (read-only)
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
A query action to return meta information about the wiki site.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
appendInterwikiMap( $property, $filter)
getCacheMode( $params)
Get the cache mode for the data generated by this module.
appendDbReplLagInfo( $property, $includeAll)
getHelpUrls()
Return links to more detailed help pages about the module.
getExamplesMessages()
Returns usage examples for this module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
__construct(ApiQuery $query, string $moduleName, UserOptionsLookup $userOptionsLookup, UserGroupManager $userGroupManager, LanguageConverterFactory $languageConverterFactory, LanguageFactory $languageFactory, LanguageNameUtils $languageNameUtils, Language $contentLanguage, NamespaceInfo $namespaceInfo, InterwikiLookup $interwikiLookup, ParserFactory $parserFactory, MagicWordFactory $magicWordFactory, SpecialPageFactory $specialPageFactory, SkinFactory $skinFactory, ILoadBalancer $loadBalancer, ReadOnlyMode $readOnlyMode, UrlUtils $urlUtils, TempUserConfig $tempUserConfig)
appendUserGroups( $property, $numberInGroup)
This is the main query class.
Definition ApiQuery.php:48
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
const META_BC_BOOLS
Key for the 'BC bools' metadata item.
const META_TYPE
Key for the 'type' metadata item.
static getMinUploadChunkSize(Config $config)
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Methods for dealing with language codes.
Base class for multi-variant language conversion.
Base class for language-specific code.
Definition Language.php:79
An interface for creating language converters.
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
A service that provides utilities to do with language names and codes.
A class containing constants representing the names of configuration variables.
const ExternalLinkTarget
Name constant for the ExternalLinkTarget setting, for use with Config::get()
const NoFollowDomainExceptions
Name constant for the NoFollowDomainExceptions setting, for use with Config::get()
const AutoConfirmCount
Name constant for the AutoConfirmCount setting, for use with Config::get()
const ServerName
Name constant for the ServerName setting, for use with Config::get()
const RightsPage
Name constant for the RightsPage setting, for use with Config::get()
const VariantArticlePath
Name constant for the VariantArticlePath setting, for use with Config::get()
const NamespaceProtection
Name constant for the NamespaceProtection setting, for use with Config::get()
const DBtype
Name constant for the DBtype setting, for use with Config::get()
const CapitalLinks
Name constant for the CapitalLinks setting, for use with Config::get()
const Localtimezone
Name constant for the Localtimezone setting, for use with Config::get()
const Server
Name constant for the Server setting, for use with Config::get()
const GroupsRemoveFromSelf
Name constant for the GroupsRemoveFromSelf setting, for use with Config::get()
const CentralIdLookupProviders
Name constant for the CentralIdLookupProviders setting, for use with Config::get()
const MaxArticleSize
Name constant for the MaxArticleSize setting, for use with Config::get()
const RestrictionTypes
Name constant for the RestrictionTypes setting, for use with Config::get()
const AutopromoteOnce
Name constant for the AutopromoteOnce setting, for use with Config::get()
const RightsText
Name constant for the RightsText setting, for use with Config::get()
const Autopromote
Name constant for the Autopromote setting, for use with Config::get()
const NoFollowNsExceptions
Name constant for the NoFollowNsExceptions setting, for use with Config::get()
const CascadingRestrictionLevels
Name constant for the CascadingRestrictionLevels setting, for use with Config::get()
const AllowExternalImages
Name constant for the AllowExternalImages setting, for use with Config::get()
const Sitename
Name constant for the Sitename setting, for use with Config::get()
const UrlProtocols
Name constant for the UrlProtocols setting, for use with Config::get()
const ArticlePath
Name constant for the ArticlePath setting, for use with Config::get()
const Favicon
Name constant for the Favicon setting, for use with Config::get()
const LocalTZoffset
Name constant for the LocalTZoffset setting, for use with Config::get()
const RightsUrl
Name constant for the RightsUrl setting, for use with Config::get()
const MainPageIsDomainRoot
Name constant for the MainPageIsDomainRoot setting, for use with Config::get()
const CategoryCollation
Name constant for the CategoryCollation setting, for use with Config::get()
const ImageLimits
Name constant for the ImageLimits setting, for use with Config::get()
const CentralIdLookupProvider
Name constant for the CentralIdLookupProvider setting, for use with Config::get()
const GroupPermissions
Name constant for the GroupPermissions setting, for use with Config::get()
const AddGroups
Name constant for the AddGroups setting, for use with Config::get()
const InterlanguageLinkCodeMap
Name constant for the InterlanguageLinkCodeMap setting, for use with Config::get()
const FileExtensions
Name constant for the FileExtensions setting, for use with Config::get()
const ScriptPath
Name constant for the ScriptPath setting, for use with Config::get()
const AllUnicodeFixes
Name constant for the AllUnicodeFixes setting, for use with Config::get()
const SemiprotectedRestrictionLevels
Name constant for the SemiprotectedRestrictionLevels setting, for use with Config::get()
const AutoConfirmAge
Name constant for the AutoConfirmAge setting, for use with Config::get()
const GalleryOptions
Name constant for the GalleryOptions setting, for use with Config::get()
const EnableMagicLinks
Name constant for the EnableMagicLinks setting, for use with Config::get()
const ThumbLimits
Name constant for the ThumbLimits setting, for use with Config::get()
const LanguageCode
Name constant for the LanguageCode setting, for use with Config::get()
const RestrictionLevels
Name constant for the RestrictionLevels setting, for use with Config::get()
const EnableImageWhitelist
Name constant for the EnableImageWhitelist setting, for use with Config::get()
const MiserMode
Name constant for the MiserMode setting, for use with Config::get()
const GroupsAddToSelf
Name constant for the GroupsAddToSelf setting, for use with Config::get()
const InvalidUsernameCharacters
Name constant for the InvalidUsernameCharacters setting, for use with Config::get()
const LocalInterwikis
Name constant for the LocalInterwikis setting, for use with Config::get()
const UploadDialog
Name constant for the UploadDialog setting, for use with Config::get()
const InterwikiMagic
Name constant for the InterwikiMagic setting, for use with Config::get()
const AllowExternalImagesFrom
Name constant for the AllowExternalImagesFrom setting, for use with Config::get()
const RemoveGroups
Name constant for the RemoveGroups setting, for use with Config::get()
const NoFollowLinks
Name constant for the NoFollowLinks setting, for use with Config::get()
const Script
Name constant for the Script setting, for use with Config::get()
const ExtraInterlanguageLinkPrefixes
Name constant for the ExtraInterlanguageLinkPrefixes setting, for use with Config::get()
const ShowHostnames
Name constant for the ShowHostnames setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Store information about magic words, and create/cache MagicWord objects.
Load JSON files, and uses a Processor to extract information.
Module for skin stylesheets.
static getAvailableLogos(Config $conf, ?string $lang=null)
Return an array of all available logos that a skin may use.
Static accessor class for site_stats and related things.
Definition SiteStats.php:36
static jobs()
Total number of jobs in the job queue.
static numberingroup( $group)
Find the number of users in a given user group.
Factory for handling the special page list and generating SpecialPage objects.
Parent class for all special pages.
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,...
Version information about MediaWiki (core, extensions, libs), PHP, and the database.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Represents a title within MediaWiki.
Definition Title.php:78
Provides access to user options.
Fetch status information from a local git repository.
Definition GitInfo.php:47
static repo()
Get the singleton for the repo at MW_INSTALL_PATH.
Definition GitInfo.php:176
A service to expand, parse, and otherwise manipulate URLs.
Definition UrlUtils.php:16
Tools for dealing with other locally-hosted wikis.
Definition WikiMap.php:31
Factory class to create Skin objects.
The base class for all skins.
Definition Skin.php:64
static normalizeKey(string $key)
Normalize a skin preference value to a form that can be loaded.
Definition Skin.php:228
UploadBase and subclasses are the backend of MediaWiki's file uploads.
Reads an installed.json file and provides accessors to get what is installed.
Service for formatting and validating API parameters.
Determine whether a site is currently in read-only mode.
Service interface for looking up Interwiki records.
Interface for temporary user creation config and name matching.
This class is a delegate to ILBFactory for a given database cluster.