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 );
302 $data[
'fallback'] = [];
303 foreach ( $this->contentLanguage->getFallbackLanguages() as $code ) {
304 $data[
'fallback'][] = [
'code' => $code ];
306 ApiResult::setIndexedTagName( $data[
'fallback'],
'lang' );
308 if ( $contLangConverter->hasVariants() ) {
309 $data[
'variants'] = [];
310 foreach ( $contLangConverter->getVariants() as $code ) {
311 $data[
'variants'][] = [
313 'name' => $this->contentLanguage->getVariantname( $code ),
316 ApiResult::setIndexedTagName( $data[
'variants'],
'lang' );
319 $data[
'rtl'] = $this->contentLanguage->isRTL();
320 $data[
'fallback8bitEncoding'] = $this->contentLanguage->fallback8bitEncoding();
322 $data[
'readonly'] = $this->readOnlyMode->isReadOnly();
323 if ( $data[
'readonly'] ) {
324 $data[
'readonlyreason'] = $this->readOnlyMode->getReason();
326 $data[
'writeapi'] =
true;
328 $data[
'maxarticlesize'] = $config->get( MainConfigNames::MaxArticleSize ) * 1024;
330 $data[
'timezone'] = $config->get( MainConfigNames::Localtimezone );
331 $data[
'timeoffset'] = (int)( $config->get( MainConfigNames::LocalTZoffset ) );
332 $data[
'articlepath'] = $config->get( MainConfigNames::ArticlePath );
333 $data[
'scriptpath'] = $config->get( MainConfigNames::ScriptPath );
334 $data[
'script'] = $config->get( MainConfigNames::Script );
335 $data[
'variantarticlepath'] = $config->get( MainConfigNames::VariantArticlePath );
336 $data[ApiResult::META_BC_BOOLS][] =
'variantarticlepath';
337 $data[
'server'] = $config->get( MainConfigNames::Server );
338 $data[
'servername'] = $config->get( MainConfigNames::ServerName );
339 $data[
'wikiid'] = WikiMap::getCurrentWikiId();
340 $data[
'time'] =
wfTimestamp( TS_ISO_8601, time() );
342 $data[
'misermode'] = (bool)$config->get( MainConfigNames::MiserMode );
344 $data[
'uploadsenabled'] = UploadBase::isEnabled();
345 $data[
'maxuploadsize'] = UploadBase::getMaxUploadSize();
348 $data[
'galleryoptions'] = $config->get( MainConfigNames::GalleryOptions );
350 $data[
'thumblimits'] = $config->get( MainConfigNames::ThumbLimits );
351 ApiResult::setArrayType( $data[
'thumblimits'],
'BCassoc' );
352 ApiResult::setIndexedTagName( $data[
'thumblimits'],
'limit' );
353 $data[
'imagelimits'] = [];
354 foreach ( $config->get( MainConfigNames::ImageLimits ) as $k => $limit ) {
355 $data[
'imagelimits'][$k] = [
'width' => $limit[0],
'height' => $limit[1] ];
357 ApiResult::setArrayType( $data[
'imagelimits'],
'BCassoc' );
358 ApiResult::setIndexedTagName( $data[
'imagelimits'],
'limit' );
360 $favicon = $config->get( MainConfigNames::Favicon );
363 $data[
'favicon'] = (string)$this->urlUtils->expand( $favicon );
366 $data[
'centralidlookupprovider'] = $config->get( MainConfigNames::CentralIdLookupProvider );
367 $providerIds = array_keys( $config->get( MainConfigNames::CentralIdLookupProviders ) );
368 $data[
'allcentralidlookupproviders'] = $providerIds;
370 $data[
'interwikimagic'] = (bool)$config->get( MainConfigNames::InterwikiMagic );
371 $data[
'magiclinks'] = $config->get( MainConfigNames::EnableMagicLinks );
373 $data[
'categorycollation'] = $config->get( MainConfigNames::CategoryCollation );
375 $data[
'nofollowlinks'] = $config->get( MainConfigNames::NoFollowLinks );
376 $data[
'nofollownsexceptions'] = $config->get( MainConfigNames::NoFollowNsExceptions );
377 $data[
'nofollowdomainexceptions'] = $config->get( MainConfigNames::NoFollowDomainExceptions );
378 $data[
'externallinktarget'] = $config->get( MainConfigNames::ExternalLinkTarget );
380 $this->
getHookRunner()->onAPIQuerySiteInfoGeneralInfo( $this, $data );
382 return $this->
getResult()->addValue(
'query', $property, $data );
386 $nsProtection = $this->
getConfig()->get( MainConfigNames::NamespaceProtection );
388 $data = [ ApiResult::META_TYPE =>
'assoc' ];
389 foreach ( $this->contentLanguage->getFormattedNamespaces() as $ns => $title ) {
392 'case' => $this->namespaceInfo->isCapitalized( $ns ) ?
'first-letter' :
'case-sensitive',
394 ApiResult::setContentValue( $data[$ns],
'name', $title );
395 $canonical = $this->namespaceInfo->getCanonicalName( $ns );
397 $data[$ns][
'subpages'] = $this->namespaceInfo->hasSubpages( $ns );
400 $data[$ns][
'canonical'] = strtr( $canonical,
'_',
' ' );
403 $data[$ns][
'content'] = $this->namespaceInfo->isContent( $ns );
404 $data[$ns][
'nonincludable'] = $this->namespaceInfo->isNonincludable( $ns );
406 $specificNs = $nsProtection[$ns] ??
'';
407 if ( is_array( $specificNs ) ) {
408 $specificNs = implode(
"|", array_filter( $specificNs ) );
410 if ( $specificNs !==
'' ) {
411 $data[$ns][
'namespaceprotection'] = $specificNs;
414 $contentmodel = $this->namespaceInfo->getNamespaceContentModel( $ns );
415 if ( $contentmodel ) {
416 $data[$ns][
'defaultcontentmodel'] = $contentmodel;
420 ApiResult::setArrayType( $data,
'assoc' );
421 ApiResult::setIndexedTagName( $data,
'ns' );
423 return $this->
getResult()->addValue(
'query', $property, $data );
427 $aliases = $this->contentLanguage->getNamespaceAliases();
428 $namespaces = $this->contentLanguage->getNamespaces();
430 foreach ( $aliases as $title => $ns ) {
431 if ( $namespaces[$ns] == $title ) {
435 $item = [
'id' => (int)$ns ];
436 ApiResult::setContentValue( $item,
'alias', strtr( $title,
'_',
' ' ) );
442 ApiResult::setIndexedTagName( $data,
'ns' );
444 return $this->
getResult()->addValue(
'query', $property, $data );
449 $aliases = $this->contentLanguage->getSpecialPageAliases();
450 foreach ( $this->specialPageFactory->getNames() as $specialpage ) {
451 if ( isset( $aliases[$specialpage] ) ) {
452 $arr = [
'realname' => $specialpage,
'aliases' => $aliases[$specialpage] ];
453 ApiResult::setIndexedTagName( $arr[
'aliases'],
'alias' );
457 ApiResult::setIndexedTagName( $data,
'specialpage' );
459 return $this->
getResult()->addValue(
'query', $property, $data );
464 foreach ( $this->contentLanguage->getMagicWords() as $name => $aliases ) {
465 $caseSensitive = (bool)array_shift( $aliases );
468 'aliases' => $aliases,
469 'case-sensitive' => $caseSensitive,
471 ApiResult::setIndexedTagName( $arr[
'aliases'],
'alias' );
474 ApiResult::setIndexedTagName( $data,
'magicword' );
476 return $this->
getResult()->addValue(
'query', $property, $data );
480 $local = $filter ? $filter ===
'local' :
null;
483 $langCode =
$params[
'inlanguagecode'] ??
'';
484 $interwikiMagic = $this->
getConfig()->get( MainConfigNames::InterwikiMagic );
486 if ( $interwikiMagic ) {
487 $langNames = $this->languageNameUtils->getLanguageNames( $langCode );
490 $extraLangPrefixes = $this->
getConfig()->get( MainConfigNames::ExtraInterlanguageLinkPrefixes );
491 $extraLangCodeMap = $this->
getConfig()->get( MainConfigNames::InterlanguageLinkCodeMap );
492 $localInterwikis = $this->
getConfig()->get( MainConfigNames::LocalInterwikis );
495 foreach ( $this->interwikiLookup->getAllPrefixes( $local ) as $row ) {
496 $prefix = $row[
'iw_prefix'];
498 $val[
'prefix'] = $prefix;
499 if ( $row[
'iw_local'] ??
false ) {
500 $val[
'local'] =
true;
502 if ( $row[
'iw_trans'] ??
false ) {
503 $val[
'trans'] =
true;
506 if ( $interwikiMagic && isset( $langNames[$prefix] ) ) {
507 $val[
'language'] = $langNames[$prefix];
508 $standard = LanguageCode::replaceDeprecatedCodes( $prefix );
509 if ( $standard !== $prefix ) {
510 # Note that even if this code is deprecated, it should
511 # only be remapped if extralanglink (set below) is false.
512 $val[
'deprecated'] = $standard;
514 $val[
'bcp47'] = LanguageCode::bcp47( $standard );
516 if ( in_array( $prefix, $localInterwikis ) ) {
517 $val[
'localinterwiki'] =
true;
519 if ( $interwikiMagic && in_array( $prefix, $extraLangPrefixes ) ) {
520 $val[
'extralanglink'] =
true;
521 $val[
'code'] = $extraLangCodeMap[$prefix] ?? $prefix;
522 $val[
'bcp47'] = LanguageCode::bcp47( $val[
'code'] );
524 $linktext = $this->
msg(
"interlanguage-link-$prefix" );
525 if ( !$linktext->isDisabled() ) {
526 $val[
'linktext'] = $linktext->text();
529 $sitename = $this->
msg(
"interlanguage-link-sitename-$prefix" );
530 if ( !$sitename->isDisabled() ) {
531 $val[
'sitename'] = $sitename->text();
535 $val[
'url'] = (string)$this->urlUtils->expand( $row[
'iw_url'],
PROTO_CURRENT );
536 $val[
'protorel'] = str_starts_with( $row[
'iw_url'],
'//' );
537 if ( ( $row[
'iw_wikiid'] ??
'' ) !==
'' ) {
538 $val[
'wikiid'] = $row[
'iw_wikiid'];
540 if ( ( $row[
'iw_api'] ??
'' ) !==
'' ) {
541 $val[
'api'] = $row[
'iw_api'];
547 ApiResult::setIndexedTagName( $data,
'iw' );
549 return $this->
getResult()->addValue(
'query', $property, $data );
554 $showHostnames = $this->
getConfig()->get( MainConfigNames::ShowHostnames );
556 if ( !$showHostnames ) {
557 $this->
dieWithError(
'apierror-siteinfo-includealldenied',
'includeAllDenied' );
560 foreach ( $this->loadBalancer->getLagTimes() as $i => $lag ) {
562 'host' => $this->loadBalancer->getServerName( $i ),
567 [ , $lag, $index ] = $this->loadBalancer->getMaxLag();
569 'host' => $showHostnames ? $this->loadBalancer->getServerName( $index ) :
'',
574 ApiResult::setIndexedTagName( $data,
'db' );
576 return $this->
getResult()->addValue(
'query', $property, $data );
581 'pages' => SiteStats::pages(),
582 'articles' => SiteStats::articles(),
583 'edits' => SiteStats::edits(),
584 'images' => SiteStats::images(),
585 'users' => SiteStats::users(),
586 'activeusers' => SiteStats::activeUsers(),
587 'admins' => SiteStats::numberingroup(
'sysop' ),
588 'jobs' => SiteStats::jobs(),
591 $this->
getHookRunner()->onAPIQuerySiteInfoStatisticsInfo( $data );
593 return $this->
getResult()->addValue(
'query', $property, $data );
601 $allGroups = array_values( $this->userGroupManager->listAllGroups() );
602 foreach ( $config->get( MainConfigNames::GroupPermissions ) as $group => $permissions ) {
605 'rights' => array_keys( $permissions,
true ),
608 if ( $numberInGroup ) {
609 $autopromote = $config->get( MainConfigNames::Autopromote );
611 if ( $group ==
'user' ) {
612 $arr[
'number'] = SiteStats::users();
614 } elseif ( $group !==
'*' && !isset( $autopromote[$group] ) ) {
615 $arr[
'number'] = SiteStats::numberingroup( $group );
620 'add' => $config->get( MainConfigNames::AddGroups ),
621 'remove' => $config->get( MainConfigNames::RemoveGroups ),
622 'add-self' => $config->get( MainConfigNames::GroupsAddToSelf ),
623 'remove-self' => $config->get( MainConfigNames::GroupsRemoveFromSelf )
626 foreach ( $groupArr as $type => $rights ) {
627 if ( isset( $rights[$group] ) ) {
628 if ( $rights[$group] ===
true ) {
629 $groups = $allGroups;
631 $groups = array_intersect( $rights[$group], $allGroups );
634 $arr[$type] = $groups;
635 ApiResult::setArrayType( $arr[$type],
'BCarray' );
636 ApiResult::setIndexedTagName( $arr[$type],
'group' );
641 ApiResult::setIndexedTagName( $arr[
'rights'],
'permission' );
645 ApiResult::setIndexedTagName( $data,
'group' );
647 return $result->addValue(
'query', $property, $data );
651 $config = $this->
getConfig()->get( MainConfigNames::AutoCreateTempUser );
653 $data = [
'enabled' => false ];
654 if ( $config[
'enabled'] ??
false ) {
655 $data[
'enabled'] =
true;
656 $data[
'actions'] = $config[
'actions'];
657 $data[
'genPattern'] = $config[
'genPattern'];
658 $data[
'matchPattern'] = $config[
'matchPattern'] ?? $data[
'genPattern'];
659 $data[
'serialProvider'] = $config[
'serialProvider'];
660 $data[
'serialMapping'] = $config[
'serialMapping'];
662 if ( isset( $config[
'reservedPattern'] ) ) {
663 $data[
'reservedPattern'] = $config[
'reservedPattern'];
666 return $this->
getResult()->addValue(
'query', $property, $data );
672 array_unique( $this->
getConfig()->
get( MainConfigNames::FileExtensions ) ) as $ext
674 $data[] = [
'ext' => $ext ];
676 ApiResult::setIndexedTagName( $data,
'fe' );
678 return $this->
getResult()->addValue(
'query', $property, $data );
683 foreach ( SpecialVersion::parseForeignResources() as $name => $info ) {
687 'name' => $info[
'name'],
688 'version' => $info[
'version'],
691 ApiResult::setIndexedTagName( $data,
'library' );
692 return $this->
getResult()->addValue(
'query', $property, $data );
696 $path = MW_INSTALL_PATH .
'/vendor/composer/installed.json';
697 if ( !file_exists(
$path ) ) {
703 foreach ( $installed->getInstalledDependencies() as $name => $info ) {
704 if ( str_starts_with( $info[
'type'],
'mediawiki-' ) ) {
711 'version' => $info[
'version'],
714 ApiResult::setIndexedTagName( $data,
'library' );
716 return $this->
getResult()->addValue(
'query', $property, $data );
721 $credits = SpecialVersion::getCredits(
722 ExtensionRegistry::getInstance(),
725 foreach ( $credits as $type => $extensions ) {
726 foreach ( $extensions as $ext ) {
727 $ret = [
'type' => $type ];
728 if ( isset( $ext[
'name'] ) ) {
729 $ret[
'name'] = $ext[
'name'];
731 if ( isset( $ext[
'namemsg'] ) ) {
732 $ret[
'namemsg'] = $ext[
'namemsg'];
734 if ( isset( $ext[
'description'] ) ) {
735 $ret[
'description'] = $ext[
'description'];
737 if ( isset( $ext[
'descriptionmsg'] ) ) {
739 if ( is_array( $ext[
'descriptionmsg'] ) ) {
740 $ret[
'descriptionmsg'] = $ext[
'descriptionmsg'][0];
741 $ret[
'descriptionmsgparams'] = array_slice( $ext[
'descriptionmsg'], 1 );
742 ApiResult::setIndexedTagName( $ret[
'descriptionmsgparams'],
'param' );
744 $ret[
'descriptionmsg'] = $ext[
'descriptionmsg'];
747 if ( isset( $ext[
'author'] ) ) {
748 $ret[
'author'] = is_array( $ext[
'author'] ) ?
749 implode(
', ', $ext[
'author'] ) : $ext[
'author'];
751 if ( isset( $ext[
'url'] ) ) {
752 $ret[
'url'] = $ext[
'url'];
754 if ( isset( $ext[
'version'] ) ) {
755 $ret[
'version'] = $ext[
'version'];
757 if ( isset( $ext[
'path'] ) ) {
758 $extensionPath = dirname( $ext[
'path'] );
759 $gitInfo =
new GitInfo( $extensionPath );
760 $vcsVersion = $gitInfo->getHeadSHA1();
761 if ( $vcsVersion !==
false ) {
762 $ret[
'vcs-system'] =
'git';
763 $ret[
'vcs-version'] = $vcsVersion;
764 $ret[
'vcs-url'] = $gitInfo->getHeadViewUrl();
765 $vcsDate = $gitInfo->getHeadCommitDate();
766 if ( $vcsDate !==
false ) {
767 $ret[
'vcs-date'] =
wfTimestamp( TS_ISO_8601, $vcsDate );
771 if ( ExtensionInfo::getLicenseFileNames( $extensionPath ) ) {
772 $ret[
'license-name'] = $ext[
'license-name'] ??
'';
773 $ret[
'license'] = SpecialPage::getTitleFor(
775 "License/{$ext['name']}"
779 if ( ExtensionInfo::getAuthorsFileName( $extensionPath ) ) {
780 $ret[
'credits'] = SpecialPage::getTitleFor(
782 "Credits/{$ext['name']}"
790 ApiResult::setIndexedTagName( $data,
'ext' );
792 return $this->
getResult()->addValue(
'query', $property, $data );
797 $title = Title::newFromText( $config->get( MainConfigNames::RightsPage ) );
799 $url = $this->urlUtils->expand( $title->getLinkURL(),
PROTO_CURRENT );
801 $url = $config->get( MainConfigNames::RightsUrl );
803 $text = $config->get( MainConfigNames::RightsText ) ??
'';
804 if ( $text ===
'' && $title ) {
805 $text = $title->getPrefixedText();
809 'url' => (string)$url,
810 'text' => (
string)$text,
813 return $this->
getResult()->addValue(
'query', $property, $data );
819 'types' => $config->get( MainConfigNames::RestrictionTypes ),
820 'levels' => $config->get( MainConfigNames::RestrictionLevels ),
821 'cascadinglevels' => $config->get( MainConfigNames::CascadingRestrictionLevels ),
822 'semiprotectedlevels' => $config->get( MainConfigNames::SemiprotectedRestrictionLevels ),
825 ApiResult::setArrayType( $data[
'types'],
'BCarray' );
826 ApiResult::setArrayType( $data[
'levels'],
'BCarray' );
827 ApiResult::setArrayType( $data[
'cascadinglevels'],
'BCarray' );
828 ApiResult::setArrayType( $data[
'semiprotectedlevels'],
'BCarray' );
830 ApiResult::setIndexedTagName( $data[
'types'],
'type' );
831 ApiResult::setIndexedTagName( $data[
'levels'],
'level' );
832 ApiResult::setIndexedTagName( $data[
'cascadinglevels'],
'level' );
833 ApiResult::setIndexedTagName( $data[
'semiprotectedlevels'],
'level' );
835 return $this->
getResult()->addValue(
'query', $property, $data );
840 $langCode =
$params[
'inlanguagecode'] ??
'';
841 $langNames = $this->languageNameUtils->getLanguageNames( $langCode );
845 foreach ( $langNames as $code => $name ) {
848 'bcp47' => LanguageCode::bcp47( $code ),
850 ApiResult::setContentValue( $lang,
'name', $name );
853 ApiResult::setIndexedTagName( $data,
'lang' );
855 return $this->
getResult()->addValue(
'query', $property, $data );
861 $langNames = $this->languageConverterFactory->isConversionDisabled() ? [] :
862 LanguageConverter::$languagesWithVariants;
866 foreach ( $langNames as $langCode ) {
867 $lang = $this->languageFactory->getLanguage( $langCode );
868 $langConverter = $this->languageConverterFactory->getLanguageConverter( $lang );
869 if ( !$langConverter->hasVariants() ) {
873 $data[$langCode] = [];
874 ApiResult::setIndexedTagName( $data[$langCode],
'variant' );
875 ApiResult::setArrayType( $data[$langCode],
'kvp',
'code' );
877 $variants = $langConverter->getVariants();
879 foreach ( $variants as $v ) {
880 $data[$langCode][$v] = [
881 'fallbacks' => (array)$langConverter->getVariantFallbacks( $v ),
883 ApiResult::setIndexedTagName(
884 $data[$langCode][$v][
'fallbacks'],
'variant'
888 ApiResult::setIndexedTagName( $data,
'lang' );
889 ApiResult::setArrayType( $data,
'kvp',
'code' );
891 return $this->
getResult()->addValue(
'query', $property, $data );
896 $allowed = $this->skinFactory->getAllowedSkins();
899 foreach ( $this->skinFactory->getInstalledSkins() as $name => $displayName ) {
900 $msg = $this->
msg(
"skinname-{$name}" );
902 if ( $code && $this->languageNameUtils->isValidCode( $code ) ) {
903 $msg->inLanguage( $code );
905 $msg->inContentLanguage();
907 if ( $msg->exists() ) {
908 $displayName = $msg->text();
910 $skin = [
'code' => $name ];
911 ApiResult::setContentValue( $skin,
'name', $displayName );
912 if ( !isset( $allowed[$name] ) ) {
913 $skin[
'unusable'] =
true;
915 if ( $name === $default ) {
916 $skin[
'default'] =
true;
920 ApiResult::setIndexedTagName( $data,
'skin' );
922 return $this->
getResult()->addValue(
'query', $property, $data );
927 static function ( $item ) {
930 $this->parserFactory->getMainInstance()->getTags()
932 ApiResult::setArrayType( $tags,
'BCarray' );
933 ApiResult::setIndexedTagName( $tags,
't' );
935 return $this->
getResult()->addValue(
'query', $property, $tags );
939 $hooks = $this->parserFactory->getMainInstance()->getFunctionHooks();
940 ApiResult::setArrayType( $hooks,
'BCarray' );
941 ApiResult::setIndexedTagName( $hooks,
'h' );
943 return $this->
getResult()->addValue(
'query', $property, $hooks );
947 $variables = $this->magicWordFactory->getVariableIDs();
948 ApiResult::setArrayType( $variables,
'BCarray' );
949 ApiResult::setIndexedTagName( $variables,
'v' );
951 return $this->
getResult()->addValue(
'query', $property, $variables );
956 $protocols = array_values( $this->
getConfig()->
get( MainConfigNames::UrlProtocols ) );
957 ApiResult::setArrayType( $protocols,
'BCarray' );
958 ApiResult::setIndexedTagName( $protocols,
'p' );
960 return $this->
getResult()->addValue(
'query', $property, $protocols );
964 $options = $this->userOptionsLookup->getDefaultOptions(
null );
965 $options[ApiResult::META_BC_BOOLS] = array_keys( $options );
966 return $this->
getResult()->addValue(
'query', $property, $options );
970 $config = $this->
getConfig()->get( MainConfigNames::UploadDialog );
971 return $this->
getResult()->addValue(
'query', $property, $config );
974 private function getAutoPromoteConds() {
975 $allowedConditions = [];
976 foreach ( get_defined_constants() as $constantName => $constantValue ) {
977 if ( strpos( $constantName,
'APCOND_' ) !==
false ) {
978 $allowedConditions[$constantName] = $constantValue;
981 return $allowedConditions;
984 private function processAutoPromote( $input, $allowedConditions ) {
986 foreach ( $input as $groupName => $conditions ) {
987 $row = $this->recAutopromote( $conditions, $allowedConditions );
988 if ( !isset( $row[0] ) || is_string( $row ) ) {
991 $data[$groupName] = $row;
996 private function appendAutoPromote( $property ) {
1000 $this->processAutoPromote(
1001 $this->
getConfig()->
get(
'Autopromote' ),
1002 $this->getAutoPromoteConds()
1007 private function appendAutoPromoteOnce( $property ) {
1008 $allowedConditions = $this->getAutoPromoteConds();
1010 foreach ( $this->
getConfig()->
get(
'AutopromoteOnce' ) as $key => $value ) {
1011 $data[$key] = $this->processAutoPromote( $value, $allowedConditions );
1013 return $this->
getResult()->addValue(
'query', $property, $data );
1021 private function recAutopromote( $cond, $allowedConditions ) {
1024 if ( is_array( $cond ) ) {
1026 if ( in_array( $cond[0], UserGroupManager::VALID_OPS,
true ) ) {
1027 $config[
'operand'] = $cond[0];
1029 foreach ( array_slice( $cond, 1 ) as $value ) {
1030 $config[] = $this->recAutopromote( $value, $allowedConditions );
1032 } elseif ( is_string( $cond[0] ) ) {
1037 $params = array_slice( $cond, 1 );
1042 $params = [ $this->
getConfig()->get( MainConfigNames::AutoConfirmCount ) ];
1048 'condname' => array_search( $cond[0], $allowedConditions ),
1053 } elseif ( is_string( $cond ) ) {
1058 'condname' => array_search( $cond, $allowedConditions ),
1068 $hookContainer = MediaWikiServices::getInstance()->getHookContainer();
1069 $hookNames = $hookContainer->getHookNames();
1073 foreach ( $hookNames as $name ) {
1076 'subscribers' => $hookContainer->getHandlerDescriptions( $name ),
1079 ApiResult::setArrayType( $arr[
'subscribers'],
'array' );
1080 ApiResult::setIndexedTagName( $arr[
'subscribers'],
's' );
1084 ApiResult::setIndexedTagName( $data,
'hook' );
1086 return $this->
getResult()->addValue(
'query', $property, $data );
1091 if ( $this->
getConfig()->
get( MainConfigNames::ExtraInterlanguageLinkPrefixes ) &&
1092 in_array(
'interwikimap',
$params[
'prop'] ?? [] )
1094 return 'anon-public-user-private';
1103 ParamValidator::PARAM_DEFAULT =>
'general',
1104 ParamValidator::PARAM_ISMULTI =>
true,
1105 ParamValidator::PARAM_TYPE => [
1109 'specialpagealiases',
1115 'autocreatetempuser',
1138 ParamValidator::PARAM_TYPE => [
1143 'showalldb' =>
false,
1144 'numberingroup' =>
false,
1145 'inlanguagecode' =>
null,
1151 'action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics'
1152 =>
'apihelp-query+siteinfo-example-simple',
1153 'action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local'
1154 =>
'apihelp-query+siteinfo-example-interwiki',
1155 'action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb='
1156 =>
'apihelp-query+siteinfo-example-replag',
1161 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.