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