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