34 parent::__construct( $query, $moduleName,
'si' );
41 foreach ( $params[
'prop'] as $p ) {
49 case 'namespacealiases':
52 case 'specialpagealiases':
76 case 'fileextensions':
88 case 'languagevariants':
109 case 'defaultoptions':
122 array_diff( $params[
'prop'], $done ) ) );
134 $data[
'mainpage'] = $mainPage->getPrefixedText();
136 $data[
'sitename'] = $config->get(
'Sitename' );
137 $data[
'mainpageisdomainroot'] = (bool)$config->get(
'MainPageIsDomainRoot' );
144 $data[
'generator'] =
'MediaWiki ' .
MW_VERSION;
146 $data[
'phpversion'] = PHP_VERSION;
147 $data[
'phpsapi'] = PHP_SAPI;
148 $data[
'dbtype'] = $config->get(
'DBtype' );
149 $data[
'dbversion'] = $this->
getDB()->getServerVersion();
152 $allowException =
true;
153 if ( !$config->get(
'AllowExternalImages' ) ) {
154 $data[
'imagewhitelistenabled'] = (bool)$config->get(
'EnableImageWhitelist' );
155 $allowFrom = $config->get(
'AllowExternalImagesFrom' );
156 $allowException = !empty( $allowFrom );
158 if ( $allowException ) {
159 $data[
'externalimages'] = (array)$allowFrom;
163 $languageConverterFactory = MediaWikiServices::getInstance()->getLanguageConverterFactory();
164 $data[
'langconversion'] = !$languageConverterFactory->isConversionDisabled();
165 $data[
'linkconversion'] = !$languageConverterFactory->isLinkConversionDisabled();
167 $data[
'titleconversion'] = $data[
'linkconversion'];
169 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
170 $contLangConverter = $languageConverterFactory
171 ->getLanguageConverter( $contLang );
172 if ( $contLang->linkPrefixExtension() ) {
176 $data[
'linkprefix'] =
"/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
178 $data[
'linkprefixcharset'] =
'';
179 $data[
'linkprefix'] =
'';
182 $linktrail = $contLang->linkTrail();
183 $data[
'linktrail'] = $linktrail ?:
'';
186 $data[
'invalidusernamechars'] = $config->get(
'InvalidUsernameCharacters' );
188 $data[
'allunicodefixes'] = (bool)$config->get(
'AllUnicodeFixes' );
189 $data[
'fixarabicunicode'] =
true;
190 $data[
'fixmalayalamunicode'] =
true;
195 $data[
'git-hash'] = $git;
196 $data[
'git-branch'] =
201 $data[
'case'] = $config->get(
'CapitalLinks' ) ?
'first-letter' :
'case-sensitive';
202 $data[
'lang'] = $config->get(
'LanguageCode' );
205 foreach ( $contLang->getFallbackLanguages() as $code ) {
206 $fallbacks[] = [
'code' => $code ];
208 $data[
'fallback'] = $fallbacks;
211 if ( $contLangConverter->hasVariants() ) {
213 foreach ( $contLangConverter->getVariants() as $code ) {
216 'name' => $contLang->getVariantname( $code ),
219 $data[
'variants'] = $variants;
223 $data[
'rtl'] = $contLang->isRTL();
224 $data[
'fallback8bitEncoding'] = $contLang->fallback8bitEncoding();
227 if ( $data[
'readonly'] ) {
230 $data[
'writeapi'] =
true;
232 $data[
'maxarticlesize'] = $config->get(
'MaxArticleSize' ) * 1024;
234 $tz = $config->get(
'Localtimezone' );
235 $offset = $config->get(
'LocalTZoffset' );
236 $data[
'timezone'] = $tz;
237 $data[
'timeoffset'] = (int)$offset;
238 $data[
'articlepath'] = $config->get(
'ArticlePath' );
239 $data[
'scriptpath'] = $config->get(
'ScriptPath' );
240 $data[
'script'] = $config->get(
'Script' );
241 $data[
'variantarticlepath'] = $config->get(
'VariantArticlePath' );
243 $data[
'server'] = $config->get(
'Server' );
244 $data[
'servername'] = $config->get(
'ServerName' );
246 $data[
'time'] =
wfTimestamp( TS_ISO_8601, time() );
248 $data[
'misermode'] = (bool)$config->get(
'MiserMode' );
254 $data[
'galleryoptions'] = $config->get(
'GalleryOptions' );
256 $data[
'thumblimits'] = $config->get(
'ThumbLimits' );
259 $data[
'imagelimits'] = [];
262 foreach ( $config->get(
'ImageLimits' ) as $k => $limit ) {
263 $data[
'imagelimits'][$k] = [
'width' => $limit[0],
'height' => $limit[1] ];
266 $favicon = $config->get(
'Favicon' );
267 if ( !empty( $favicon ) ) {
273 $data[
'centralidlookupprovider'] = $config->get(
'CentralIdLookupProvider' );
274 $providerIds = array_keys( $config->get(
'CentralIdLookupProviders' ) );
275 $data[
'allcentralidlookupproviders'] = $providerIds;
277 $data[
'interwikimagic'] = (bool)$config->get(
'InterwikiMagic' );
278 $data[
'magiclinks'] = $config->get(
'EnableMagicLinks' );
280 $data[
'categorycollation'] = $config->get(
'CategoryCollation' );
282 $this->
getHookRunner()->onAPIQuerySiteInfoGeneralInfo( $this, $data );
284 return $this->
getResult()->addValue(
'query', $property, $data );
288 $nsProtection = $this->
getConfig()->get(
'NamespaceProtection' );
293 $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
295 MediaWikiServices::getInstance()->getContentLanguage()->getFormattedNamespaces()
300 'case' => $nsInfo->isCapitalized( $ns ) ?
'first-letter' :
'case-sensitive',
303 $canonical = $nsInfo->getCanonicalName( $ns );
305 $data[$ns][
'subpages'] = $nsInfo->hasSubpages( $ns );
308 $data[$ns][
'canonical'] = strtr( $canonical,
'_',
' ' );
311 $data[$ns][
'content'] = $nsInfo->isContent( $ns );
312 $data[$ns][
'nonincludable'] = $nsInfo->isNonincludable( $ns );
314 if ( isset( $nsProtection[$ns] ) ) {
315 if ( is_array( $nsProtection[$ns] ) ) {
316 $specificNs = implode(
"|", array_filter( $nsProtection[$ns] ) );
317 } elseif ( $nsProtection[$ns] !==
'' ) {
318 $specificNs = $nsProtection[$ns];
320 if ( isset( $specificNs ) && $specificNs !==
'' ) {
321 $data[$ns][
'namespaceprotection'] = $specificNs;
325 $contentmodel = $nsInfo->getNamespaceContentModel( $ns );
326 if ( $contentmodel ) {
327 $data[$ns][
'defaultcontentmodel'] = $contentmodel;
334 return $this->
getResult()->addValue(
'query', $property, $data );
338 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
339 $aliases = $contLang->getNamespaceAliases();
340 $namespaces = $contLang->getNamespaces();
342 foreach ( $aliases as
$title => $ns ) {
343 if ( $namespaces[$ns] ==
$title ) {
358 return $this->
getResult()->addValue(
'query', $property, $data );
363 $services = MediaWikiServices::getInstance();
364 $aliases = $services->getContentLanguage()->getSpecialPageAliases();
365 foreach ( $services->getSpecialPageFactory()->getNames() as $specialpage ) {
366 if ( isset( $aliases[$specialpage] ) ) {
367 $arr = [
'realname' => $specialpage,
'aliases' => $aliases[$specialpage] ];
374 return $this->
getResult()->addValue(
'query', $property, $data );
380 MediaWikiServices::getInstance()->getContentLanguage()->getMagicWords()
381 as $magicword => $aliases
383 $caseSensitive = array_shift( $aliases );
384 $arr = [
'name' => $magicword,
'aliases' => $aliases ];
385 $arr[
'case-sensitive'] = (bool)$caseSensitive;
391 return $this->
getResult()->addValue(
'query', $property, $data );
395 if ( $filter ===
'local' ) {
397 } elseif ( $filter ===
'!local' ) {
405 $langCode = $params[
'inlanguagecode'] ??
'';
406 $interwikiMagic = $this->
getConfig()->get(
'InterwikiMagic' );
408 if ( $interwikiMagic ) {
409 $langNames = MediaWikiServices::getInstance()
410 ->getLanguageNameUtils()
411 ->getLanguageNames( $langCode );
414 $getPrefixes = MediaWikiServices::getInstance()->getInterwikiLookup()->getAllPrefixes( $local );
415 $extraLangPrefixes = $this->
getConfig()->get(
'ExtraInterlanguageLinkPrefixes' );
416 $localInterwikis = $this->
getConfig()->get(
'LocalInterwikis' );
419 foreach ( $getPrefixes as $row ) {
420 $prefix = $row[
'iw_prefix'];
422 $val[
'prefix'] = $prefix;
423 if ( isset( $row[
'iw_local'] ) && $row[
'iw_local'] ==
'1' ) {
424 $val[
'local'] =
true;
426 if ( isset( $row[
'iw_trans'] ) && $row[
'iw_trans'] ==
'1' ) {
427 $val[
'trans'] =
true;
430 if ( $interwikiMagic && isset( $langNames[$prefix] ) ) {
431 $val[
'language'] = $langNames[$prefix];
433 if ( in_array( $prefix, $localInterwikis ) ) {
434 $val[
'localinterwiki'] =
true;
436 if ( $interwikiMagic && in_array( $prefix, $extraLangPrefixes ) ) {
437 $val[
'extralanglink'] =
true;
439 $linktext =
wfMessage(
"interlanguage-link-$prefix" );
440 if ( !$linktext->isDisabled() ) {
441 $val[
'linktext'] = $linktext->text();
444 $sitename =
wfMessage(
"interlanguage-link-sitename-$prefix" );
445 if ( !$sitename->isDisabled() ) {
446 $val[
'sitename'] = $sitename->text();
451 $val[
'protorel'] = substr( $row[
'iw_url'], 0, 2 ) ==
'//';
452 if ( isset( $row[
'iw_wikiid'] ) && $row[
'iw_wikiid'] !==
'' ) {
453 $val[
'wikiid'] = $row[
'iw_wikiid'];
455 if ( isset( $row[
'iw_api'] ) && $row[
'iw_api'] !==
'' ) {
456 $val[
'api'] = $row[
'iw_api'];
464 return $this->
getResult()->addValue(
'query', $property, $data );
469 $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
470 $showHostnames = $this->
getConfig()->get(
'ShowHostnames' );
472 if ( !$showHostnames ) {
473 $this->
dieWithError(
'apierror-siteinfo-includealldenied',
'includeAllDenied' );
476 $lags = $lb->getLagTimes();
477 foreach ( $lags as $i => $lag ) {
479 'host' => $lb->getServerName( $i ),
484 list( , $lag, $index ) = $lb->getMaxLag();
486 'host' => $showHostnames
487 ? $lb->getServerName( $index )
495 return $this->
getResult()->addValue(
'query', $property, $data );
509 $this->
getHookRunner()->onAPIQuerySiteInfoStatisticsInfo( $data );
511 return $this->
getResult()->addValue(
'query', $property, $data );
520 foreach ( $config->get(
'GroupPermissions' ) as $group => $permissions ) {
523 'rights' => array_keys( $permissions,
true ),
526 if ( $numberInGroup ) {
527 $autopromote = $config->get(
'Autopromote' );
529 if ( $group ==
'user' ) {
532 } elseif ( $group !==
'*' && !isset( $autopromote[$group] ) ) {
538 'add' => $config->get(
'AddGroups' ),
539 'remove' => $config->get(
'RemoveGroups' ),
540 'add-self' => $config->get(
'GroupsAddToSelf' ),
541 'remove-self' => $config->get(
'GroupsRemoveFromSelf' )
544 foreach ( $groupArr as
$type => $rights ) {
545 if ( isset( $rights[$group] ) ) {
546 if ( $rights[$group] ===
true ) {
547 $groups = $allGroups;
549 $groups = array_intersect( $rights[$group], $allGroups );
552 $arr[
$type] = $groups;
565 return $result->addValue(
'query', $property, $data );
570 foreach ( array_unique( $this->
getConfig()->
get(
'FileExtensions' ) ) as
$ext ) {
571 $data[] = [
'ext' =>
$ext ];
575 return $this->
getResult()->addValue(
'query', $property, $data );
580 $path =
"$IP/vendor/composer/installed.json";
581 if ( !file_exists(
$path ) ) {
587 foreach ( $installed->getInstalledDependencies() as $name => $info ) {
588 if ( strpos( $info[
'type'],
'mediawiki-' ) === 0 ) {
595 'version' => $info[
'version'],
600 return $this->
getResult()->addValue(
'query', $property, $data );
609 foreach ( $credits as
$type => $extensions ) {
610 foreach ( $extensions as
$ext ) {
612 $ret[
'type'] =
$type;
613 if ( isset(
$ext[
'name'] ) ) {
614 $ret[
'name'] =
$ext[
'name'];
616 if ( isset(
$ext[
'namemsg'] ) ) {
617 $ret[
'namemsg'] =
$ext[
'namemsg'];
619 if ( isset(
$ext[
'description'] ) ) {
620 $ret[
'description'] =
$ext[
'description'];
622 if ( isset(
$ext[
'descriptionmsg'] ) ) {
624 if ( is_array(
$ext[
'descriptionmsg'] ) ) {
625 $ret[
'descriptionmsg'] =
$ext[
'descriptionmsg'][0];
626 $ret[
'descriptionmsgparams'] = array_slice(
$ext[
'descriptionmsg'], 1 );
629 $ret[
'descriptionmsg'] =
$ext[
'descriptionmsg'];
632 if ( isset(
$ext[
'author'] ) ) {
633 $ret[
'author'] = is_array(
$ext[
'author'] ) ?
634 implode(
', ',
$ext[
'author'] ) :
$ext[
'author'];
636 if ( isset(
$ext[
'url'] ) ) {
637 $ret[
'url'] =
$ext[
'url'];
639 if ( isset(
$ext[
'version'] ) ) {
640 $ret[
'version'] =
$ext[
'version'];
642 if ( isset(
$ext[
'path'] ) ) {
643 $extensionPath = dirname(
$ext[
'path'] );
644 $gitInfo =
new GitInfo( $extensionPath );
645 $vcsVersion = $gitInfo->getHeadSHA1();
646 if ( $vcsVersion !==
false ) {
647 $ret[
'vcs-system'] =
'git';
648 $ret[
'vcs-version'] = $vcsVersion;
649 $ret[
'vcs-url'] = $gitInfo->getHeadViewUrl();
650 $vcsDate = $gitInfo->getHeadCommitDate();
651 if ( $vcsDate !==
false ) {
652 $ret[
'vcs-date'] =
wfTimestamp( TS_ISO_8601, $vcsDate );
656 if ( ExtensionInfo::getLicenseFileNames( $extensionPath ) ) {
657 $ret[
'license-name'] =
$ext[
'license-name'] ??
'';
660 "License/{$ext['name']}"
664 if ( ExtensionInfo::getAuthorsFileName( $extensionPath ) ) {
667 "Credits/{$ext['name']}"
677 return $this->
getResult()->addValue(
'query', $property, $data );
682 $rightsPage = $config->get(
'RightsPage' );
683 if ( is_string( $rightsPage ) ) {
688 $url = $config->get(
'RightsUrl' );
690 $text = $config->get(
'RightsText' );
691 if (
$title && !strlen( $text ) ) {
692 $text =
$title->getPrefixedText();
696 'url' => (string)$url,
697 'text' => (
string)$text,
700 return $this->
getResult()->addValue(
'query', $property, $data );
706 'types' => $config->get(
'RestrictionTypes' ),
707 'levels' => $config->get(
'RestrictionLevels' ),
708 'cascadinglevels' => $config->get(
'CascadingRestrictionLevels' ),
709 'semiprotectedlevels' => $config->get(
'SemiprotectedRestrictionLevels' ),
722 return $this->
getResult()->addValue(
'query', $property, $data );
727 $langCode = $params[
'inlanguagecode'] ??
'';
728 $langNames = MediaWikiServices::getInstance()
729 ->getLanguageNameUtils()
730 ->getLanguageNames( $langCode );
734 foreach ( $langNames as $code => $name ) {
744 return $this->
getResult()->addValue(
'query', $property, $data );
751 $languageConverterFactory = MediaWikiServices::getInstance()->getLanguageConverterFactory();
752 if ( $languageConverterFactory->isConversionDisabled() ) {
759 foreach ( $langNames as $langCode ) {
760 $lang = MediaWikiServices::getInstance()->getLanguageFactory()
761 ->getLanguage( $langCode );
762 $langConverter = $languageConverterFactory
763 ->getLanguageConverter(
$lang );
764 if ( !$langConverter->hasVariants() ) {
768 $data[$langCode] = [];
772 $variants =
$lang->getVariants();
774 foreach ( $variants as $v ) {
775 $fallbacks = $langConverter->getVariantFallbacks( $v );
776 if ( !is_array( $fallbacks ) ) {
777 $fallbacks = [ $fallbacks ];
779 $data[$langCode][$v] = [
780 'fallbacks' => $fallbacks,
783 $data[$langCode][$v][
'fallbacks'],
'variant'
790 return $this->
getResult()->addValue(
'query', $property, $data );
794 $services = MediaWikiServices::getInstance();
796 $allowed = $services->getSkinFactory()->getAllowedSkins();
798 $languageNameUtils = $services->getLanguageNameUtils();
799 $skinNames = $services->getSkinFactory()->getSkinNames();
801 foreach ( $skinNames as $name => $displayName ) {
802 $msg = $this->
msg(
"skinname-{$name}" );
804 if ( $code && $languageNameUtils->isValidCode( $code ) ) {
805 $msg->inLanguage( $code );
807 $msg->inContentLanguage();
809 if ( $msg->exists() ) {
810 $displayName = $msg->text();
812 $skin = [
'code' => $name ];
814 if ( !isset( $allowed[$name] ) ) {
815 $skin[
'unusable'] =
true;
817 if ( $name === $default ) {
818 $skin[
'default'] =
true;
824 return $this->
getResult()->addValue(
'query', $property, $data );
832 MediaWikiServices::getInstance()->getParser()->getTags()
837 return $this->
getResult()->addValue(
'query', $property, $tags );
841 $hooks = MediaWikiServices::getInstance()->getParser()->getFunctionHooks();
845 return $this->
getResult()->addValue(
'query', $property, $hooks );
849 $variables = MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs();
853 return $this->
getResult()->addValue(
'query', $property, $variables );
858 $protocols = array_values( $this->
getConfig()->
get(
'UrlProtocols' ) );
862 return $this->
getResult()->addValue(
'query', $property, $protocols );
868 return $this->
getResult()->addValue(
'query', $property, $options );
872 $config = $this->
getConfig()->get(
'UploadDialog' );
873 return $this->
getResult()->addValue(
'query', $property, $config );
877 $hooks = $this->
getConfig()->get(
'Hooks' );
882 foreach ( $myWgHooks as $name => $subscribers ) {
885 'subscribers' => array_map( [ SpecialVersion::class,
'arrayToString' ], $subscribers ),
895 return $this->
getResult()->addValue(
'query', $property, $data );
901 count( $this->
getConfig()->
get(
'ExtraInterlanguageLinkPrefixes' ) ) &&
902 $params[
'prop'] !==
null &&
903 in_array(
'interwikimap', $params[
'prop'] )
905 return 'anon-public-user-private';
920 'specialpagealiases',
950 'showalldb' =>
false,
951 'numberingroup' =>
false,
952 'inlanguagecode' =>
null,
958 'action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics'
959 =>
'apihelp-query+siteinfo-example-simple',
960 'action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local'
961 =>
'apihelp-query+siteinfo-example-interwiki',
962 'action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb='
963 =>
'apihelp-query+siteinfo-example-replag',
968 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Siteinfo';