109 parent::__construct( $query, $moduleName,
'si' );
110 $this->userOptionsLookup = $userOptionsLookup;
111 $this->userGroupManager = $userGroupManager;
112 $this->languageConverterFactory = $languageConverterFactory;
113 $this->languageFactory = $languageFactory;
114 $this->languageNameUtils = $languageNameUtils;
115 $this->contentLanguage = $contentLanguage;
116 $this->namespaceInfo = $namespaceInfo;
117 $this->interwikiLookup = $interwikiLookup;
118 $this->parserFactory = $parserFactory;
119 $this->magicWordFactory = $magicWordFactory;
120 $this->specialPageFactory = $specialPageFactory;
121 $this->skinFactory = $skinFactory;
122 $this->loadBalancer = $loadBalancer;
123 $this->readOnlyMode = $readOnlyMode;
124 $this->urlUtils = $urlUtils;
130 foreach (
$params[
'prop'] as $p ) {
138 case 'namespacealiases':
141 case 'specialpagealiases':
159 case 'autocreatetempuser':
162 case 'clientlibraries':
171 case 'fileextensions':
183 case 'languagevariants':
189 case 'extensiontags':
192 case 'functionhooks':
204 case 'defaultoptions':
211 $fit = $this->appendAutoPromote( $p );
213 case 'autopromoteonce':
214 $fit = $this->appendAutoPromoteOnce( $p );
223 array_diff(
$params[
'prop'], $done ) ) );
232 $mainPage = Title::newMainPage();
233 $logo = SkinModule::getAvailableLogos( $config );
236 'mainpage' => $mainPage->getPrefixedText(),
237 'base' => (string)$this->urlUtils->expand( $mainPage->getFullURL(),
PROTO_CURRENT ),
238 'sitename' => $config->get( MainConfigNames::Sitename ),
239 'mainpageisdomainroot' => (bool)$config->get( MainConfigNames::MainPageIsDomainRoot ),
243 'logo' => (string)$this->urlUtils->expand( $logo[
'1x'],
PROTO_RELATIVE ),
247 'phpversion' => PHP_VERSION,
248 'phpsapi' => PHP_SAPI,
249 'dbtype' => $config->get( MainConfigNames::DBtype ),
250 'dbversion' => $this->
getDB()->getServerVersion(),
254 $allowException =
true;
255 if ( !$config->get( MainConfigNames::AllowExternalImages ) ) {
256 $data[
'imagewhitelistenabled'] =
257 (bool)$config->get( MainConfigNames::EnableImageWhitelist );
258 $allowFrom = $config->get( MainConfigNames::AllowExternalImagesFrom );
259 $allowException = (bool)$allowFrom;
261 if ( $allowException ) {
262 $data[
'externalimages'] = (array)$allowFrom;
263 ApiResult::setIndexedTagName( $data[
'externalimages'],
'prefix' );
266 $data[
'langconversion'] = !$this->languageConverterFactory->isConversionDisabled();
267 $data[
'linkconversion'] = !$this->languageConverterFactory->isLinkConversionDisabled();
269 $data[
'titleconversion'] = $data[
'linkconversion'];
271 $contLangConverter = $this->languageConverterFactory->getLanguageConverter( $this->contentLanguage );
272 if ( $this->contentLanguage->linkPrefixExtension() ) {
276 $data[
'linkprefix'] =
"/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
278 $data[
'linkprefixcharset'] =
'';
279 $data[
'linkprefix'] =
'';
282 $data[
'linktrail'] = $this->contentLanguage->linkTrail() ?:
'';
284 $data[
'legaltitlechars'] = Title::legalChars();
285 $data[
'invalidusernamechars'] = $config->get( MainConfigNames::InvalidUsernameCharacters );
287 $data[
'allunicodefixes'] = (bool)$config->get( MainConfigNames::AllUnicodeFixes );
288 $data[
'fixarabicunicode'] =
true;
289 $data[
'fixmalayalamunicode'] =
true;
291 $git = GitInfo::repo()->getHeadSHA1();
293 $data[
'git-hash'] = $git;
294 $data[
'git-branch'] = GitInfo::repo()->getCurrentBranch();
299 $config->get( MainConfigNames::CapitalLinks ) ?
'first-letter' :
'case-sensitive';
300 $data[
'lang'] = $config->get( MainConfigNames::LanguageCode );
303 foreach ( $this->contentLanguage->getFallbackLanguages() as $code ) {
304 $fallbacks[] = [
'code' => $code ];
306 $data[
'fallback'] = $fallbacks;
307 ApiResult::setIndexedTagName( $data[
'fallback'],
'lang' );
309 if ( $contLangConverter->hasVariants() ) {
311 foreach ( $contLangConverter->getVariants() as $code ) {
314 'name' => $this->contentLanguage->getVariantname( $code ),
317 $data[
'variants'] = $variants;
318 ApiResult::setIndexedTagName( $data[
'variants'],
'lang' );
321 $data[
'rtl'] = $this->contentLanguage->isRTL();
322 $data[
'fallback8bitEncoding'] = $this->contentLanguage->fallback8bitEncoding();
324 $data[
'readonly'] = $this->readOnlyMode->isReadOnly();
325 if ( $data[
'readonly'] ) {
326 $data[
'readonlyreason'] = $this->readOnlyMode->getReason();
328 $data[
'writeapi'] =
true;
330 $data[
'maxarticlesize'] = $config->get( MainConfigNames::MaxArticleSize ) * 1024;
332 $data[
'timezone'] = $config->get( MainConfigNames::Localtimezone );
333 $data[
'timeoffset'] = (int)( $config->get( MainConfigNames::LocalTZoffset ) );
334 $data[
'articlepath'] = $config->get( MainConfigNames::ArticlePath );
335 $data[
'scriptpath'] = $config->get( MainConfigNames::ScriptPath );
336 $data[
'script'] = $config->get( MainConfigNames::Script );
337 $data[
'variantarticlepath'] = $config->get( MainConfigNames::VariantArticlePath );
338 $data[ApiResult::META_BC_BOOLS][] =
'variantarticlepath';
339 $data[
'server'] = $config->get( MainConfigNames::Server );
340 $data[
'servername'] = $config->get( MainConfigNames::ServerName );
341 $data[
'wikiid'] = WikiMap::getCurrentWikiId();
342 $data[
'time'] =
wfTimestamp( TS_ISO_8601, time() );
344 $data[
'misermode'] = (bool)$config->get( MainConfigNames::MiserMode );
346 $data[
'uploadsenabled'] = UploadBase::isEnabled();
347 $data[
'maxuploadsize'] = UploadBase::getMaxUploadSize();
350 $data[
'galleryoptions'] = $config->get( MainConfigNames::GalleryOptions );
352 $data[
'thumblimits'] = $config->get( MainConfigNames::ThumbLimits );
353 ApiResult::setArrayType( $data[
'thumblimits'],
'BCassoc' );
354 ApiResult::setIndexedTagName( $data[
'thumblimits'],
'limit' );
355 $data[
'imagelimits'] = [];
356 ApiResult::setArrayType( $data[
'imagelimits'],
'BCassoc' );
357 ApiResult::setIndexedTagName( $data[
'imagelimits'],
'limit' );
358 foreach ( $config->get( MainConfigNames::ImageLimits ) as $k => $limit ) {
359 $data[
'imagelimits'][$k] = [
'width' => $limit[0],
'height' => $limit[1] ];
362 $favicon = $config->get( MainConfigNames::Favicon );
365 $data[
'favicon'] = (string)$this->urlUtils->expand( $favicon );
368 $data[
'centralidlookupprovider'] = $config->get( MainConfigNames::CentralIdLookupProvider );
369 $providerIds = array_keys( $config->get( MainConfigNames::CentralIdLookupProviders ) );
370 $data[
'allcentralidlookupproviders'] = $providerIds;
372 $data[
'interwikimagic'] = (bool)$config->get( MainConfigNames::InterwikiMagic );
373 $data[
'magiclinks'] = $config->get( MainConfigNames::EnableMagicLinks );
375 $data[
'categorycollation'] = $config->get( MainConfigNames::CategoryCollation );
377 $data[
'nofollowlinks'] = $config->get( MainConfigNames::NoFollowLinks );
378 $data[
'nofollownsexceptions'] = $config->get( MainConfigNames::NoFollowNsExceptions );
379 $data[
'nofollowdomainexceptions'] = $config->get( MainConfigNames::NoFollowDomainExceptions );
380 $data[
'externallinktarget'] = $config->get( MainConfigNames::ExternalLinkTarget );
382 $this->
getHookRunner()->onAPIQuerySiteInfoGeneralInfo( $this, $data );
384 return $this->
getResult()->addValue(
'query', $property, $data );
388 $nsProtection = $this->
getConfig()->get( MainConfigNames::NamespaceProtection );
390 $data = [ ApiResult::META_TYPE =>
'assoc' ];
391 foreach ( $this->contentLanguage->getFormattedNamespaces() as $ns => $title ) {
394 'case' => $this->namespaceInfo->isCapitalized( $ns ) ?
'first-letter' :
'case-sensitive',
396 ApiResult::setContentValue( $data[$ns],
'name', $title );
397 $canonical = $this->namespaceInfo->getCanonicalName( $ns );
399 $data[$ns][
'subpages'] = $this->namespaceInfo->hasSubpages( $ns );
402 $data[$ns][
'canonical'] = strtr( $canonical,
'_',
' ' );
405 $data[$ns][
'content'] = $this->namespaceInfo->isContent( $ns );
406 $data[$ns][
'nonincludable'] = $this->namespaceInfo->isNonincludable( $ns );
408 $specificNs = $nsProtection[$ns] ??
'';
409 if ( is_array( $specificNs ) ) {
410 $specificNs = implode(
"|", array_filter( $specificNs ) );
412 if ( $specificNs !==
'' ) {
413 $data[$ns][
'namespaceprotection'] = $specificNs;
416 $contentmodel = $this->namespaceInfo->getNamespaceContentModel( $ns );
417 if ( $contentmodel ) {
418 $data[$ns][
'defaultcontentmodel'] = $contentmodel;
422 ApiResult::setArrayType( $data,
'assoc' );
423 ApiResult::setIndexedTagName( $data,
'ns' );
425 return $this->
getResult()->addValue(
'query', $property, $data );
429 $aliases = $this->contentLanguage->getNamespaceAliases();
430 $namespaces = $this->contentLanguage->getNamespaces();
432 foreach ( $aliases as $title => $ns ) {
433 if ( $namespaces[$ns] == $title ) {
437 $item = [
'id' => (int)$ns ];
438 ApiResult::setContentValue( $item,
'alias', strtr( $title,
'_',
' ' ) );
444 ApiResult::setIndexedTagName( $data,
'ns' );
446 return $this->
getResult()->addValue(
'query', $property, $data );
451 $aliases = $this->contentLanguage->getSpecialPageAliases();
452 foreach ( $this->specialPageFactory->getNames() as $specialpage ) {
453 if ( isset( $aliases[$specialpage] ) ) {
454 $arr = [
'realname' => $specialpage,
'aliases' => $aliases[$specialpage] ];
455 ApiResult::setIndexedTagName( $arr[
'aliases'],
'alias' );
459 ApiResult::setIndexedTagName( $data,
'specialpage' );
461 return $this->
getResult()->addValue(
'query', $property, $data );
466 foreach ( $this->contentLanguage->getMagicWords() as $name => $aliases ) {
467 $caseSensitive = (bool)array_shift( $aliases );
470 'aliases' => $aliases,
471 'case-sensitive' => $caseSensitive,
473 ApiResult::setIndexedTagName( $arr[
'aliases'],
'alias' );
476 ApiResult::setIndexedTagName( $data,
'magicword' );
478 return $this->
getResult()->addValue(
'query', $property, $data );
482 $local = $filter ? $filter ===
'local' :
null;
485 $langCode =
$params[
'inlanguagecode'] ??
'';
486 $interwikiMagic = $this->
getConfig()->get( MainConfigNames::InterwikiMagic );
488 if ( $interwikiMagic ) {
489 $langNames = $this->languageNameUtils->getLanguageNames( $langCode );
492 $extraLangPrefixes = $this->
getConfig()->get( MainConfigNames::ExtraInterlanguageLinkPrefixes );
493 $extraLangCodeMap = $this->
getConfig()->get( MainConfigNames::InterlanguageLinkCodeMap );
494 $localInterwikis = $this->
getConfig()->get( MainConfigNames::LocalInterwikis );
497 foreach ( $this->interwikiLookup->getAllPrefixes( $local ) as $row ) {
498 $prefix = $row[
'iw_prefix'];
500 $val[
'prefix'] = $prefix;
501 if ( $row[
'iw_local'] ??
false ) {
502 $val[
'local'] =
true;
504 if ( $row[
'iw_trans'] ??
false ) {
505 $val[
'trans'] =
true;
508 if ( $interwikiMagic && isset( $langNames[$prefix] ) ) {
509 $val[
'language'] = $langNames[$prefix];
510 $standard = LanguageCode::replaceDeprecatedCodes( $prefix );
511 if ( $standard !== $prefix ) {
512 # Note that even if this code is deprecated, it should
513 # only be remapped if extralanglink (set below) is false.
514 $val[
'deprecated'] = $standard;
516 $val[
'bcp47'] = LanguageCode::bcp47( $standard );
518 if ( in_array( $prefix, $localInterwikis ) ) {
519 $val[
'localinterwiki'] =
true;
521 if ( $interwikiMagic && in_array( $prefix, $extraLangPrefixes ) ) {
522 $val[
'extralanglink'] =
true;
523 $val[
'code'] = $extraLangCodeMap[$prefix] ?? $prefix;
524 $val[
'bcp47'] = LanguageCode::bcp47( $val[
'code'] );
526 $linktext = $this->
msg(
"interlanguage-link-$prefix" );
527 if ( !$linktext->isDisabled() ) {
528 $val[
'linktext'] = $linktext->text();
531 $sitename = $this->
msg(
"interlanguage-link-sitename-$prefix" );
532 if ( !$sitename->isDisabled() ) {
533 $val[
'sitename'] = $sitename->text();
537 $val[
'url'] = (string)$this->urlUtils->expand( $row[
'iw_url'],
PROTO_CURRENT );
538 $val[
'protorel'] = str_starts_with( $row[
'iw_url'],
'//' );
539 if ( ( $row[
'iw_wikiid'] ??
'' ) !==
'' ) {
540 $val[
'wikiid'] = $row[
'iw_wikiid'];
542 if ( ( $row[
'iw_api'] ??
'' ) !==
'' ) {
543 $val[
'api'] = $row[
'iw_api'];
549 ApiResult::setIndexedTagName( $data,
'iw' );
551 return $this->
getResult()->addValue(
'query', $property, $data );
556 $showHostnames = $this->
getConfig()->get( MainConfigNames::ShowHostnames );
558 if ( !$showHostnames ) {
559 $this->
dieWithError(
'apierror-siteinfo-includealldenied',
'includeAllDenied' );
562 foreach ( $this->loadBalancer->getLagTimes() as $i => $lag ) {
564 'host' => $this->loadBalancer->getServerName( $i ),
569 [ , $lag, $index ] = $this->loadBalancer->getMaxLag();
571 'host' => $showHostnames ? $this->loadBalancer->getServerName( $index ) :
'',
576 ApiResult::setIndexedTagName( $data,
'db' );
578 return $this->
getResult()->addValue(
'query', $property, $data );
583 'pages' => SiteStats::pages(),
584 'articles' => SiteStats::articles(),
585 'edits' => SiteStats::edits(),
586 'images' => SiteStats::images(),
587 'users' => SiteStats::users(),
588 'activeusers' => SiteStats::activeUsers(),
589 'admins' => SiteStats::numberingroup(
'sysop' ),
590 'jobs' => SiteStats::jobs(),
593 $this->
getHookRunner()->onAPIQuerySiteInfoStatisticsInfo( $data );
595 return $this->
getResult()->addValue(
'query', $property, $data );
603 $allGroups = array_values( $this->userGroupManager->listAllGroups() );
604 foreach ( $config->get( MainConfigNames::GroupPermissions ) as $group => $permissions ) {
607 'rights' => array_keys( $permissions,
true ),
610 if ( $numberInGroup ) {
611 $autopromote = $config->get( MainConfigNames::Autopromote );
613 if ( $group ==
'user' ) {
614 $arr[
'number'] = SiteStats::users();
616 } elseif ( $group !==
'*' && !isset( $autopromote[$group] ) ) {
617 $arr[
'number'] = SiteStats::numberingroup( $group );
622 'add' => $config->get( MainConfigNames::AddGroups ),
623 'remove' => $config->get( MainConfigNames::RemoveGroups ),
624 'add-self' => $config->get( MainConfigNames::GroupsAddToSelf ),
625 'remove-self' => $config->get( MainConfigNames::GroupsRemoveFromSelf )
628 foreach ( $groupArr as $type => $rights ) {
629 if ( isset( $rights[$group] ) ) {
630 if ( $rights[$group] ===
true ) {
631 $groups = $allGroups;
633 $groups = array_intersect( $rights[$group], $allGroups );
636 $arr[$type] = $groups;
637 ApiResult::setArrayType( $arr[$type],
'BCarray' );
638 ApiResult::setIndexedTagName( $arr[$type],
'group' );
643 ApiResult::setIndexedTagName( $arr[
'rights'],
'permission' );
647 ApiResult::setIndexedTagName( $data,
'group' );
649 return $result->addValue(
'query', $property, $data );
653 $config = $this->
getConfig()->get( MainConfigNames::AutoCreateTempUser );
655 $data = [
'enabled' => false ];
656 if ( $config[
'enabled'] ??
false ) {
657 $data[
'enabled'] =
true;
658 $data[
'actions'] = $config[
'actions'];
659 $data[
'genPattern'] = $config[
'genPattern'];
660 $data[
'matchPattern'] = $config[
'matchPattern'] ?? $data[
'genPattern'];
661 $data[
'serialProvider'] = $config[
'serialProvider'];
662 $data[
'serialMapping'] = $config[
'serialMapping'];
664 if ( isset( $config[
'reservedPattern'] ) ) {
665 $data[
'reservedPattern'] = $config[
'reservedPattern'];
668 return $this->
getResult()->addValue(
'query', $property, $data );
674 array_unique( $this->
getConfig()->
get( MainConfigNames::FileExtensions ) ) as $ext
676 $data[] = [
'ext' => $ext ];
678 ApiResult::setIndexedTagName( $data,
'fe' );
680 return $this->
getResult()->addValue(
'query', $property, $data );
685 foreach ( SpecialVersion::parseForeignResources() as $name => $info ) {
689 'name' => $info[
'name'],
690 'version' => $info[
'version'],
693 ApiResult::setIndexedTagName( $data,
'library' );
694 return $this->
getResult()->addValue(
'query', $property, $data );
698 $path = MW_INSTALL_PATH .
'/vendor/composer/installed.json';
699 if ( !file_exists(
$path ) ) {
705 foreach ( $installed->getInstalledDependencies() as $name => $info ) {
706 if ( str_starts_with( $info[
'type'],
'mediawiki-' ) ) {
713 'version' => $info[
'version'],
716 ApiResult::setIndexedTagName( $data,
'library' );
718 return $this->
getResult()->addValue(
'query', $property, $data );
723 $credits = SpecialVersion::getCredits(
724 ExtensionRegistry::getInstance(),
727 foreach ( $credits as $type => $extensions ) {
728 foreach ( $extensions as $ext ) {
729 $ret = [
'type' => $type ];
730 if ( isset( $ext[
'name'] ) ) {
731 $ret[
'name'] = $ext[
'name'];
733 if ( isset( $ext[
'namemsg'] ) ) {
734 $ret[
'namemsg'] = $ext[
'namemsg'];
736 if ( isset( $ext[
'description'] ) ) {
737 $ret[
'description'] = $ext[
'description'];
739 if ( isset( $ext[
'descriptionmsg'] ) ) {
741 if ( is_array( $ext[
'descriptionmsg'] ) ) {
742 $ret[
'descriptionmsg'] = $ext[
'descriptionmsg'][0];
743 $ret[
'descriptionmsgparams'] = array_slice( $ext[
'descriptionmsg'], 1 );
744 ApiResult::setIndexedTagName( $ret[
'descriptionmsgparams'],
'param' );
746 $ret[
'descriptionmsg'] = $ext[
'descriptionmsg'];
749 if ( isset( $ext[
'author'] ) ) {
750 $ret[
'author'] = is_array( $ext[
'author'] ) ?
751 implode(
', ', $ext[
'author'] ) : $ext[
'author'];
753 if ( isset( $ext[
'url'] ) ) {
754 $ret[
'url'] = $ext[
'url'];
756 if ( isset( $ext[
'version'] ) ) {
757 $ret[
'version'] = $ext[
'version'];
759 if ( isset( $ext[
'path'] ) ) {
760 $extensionPath = dirname( $ext[
'path'] );
761 $gitInfo =
new GitInfo( $extensionPath );
762 $vcsVersion = $gitInfo->getHeadSHA1();
763 if ( $vcsVersion !==
false ) {
764 $ret[
'vcs-system'] =
'git';
765 $ret[
'vcs-version'] = $vcsVersion;
766 $ret[
'vcs-url'] = $gitInfo->getHeadViewUrl();
767 $vcsDate = $gitInfo->getHeadCommitDate();
768 if ( $vcsDate !==
false ) {
769 $ret[
'vcs-date'] =
wfTimestamp( TS_ISO_8601, $vcsDate );
773 if ( ExtensionInfo::getLicenseFileNames( $extensionPath ) ) {
774 $ret[
'license-name'] = $ext[
'license-name'] ??
'';
775 $ret[
'license'] = SpecialPage::getTitleFor(
777 "License/{$ext['name']}"
781 if ( ExtensionInfo::getAuthorsFileName( $extensionPath ) ) {
782 $ret[
'credits'] = SpecialPage::getTitleFor(
784 "Credits/{$ext['name']}"
792 ApiResult::setIndexedTagName( $data,
'ext' );
794 return $this->
getResult()->addValue(
'query', $property, $data );
799 $title = Title::newFromText( $config->get( MainConfigNames::RightsPage ) );
801 $url = $this->urlUtils->expand( $title->getLinkURL(),
PROTO_CURRENT );
803 $url = $config->get( MainConfigNames::RightsUrl );
805 $text = $config->get( MainConfigNames::RightsText ) ??
'';
806 if ( $text ===
'' && $title ) {
807 $text = $title->getPrefixedText();
811 'url' => (string)$url,
812 'text' => (
string)$text,
815 return $this->
getResult()->addValue(
'query', $property, $data );
821 'types' => $config->get( MainConfigNames::RestrictionTypes ),
822 'levels' => $config->get( MainConfigNames::RestrictionLevels ),
823 'cascadinglevels' => $config->get( MainConfigNames::CascadingRestrictionLevels ),
824 'semiprotectedlevels' => $config->get( MainConfigNames::SemiprotectedRestrictionLevels ),
827 ApiResult::setArrayType( $data[
'types'],
'BCarray' );
828 ApiResult::setArrayType( $data[
'levels'],
'BCarray' );
829 ApiResult::setArrayType( $data[
'cascadinglevels'],
'BCarray' );
830 ApiResult::setArrayType( $data[
'semiprotectedlevels'],
'BCarray' );
832 ApiResult::setIndexedTagName( $data[
'types'],
'type' );
833 ApiResult::setIndexedTagName( $data[
'levels'],
'level' );
834 ApiResult::setIndexedTagName( $data[
'cascadinglevels'],
'level' );
835 ApiResult::setIndexedTagName( $data[
'semiprotectedlevels'],
'level' );
837 return $this->
getResult()->addValue(
'query', $property, $data );
842 $langCode =
$params[
'inlanguagecode'] ??
'';
843 $langNames = $this->languageNameUtils->getLanguageNames( $langCode );
847 foreach ( $langNames as $code => $name ) {
850 'bcp47' => LanguageCode::bcp47( $code ),
852 ApiResult::setContentValue( $lang,
'name', $name );
855 ApiResult::setIndexedTagName( $data,
'lang' );
857 return $this->
getResult()->addValue(
'query', $property, $data );
863 $langNames = $this->languageConverterFactory->isConversionDisabled() ? [] :
864 LanguageConverter::$languagesWithVariants;
868 foreach ( $langNames as $langCode ) {
869 $lang = $this->languageFactory->getLanguage( $langCode );
870 $langConverter = $this->languageConverterFactory->getLanguageConverter( $lang );
871 if ( !$langConverter->hasVariants() ) {
875 $data[$langCode] = [];
876 ApiResult::setIndexedTagName( $data[$langCode],
'variant' );
877 ApiResult::setArrayType( $data[$langCode],
'kvp',
'code' );
879 $variants = $langConverter->getVariants();
881 foreach ( $variants as $v ) {
882 $data[$langCode][$v] = [
883 'fallbacks' => (array)$langConverter->getVariantFallbacks( $v ),
885 ApiResult::setIndexedTagName(
886 $data[$langCode][$v][
'fallbacks'],
'variant'
890 ApiResult::setIndexedTagName( $data,
'lang' );
891 ApiResult::setArrayType( $data,
'kvp',
'code' );
893 return $this->
getResult()->addValue(
'query', $property, $data );
898 $allowed = $this->skinFactory->getAllowedSkins();
901 foreach ( $this->skinFactory->getInstalledSkins() as $name => $displayName ) {
902 $msg = $this->
msg(
"skinname-{$name}" );
904 if ( $code && $this->languageNameUtils->isValidCode( $code ) ) {
905 $msg->inLanguage( $code );
907 $msg->inContentLanguage();
909 if ( $msg->exists() ) {
910 $displayName = $msg->text();
912 $skin = [
'code' => $name ];
913 ApiResult::setContentValue( $skin,
'name', $displayName );
914 if ( !isset( $allowed[$name] ) ) {
915 $skin[
'unusable'] =
true;
917 if ( $name === $default ) {
918 $skin[
'default'] =
true;
922 ApiResult::setIndexedTagName( $data,
'skin' );
924 return $this->
getResult()->addValue(
'query', $property, $data );
929 static function ( $item ) {
932 $this->parserFactory->getMainInstance()->getTags()
934 ApiResult::setArrayType( $tags,
'BCarray' );
935 ApiResult::setIndexedTagName( $tags,
't' );
937 return $this->
getResult()->addValue(
'query', $property, $tags );
941 $hooks = $this->parserFactory->getMainInstance()->getFunctionHooks();
942 ApiResult::setArrayType( $hooks,
'BCarray' );
943 ApiResult::setIndexedTagName( $hooks,
'h' );
945 return $this->
getResult()->addValue(
'query', $property, $hooks );
949 $variables = $this->magicWordFactory->getVariableIDs();
950 ApiResult::setArrayType( $variables,
'BCarray' );
951 ApiResult::setIndexedTagName( $variables,
'v' );
953 return $this->
getResult()->addValue(
'query', $property, $variables );
958 $protocols = array_values( $this->
getConfig()->
get( MainConfigNames::UrlProtocols ) );
959 ApiResult::setArrayType( $protocols,
'BCarray' );
960 ApiResult::setIndexedTagName( $protocols,
'p' );
962 return $this->
getResult()->addValue(
'query', $property, $protocols );
966 $options = $this->userOptionsLookup->getDefaultOptions(
null );
967 $options[ApiResult::META_BC_BOOLS] = array_keys( $options );
968 return $this->
getResult()->addValue(
'query', $property, $options );
972 $config = $this->
getConfig()->get( MainConfigNames::UploadDialog );
973 return $this->
getResult()->addValue(
'query', $property, $config );
976 private function getAutoPromoteConds() {
977 $allowedConditions = [];
978 foreach ( get_defined_constants() as $constantName => $constantValue ) {
979 if ( strpos( $constantName,
'APCOND_' ) !==
false ) {
980 $allowedConditions[$constantName] = $constantValue;
983 return $allowedConditions;
986 private function processAutoPromote( $input, $allowedConditions ) {
988 foreach ( $input as $groupName => $conditions ) {
989 $row = $this->recAutopromote( $conditions, $allowedConditions );
990 if ( !isset( $row[0] ) || is_string( $row ) ) {
993 $data[$groupName] = $row;
998 private function appendAutoPromote( $property ) {
1002 $this->processAutoPromote(
1003 $this->
getConfig()->
get(
'Autopromote' ),
1004 $this->getAutoPromoteConds()
1009 private function appendAutoPromoteOnce( $property ) {
1010 $allowedConditions = $this->getAutoPromoteConds();
1012 foreach ( $this->
getConfig()->
get(
'AutopromoteOnce' ) as $key => $value ) {
1013 $data[$key] = $this->processAutoPromote( $value, $allowedConditions );
1015 return $this->
getResult()->addValue(
'query', $property, $data );
1023 private function recAutopromote( $cond, $allowedConditions ) {
1026 if ( is_array( $cond ) ) {
1028 if ( in_array( $cond[0], UserGroupManager::VALID_OPS,
true ) ) {
1029 $config[
'operand'] = $cond[0];
1031 foreach ( array_slice( $cond, 1 ) as $value ) {
1032 $config[] = $this->recAutopromote( $value, $allowedConditions );
1034 } elseif ( is_string( $cond[0] ) ) {
1039 $params = array_slice( $cond, 1 );
1044 $params = [ $this->
getConfig()->get( MainConfigNames::AutoConfirmCount ) ];
1050 'condname' => array_search( $cond[0], $allowedConditions ),
1055 } elseif ( is_string( $cond ) ) {
1060 'condname' => array_search( $cond, $allowedConditions ),
1070 $hookContainer = MediaWikiServices::getInstance()->getHookContainer();
1071 $hookNames = $hookContainer->getHookNames();
1075 foreach ( $hookNames as $name ) {
1078 'subscribers' => $hookContainer->getHandlerDescriptions( $name ),
1081 ApiResult::setArrayType( $arr[
'subscribers'],
'array' );
1082 ApiResult::setIndexedTagName( $arr[
'subscribers'],
's' );
1086 ApiResult::setIndexedTagName( $data,
'hook' );
1088 return $this->
getResult()->addValue(
'query', $property, $data );
1093 if ( $this->
getConfig()->
get( MainConfigNames::ExtraInterlanguageLinkPrefixes ) &&
1094 in_array(
'interwikimap',
$params[
'prop'] ?? [] )
1096 return 'anon-public-user-private';
1105 ParamValidator::PARAM_DEFAULT =>
'general',
1106 ParamValidator::PARAM_ISMULTI =>
true,
1107 ParamValidator::PARAM_TYPE => [
1111 'specialpagealiases',
1117 'autocreatetempuser',
1140 ParamValidator::PARAM_TYPE => [
1145 'showalldb' =>
false,
1146 'numberingroup' =>
false,
1147 'inlanguagecode' =>
null,
1153 'action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics'
1154 =>
'apihelp-query+siteinfo-example-simple',
1155 'action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local'
1156 =>
'apihelp-query+siteinfo-example-interwiki',
1157 'action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb='
1158 =>
'apihelp-query+siteinfo-example-replag',
1163 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Siteinfo';
const MW_VERSION
The running version of MediaWiki.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
array $params
The job parameters.
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
getHookRunner()
Get an ApiHookRunner for running core API hooks.
This is a base class for all Query modules.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
A query action to return meta information about the wiki site.
appendLanguageVariants( $property)
appendLanguages( $property)
appendInterwikiMap( $property, $filter)
appendGeneralInfo( $property)
appendRightsInfo( $property)
getExamplesMessages()
Returns usage examples for this module.
appendInstalledLibraries( $property)
appendVariables( $property)
appendAutoCreateTempUser( $property)
appendInstalledClientLibraries( $property)
appendUserGroups( $property, $numberInGroup)
appendFileExtensions( $property)
appendNamespaces( $property)
appendDefaultOptions( $property)
appendMagicWords( $property)
getHelpUrls()
Return links to more detailed help pages about the module.
appendExtensions( $property)
getCacheMode( $params)
Get the cache mode for the data generated by this module.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
appendRestrictions( $property)
__construct(ApiQuery $query, $moduleName, UserOptionsLookup $userOptionsLookup, UserGroupManager $userGroupManager, LanguageConverterFactory $languageConverterFactory, LanguageFactory $languageFactory, LanguageNameUtils $languageNameUtils, Language $contentLanguage, NamespaceInfo $namespaceInfo, InterwikiLookup $interwikiLookup, ParserFactory $parserFactory, MagicWordFactory $magicWordFactory, SpecialPageFactory $specialPageFactory, SkinFactory $skinFactory, ILoadBalancer $loadBalancer, ReadOnlyMode $readOnlyMode, UrlUtils $urlUtils)
appendExtensionTags( $property)
appendUploadDialog( $property)
appendProtocols( $property)
appendStatistics( $property)
appendSpecialPageAliases( $property)
appendDbReplLagInfo( $property, $includeAll)
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
appendSubscribedHooks( $property)
appendFunctionHooks( $property)
appendNamespaceAliases( $property)
This is the main query class.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
static getMinUploadChunkSize(Config $config)
Base class for language-specific code.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
A class containing constants representing the names of configuration variables.
Factory for handling the special page list and generating SpecialPage objects.
Parent class for all special pages.
Factory class to create Skin objects.
static normalizeKey(string $key)
Normalize a skin preference value to a form that can be loaded.