44 'class' => ApiQueryCategories::class,
47 'class' => ApiQueryCategoryInfo::class,
50 'class' => ApiQueryContributors::class,
55 'GroupPermissionsLookup',
58 'deletedrevisions' => [
59 'class' => ApiQueryDeletedRevisions::class,
62 'ContentHandlerFactory',
71 'class' => ApiQueryDuplicateFiles::class,
77 'class' => ApiQueryExternalLinks::class,
80 'class' => ApiQueryBacklinksprop::class,
83 'class' => ApiQueryImages::class,
86 'class' => ApiQueryImageInfo::class,
95 'class' => ApiQueryInfo::class,
103 'LanguageConverterFactory',
107 'class' => ApiQueryLinks::class,
113 'class' => ApiQueryBacklinksprop::class,
116 'class' => ApiQueryIWLinks::class,
119 'class' => ApiQueryLangLinks::class,
126 'class' => ApiQueryPageProps::class,
132 'class' => ApiQueryBacklinksprop::class,
135 'class' => ApiQueryRevisions::class,
138 'ContentHandlerFactory',
143 'ContentTransformer',
146 'stashimageinfo' => [
147 'class' => ApiQueryStashImageInfo::class,
156 'class' => ApiQueryLinks::class,
162 'class' => ApiQueryBacklinksprop::class,
171 'class' => ApiQueryAllCategories::class,
173 'alldeletedrevisions' => [
174 'class' => ApiQueryAllDeletedRevisions::class,
177 'ContentHandlerFactory',
182 'ContentTransformer',
186 'class' => ApiQueryAllLinks::class,
194 'class' => ApiQueryAllImages::class,
197 'GroupPermissionsLookup',
201 'class' => ApiQueryAllLinks::class,
209 'class' => ApiQueryAllPages::class,
216 'class' => ApiQueryAllLinks::class,
224 'class' => ApiQueryAllRevisions::class,
227 'ContentHandlerFactory',
232 'ContentTransformer',
235 'mystashedfiles' => [
236 'class' => ApiQueryMyStashedFiles::class,
238 'alltransclusions' => [
239 'class' => ApiQueryAllLinks::class,
247 'class' => ApiQueryAllUsers::class,
251 'GroupPermissionsLookup',
255 'class' => ApiQueryBacklinks::class,
258 'class' => ApiQueryBlocks::class,
261 'BlockRestrictionStore',
266 'categorymembers' => [
267 'class' => ApiQueryCategoryMembers::class,
273 'class' => ApiQueryDeletedrevs::class,
282 'class' => ApiQueryBacklinks::class,
285 'class' => ApiQueryExtLinksUsage::class,
288 'class' => ApiQueryFilearchive::class,
294 'class' => ApiQueryBacklinks::class,
297 'class' => ApiQueryIWBacklinks::class,
300 'class' => ApiQueryLangBacklinks::class,
303 'class' => ApiQueryLogEvents::class,
310 'class' => ApiQueryPagesWithProp::class,
313 'class' => ApiQueryPagePropNames::class,
316 'class' => ApiQueryPrefixSearch::class,
318 'SearchEngineConfig',
319 'SearchEngineFactory',
322 'protectedtitles' => [
323 'class' => ApiQueryProtectedTitles::class,
329 'class' => ApiQueryQueryPage::class,
331 'SpecialPageFactory',
335 'class' => ApiQueryRandom::class,
338 'class' => ApiQueryRecentChanges::class,
347 'class' => ApiQuerySearch::class,
349 'SearchEngineConfig',
350 'SearchEngineFactory',
354 'class' => ApiQueryTags::class,
357 'class' => ApiQueryUserContribs::class,
360 'UserIdentityLookup',
368 'class' => ApiQueryUsers::class,
378 'class' => ApiQueryWatchlist::class,
381 'WatchedItemQueryService',
388 'class' => ApiQueryWatchlistRaw::class,
390 'WatchedItemQueryService',
403 'class' => ApiQueryAllMessages::class,
412 'authmanagerinfo' => [
413 'class' => ApiQueryAuthManagerInfo::class,
419 'class' => ApiQuerySiteinfo::class,
423 'LanguageConverterFactory',
431 'SpecialPageFactory',
438 'class' => ApiQueryUserInfo::class,
440 'TalkPageNotificationManager',
448 'class' => ApiQueryFileRepoInfo::class,
454 'class' => ApiQueryTokens::class,
457 'class' => ApiQueryLanguageinfo::class,
462 'LanguageConverterFactory',
481 parent::__construct( $main, $action );
485 MediaWikiServices::getInstance()->getObjectFactory()
490 $this->mModuleMgr->addModules( self::QUERY_PROP_MODULES,
'prop' );
491 $this->mModuleMgr->addModules( $config->get(
'APIPropModules' ),
'prop' );
492 $this->mModuleMgr->addModules( self::QUERY_LIST_MODULES,
'list' );
493 $this->mModuleMgr->addModules( $config->get(
'APIListModules' ),
'list' );
494 $this->mModuleMgr->addModules( self::QUERY_META_MODULES,
'meta' );
495 $this->mModuleMgr->addModules( $config->get(
'APIMetaModules' ),
'meta' );
497 $this->
getHookRunner()->onApiQuery__moduleManager( $this->mModuleMgr );
522 if ( !array_key_exists( $name, $this->mNamedDB ) ) {
523 $this->mNamedDB[$name] =
wfGetDB( $db, $groups );
526 return $this->mNamedDB[$name];
546 $this->
getMain()->createPrinterByName(
'xml' ) );
568 $propModules = array_keys( $allModules );
576 $modules = $continuationManager->getRunModules();
577 '@phan-var ApiQueryBase[] $modules';
579 if ( !$continuationManager->isGeneratorDone() ) {
583 $module->requestExtraData( $this->mPageSet );
586 $this->mPageSet->execute();
590 $this->mPageSet->executeDryRun();
593 $cacheMode = $this->mPageSet->getCacheMode();
597 $params = $module->extractRequestParams();
599 $cacheMode, $module->getCacheMode( $params ) );
605 $this->
getMain()->setCacheMode( $cacheMode );
609 if ( $this->mParams[
'rawcontinue'] ) {
610 $data = $continuationManager->getRawNonContinuation();
612 $this->
getResult()->addValue(
null,
'query-noncontinue', $data,
613 ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
615 $data = $continuationManager->getRawContinuation();
617 $this->
getResult()->addValue(
null,
'query-continue', $data,
618 ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
621 $continuationManager->setContinuationIntoResult( $this->
getResult() );
635 if ( $modCacheMode ===
'anon-public-user-private' ) {
636 if ( $cacheMode !==
'private' ) {
637 $cacheMode =
'anon-public-user-private';
639 } elseif ( $modCacheMode ===
'public' ) {
642 $cacheMode =
'private';
654 $wasPosted = $this->
getRequest()->wasPosted();
655 if ( isset( $this->mParams[$param] ) ) {
656 foreach ( $this->mParams[$param] as $moduleName ) {
657 $instance = $this->mModuleMgr->getModule( $moduleName, $param );
658 if ( $instance ===
null ) {
661 if ( !$wasPosted && $instance->mustBePosted() ) {
665 if ( !array_key_exists( $moduleName,
$modules ) ) {
685 $values = $pageSet->getNormalizedTitlesAsResult( $result );
688 $fit = $fit && $result->addValue(
'query',
'normalized', $values );
690 $values = $pageSet->getConvertedTitlesAsResult( $result );
692 $fit = $fit && $result->addValue(
'query',
'converted', $values );
694 $values = $pageSet->getInterwikiTitlesAsResult( $result, $this->mParams[
'iwurl'] );
696 $fit = $fit && $result->addValue(
'query',
'interwiki', $values );
698 $values = $pageSet->getRedirectTitlesAsResult( $result );
700 $fit = $fit && $result->addValue(
'query',
'redirects', $values );
702 $values = $pageSet->getMissingRevisionIDsAsResult( $result );
704 $fit = $fit && $result->addValue(
'query',
'badrevids', $values );
711 foreach ( $pageSet->getMissingTitles() as $fakeId =>
$title ) {
713 ApiQueryBase::addTitleInfo( $vals,
$title );
714 $vals[
'missing'] =
true;
715 if (
$title->isKnown() ) {
716 $vals[
'known'] =
true;
718 $pages[$fakeId] = $vals;
721 foreach ( $pageSet->getInvalidTitlesAndReasons() as $fakeId => $data ) {
722 $pages[$fakeId] = $data + [
'invalid' =>
true ];
725 foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
733 foreach ( $pageSet->getSpecialTitles() as $fakeId =>
$title ) {
735 ApiQueryBase::addTitleInfo( $vals,
$title );
736 $vals[
'special'] =
true;
737 if ( !
$title->isKnown() ) {
738 $vals[
'missing'] =
true;
740 $pages[$fakeId] = $vals;
744 foreach ( $pageSet->getGoodTitles() as $pageid =>
$title ) {
746 $vals[
'pageid'] = $pageid;
747 ApiQueryBase::addTitleInfo( $vals,
$title );
748 $pages[$pageid] = $vals;
751 if ( count( $pages ) ) {
752 $pageSet->populateGeneratorData( $pages );
753 ApiResult::setArrayType( $pages,
'BCarray' );
755 if ( $this->mParams[
'indexpageids'] ) {
756 $pageIDs = array_keys( ApiResult::stripMetadataNonRecursive( $pages ) );
758 $pageIDs = array_map(
'strval', $pageIDs );
759 ApiResult::setIndexedTagName( $pageIDs,
'id' );
760 $fit = $fit && $result->addValue(
'query',
'pageids', $pageIDs );
763 ApiResult::setIndexedTagName( $pages,
'page' );
764 $fit = $fit && $result->addValue(
'query',
'pages', $pages );
768 $this->
dieWithError(
'apierror-badconfig-resulttoosmall',
'badconfig' );
771 if ( $this->mParams[
'export'] ) {
772 $this->
doExport( $pageSet, $result );
782 $titles = $pageSet->getGoodPages();
783 if ( count( $titles ) ) {
785 foreach ( $titles as
$title ) {
794 $exporter->setOutputSink( $sink );
795 $exporter->setSchemaVersion( $this->mParams[
'exportschema'] );
796 $exporter->openStream();
797 foreach ( $exportTitles as
$title ) {
798 $exporter->pageByTitle(
$title );
800 $exporter->closeStream();
805 if ( $this->mParams[
'exportnowrap'] ) {
808 $result->addValue(
null,
'text', $sink, ApiResult::NO_SIZE_CHECK );
809 $result->addValue(
null,
'mime',
'text/xml', ApiResult::NO_SIZE_CHECK );
810 $result->addValue(
null,
'filename',
'export.xml', ApiResult::NO_SIZE_CHECK );
812 $result->addValue(
'query',
'export', $sink, ApiResult::NO_SIZE_CHECK );
813 $result->addValue(
'query', ApiResult::META_BC_SUBELEMENTS, [
'export' ] );
831 'indexpageids' =>
false,
833 'exportnowrap' =>
false,
842 'rawcontinue' =>
false,
845 $result += $this->
getPageSet()->getFinalParams( $flags );
858 $allowedParams = [
'rawcontinue' => 1,
'indexpageids' => 1 ];
862 $needed = $param ===
'meta';
863 if ( !isset( $allowedParams[$param] ) && $request->getCheck( $param ) !== $needed ) {
873 if ( $module->isReadMode() ) {
883 'action=query&prop=revisions&meta=siteinfo&' .
884 'titles=Main%20Page&rvprop=user|comment&continue='
885 =>
'apihelp-query-example-revisions',
886 'action=query&generator=allpages&gapprefix=API/&prop=revisions&continue='
887 =>
'apihelp-query-example-allpages',
893 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Query',
894 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Meta',
895 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Properties',
896 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Lists',
This is the main API class, used for both external and internal processing.
This class contains a list of pages that the client has requested.