MediaWiki  master
ApiQuery.php
Go to the documentation of this file.
1 <?php
24 use Wikimedia\ObjectFactory;
27 
39 class ApiQuery extends ApiBase {
40 
44  private const QUERY_PROP_MODULES = [
45  'categories' => [
46  'class' => ApiQueryCategories::class,
47  ],
48  'categoryinfo' => [
49  'class' => ApiQueryCategoryInfo::class,
50  ],
51  'contributors' => [
52  'class' => ApiQueryContributors::class,
53  'services' => [
54  'RevisionStore',
55  'ActorMigration',
56  'UserGroupManager',
57  'GroupPermissionsLookup',
58  ]
59  ],
60  'deletedrevisions' => [
61  'class' => ApiQueryDeletedRevisions::class,
62  'services' => [
63  'RevisionStore',
64  'ContentHandlerFactory',
65  'ParserFactory',
66  'SlotRoleRegistry',
67  'ChangeTagDefStore',
68  'LinkBatchFactory',
69  'ContentRenderer',
70  'ContentTransformer',
71  ]
72  ],
73  'duplicatefiles' => [
74  'class' => ApiQueryDuplicateFiles::class,
75  'services' => [
76  'RepoGroup',
77  ]
78  ],
79  'extlinks' => [
80  'class' => ApiQueryExternalLinks::class,
81  ],
82  'fileusage' => [
83  'class' => ApiQueryBacklinksprop::class,
84  ],
85  'images' => [
86  'class' => ApiQueryImages::class,
87  ],
88  'imageinfo' => [
89  'class' => ApiQueryImageInfo::class,
90  'services' => [
91  // Same as for stashimageinfo
92  'RepoGroup',
93  'ContentLanguage',
94  'BadFileLookup',
95  ]
96  ],
97  'info' => [
98  'class' => ApiQueryInfo::class,
99  'services' => [
100  'ContentLanguage',
101  'LinkBatchFactory',
102  'NamespaceInfo',
103  'TitleFactory',
104  'TitleFormatter',
105  'WatchedItemStore',
106  'LanguageConverterFactory',
107  ],
108  ],
109  'links' => [
110  'class' => ApiQueryLinks::class,
111  'services' => [
112  'LinkBatchFactory',
113  ]
114  ],
115  'linkshere' => [
116  'class' => ApiQueryBacklinksprop::class,
117  ],
118  'iwlinks' => [
119  'class' => ApiQueryIWLinks::class,
120  ],
121  'langlinks' => [
122  'class' => ApiQueryLangLinks::class,
123  'services' => [
124  'LanguageNameUtils',
125  'ContentLanguage',
126  ]
127  ],
128  'pageprops' => [
129  'class' => ApiQueryPageProps::class,
130  'services' => [
131  'PageProps',
132  ]
133  ],
134  'redirects' => [
135  'class' => ApiQueryBacklinksprop::class,
136  ],
137  'revisions' => [
138  'class' => ApiQueryRevisions::class,
139  'services' => [
140  'RevisionStore',
141  'ContentHandlerFactory',
142  'ParserFactory',
143  'SlotRoleRegistry',
144  'ChangeTagDefStore',
145  'ActorMigration',
146  'ContentRenderer',
147  'ContentTransformer',
148  ]
149  ],
150  'stashimageinfo' => [
151  'class' => ApiQueryStashImageInfo::class,
152  'services' => [
153  // Same as for imageinfo
154  'RepoGroup',
155  'ContentLanguage',
156  'BadFileLookup',
157  ]
158  ],
159  'templates' => [
160  'class' => ApiQueryLinks::class,
161  'services' => [
162  'LinkBatchFactory',
163  ]
164  ],
165  'transcludedin' => [
166  'class' => ApiQueryBacklinksprop::class,
167  ],
168  ];
169 
173  private const QUERY_LIST_MODULES = [
174  'allcategories' => [
175  'class' => ApiQueryAllCategories::class,
176  ],
177  'alldeletedrevisions' => [
178  'class' => ApiQueryAllDeletedRevisions::class,
179  'services' => [
180  'RevisionStore',
181  'ContentHandlerFactory',
182  'ParserFactory',
183  'SlotRoleRegistry',
184  'ChangeTagDefStore',
185  'NamespaceInfo',
186  'ContentRenderer',
187  'ContentTransformer',
188  ]
189  ],
190  'allfileusages' => [
191  'class' => ApiQueryAllLinks::class,
192  'services' => [
193  // Same as for alllinks, allredirects, alltransclusions
194  'NamespaceInfo',
195  'GenderCache',
196  ]
197  ],
198  'allimages' => [
199  'class' => ApiQueryAllImages::class,
200  'services' => [
201  'RepoGroup',
202  'GroupPermissionsLookup',
203  ]
204  ],
205  'alllinks' => [
206  'class' => ApiQueryAllLinks::class,
207  'services' => [
208  // Same as for allfileusages, allredirects, alltransclusions
209  'NamespaceInfo',
210  'GenderCache',
211  ]
212  ],
213  'allpages' => [
214  'class' => ApiQueryAllPages::class,
215  'services' => [
216  'NamespaceInfo',
217  'GenderCache',
218  ]
219  ],
220  'allredirects' => [
221  'class' => ApiQueryAllLinks::class,
222  'services' => [
223  // Same as for allfileusages, alllinks, alltransclusions
224  'NamespaceInfo',
225  'GenderCache',
226  ]
227  ],
228  'allrevisions' => [
229  'class' => ApiQueryAllRevisions::class,
230  'services' => [
231  'RevisionStore',
232  'ContentHandlerFactory',
233  'ParserFactory',
234  'SlotRoleRegistry',
235  'ActorMigration',
236  'NamespaceInfo',
237  'ContentRenderer',
238  'ContentTransformer',
239  ]
240  ],
241  'mystashedfiles' => [
242  'class' => ApiQueryMyStashedFiles::class,
243  ],
244  'alltransclusions' => [
245  'class' => ApiQueryAllLinks::class,
246  'services' => [
247  // Same as for allfileusages, alllinks, allredirects
248  'NamespaceInfo',
249  'GenderCache',
250  ]
251  ],
252  'allusers' => [
253  'class' => ApiQueryAllUsers::class,
254  'services' => [
255  'UserFactory',
256  'UserGroupManager',
257  'GroupPermissionsLookup',
258  'ContentLanguage',
259  ]
260  ],
261  'backlinks' => [
262  'class' => ApiQueryBacklinks::class,
263  ],
264  'blocks' => [
265  'class' => ApiQueryBlocks::class,
266  'services' => [
267  'BlockActionInfo',
268  'BlockRestrictionStore',
269  'CommentStore',
270  'UserNameUtils',
271  ],
272  ],
273  'categorymembers' => [
274  'class' => ApiQueryCategoryMembers::class,
275  'services' => [
276  'CollationFactory',
277  ]
278  ],
279  'deletedrevs' => [
280  'class' => ApiQueryDeletedrevs::class,
281  'services' => [
282  'CommentStore',
283  'RowCommentFormatter',
284  'RevisionStore',
285  'ChangeTagDefStore',
286  'LinkBatchFactory',
287  ],
288  ],
289  'embeddedin' => [
290  'class' => ApiQueryBacklinks::class,
291  ],
292  'exturlusage' => [
293  'class' => ApiQueryExtLinksUsage::class,
294  ],
295  'filearchive' => [
296  'class' => ApiQueryFilearchive::class,
297  'services' => [
298  'CommentStore',
299  'CommentFormatter',
300  ],
301  ],
302  'imageusage' => [
303  'class' => ApiQueryBacklinks::class,
304  ],
305  'iwbacklinks' => [
306  'class' => ApiQueryIWBacklinks::class,
307  ],
308  'langbacklinks' => [
309  'class' => ApiQueryLangBacklinks::class,
310  ],
311  'logevents' => [
312  'class' => ApiQueryLogEvents::class,
313  'services' => [
314  'CommentStore',
315  'RowCommentFormatter',
316  'ChangeTagDefStore',
317  ],
318  ],
319  'pageswithprop' => [
320  'class' => ApiQueryPagesWithProp::class,
321  ],
322  'pagepropnames' => [
323  'class' => ApiQueryPagePropNames::class,
324  ],
325  'prefixsearch' => [
326  'class' => ApiQueryPrefixSearch::class,
327  'services' => [
328  'SearchEngineConfig',
329  'SearchEngineFactory',
330  ],
331  ],
332  'protectedtitles' => [
333  'class' => ApiQueryProtectedTitles::class,
334  'services' => [
335  'CommentStore',
336  'RowCommentFormatter'
337  ],
338  ],
339  'querypage' => [
340  'class' => ApiQueryQueryPage::class,
341  'services' => [
342  'SpecialPageFactory',
343  ]
344  ],
345  'random' => [
346  'class' => ApiQueryRandom::class,
347  ],
348  'recentchanges' => [
349  'class' => ApiQueryRecentChanges::class,
350  'services' => [
351  'CommentStore',
352  'RowCommentFormatter',
353  'ChangeTagDefStore',
354  'SlotRoleStore',
355  'SlotRoleRegistry',
356  ],
357  ],
358  'search' => [
359  'class' => ApiQuerySearch::class,
360  'services' => [
361  'SearchEngineConfig',
362  'SearchEngineFactory',
363  ],
364  ],
365  'tags' => [
366  'class' => ApiQueryTags::class,
367  ],
368  'usercontribs' => [
369  'class' => ApiQueryUserContribs::class,
370  'services' => [
371  'CommentStore',
372  'UserIdentityLookup',
373  'UserNameUtils',
374  'RevisionStore',
375  'ChangeTagDefStore',
376  'ActorMigration',
377  ],
378  ],
379  'users' => [
380  'class' => ApiQueryUsers::class,
381  'services' => [
382  'UserNameUtils',
383  'UserFactory',
384  'UserGroupManager',
385  'UserOptionsLookup',
386  'AuthManager',
387  ],
388  ],
389  'watchlist' => [
390  'class' => ApiQueryWatchlist::class,
391  'services' => [
392  'CommentStore',
393  'WatchedItemQueryService',
394  'ContentLanguage',
395  'NamespaceInfo',
396  'GenderCache',
397  ],
398  ],
399  'watchlistraw' => [
400  'class' => ApiQueryWatchlistRaw::class,
401  'services' => [
402  'WatchedItemQueryService',
403  'ContentLanguage',
404  'NamespaceInfo',
405  'GenderCache',
406  ]
407  ],
408  ];
409 
413  private const QUERY_META_MODULES = [
414  'allmessages' => [
415  'class' => ApiQueryAllMessages::class,
416  'services' => [
417  'ContentLanguage',
418  'LanguageFactory',
419  'LanguageNameUtils',
420  'LocalisationCache',
421  'MessageCache',
422  ]
423  ],
424  'authmanagerinfo' => [
425  'class' => ApiQueryAuthManagerInfo::class,
426  'services' => [
427  'AuthManager',
428  ]
429  ],
430  'siteinfo' => [
431  'class' => ApiQuerySiteinfo::class,
432  'services' => [
433  'UserOptionsLookup',
434  'UserGroupManager',
435  'LanguageConverterFactory',
436  'LanguageFactory',
437  'LanguageNameUtils',
438  'ContentLanguage',
439  'NamespaceInfo',
440  'InterwikiLookup',
441  'Parser',
442  'MagicWordFactory',
443  'SpecialPageFactory',
444  'SkinFactory',
445  'DBLoadBalancer',
446  'ReadOnlyMode',
447  ]
448  ],
449  'userinfo' => [
450  'class' => ApiQueryUserInfo::class,
451  'services' => [
452  'TalkPageNotificationManager',
453  'WatchedItemStore',
454  'UserEditTracker',
455  'UserOptionsLookup',
456  'UserGroupManager',
457  ]
458  ],
459  'filerepoinfo' => [
460  'class' => ApiQueryFileRepoInfo::class,
461  'services' => [
462  'RepoGroup',
463  ]
464  ],
465  'tokens' => [
466  'class' => ApiQueryTokens::class,
467  ],
468  'languageinfo' => [
469  'class' => ApiQueryLanguageinfo::class,
470  'services' => [
471  'LanguageFactory',
472  'LanguageNameUtils',
473  'LanguageFallback',
474  'LanguageConverterFactory',
475  ],
476  ],
477  ];
478 
482  private $mPageSet;
483 
484  private $mParams;
485  private $mNamedDB = [];
486  private $mModuleMgr;
487 
489  private $loadBalancer;
490 
493 
501  public function __construct(
502  ApiMain $main,
503  $action,
504  ObjectFactory $objectFactory,
507  ) {
508  parent::__construct( $main, $action );
509 
510  $this->mModuleMgr = new ApiModuleManager(
511  $this,
512  $objectFactory
513  );
514 
515  // Allow custom modules to be added in LocalSettings.php
516  $config = $this->getConfig();
517  $this->mModuleMgr->addModules( self::QUERY_PROP_MODULES, 'prop' );
518  $this->mModuleMgr->addModules( $config->get( 'APIPropModules' ), 'prop' );
519  $this->mModuleMgr->addModules( self::QUERY_LIST_MODULES, 'list' );
520  $this->mModuleMgr->addModules( $config->get( 'APIListModules' ), 'list' );
521  $this->mModuleMgr->addModules( self::QUERY_META_MODULES, 'meta' );
522  $this->mModuleMgr->addModules( $config->get( 'APIMetaModules' ), 'meta' );
523 
524  $this->getHookRunner()->onApiQuery__moduleManager( $this->mModuleMgr );
525 
526  // Create PageSet that will process titles/pageids/revids/generator
527  $this->mPageSet = new ApiPageSet( $this );
528  $this->loadBalancer = $loadBalancer;
529  $this->wikiExporterFactory = $wikiExporterFactory;
530  }
531 
536  public function getModuleManager() {
537  return $this->mModuleMgr;
538  }
539 
550  public function getNamedDB( $name, $db, $groups ) {
551  if ( !array_key_exists( $name, $this->mNamedDB ) ) {
552  $this->mNamedDB[$name] = $this->loadBalancer->getConnectionRef( $db, $groups );
553  }
554 
555  return $this->mNamedDB[$name];
556  }
557 
562  public function getPageSet() {
563  return $this->mPageSet;
564  }
565 
569  public function getCustomPrinter() {
570  // If &exportnowrap is set, use the raw formatter
571  if ( $this->getParameter( 'export' ) &&
572  $this->getParameter( 'exportnowrap' )
573  ) {
574  return new ApiFormatRaw( $this->getMain(),
575  $this->getMain()->createPrinterByName( 'xml' ) );
576  } else {
577  return null;
578  }
579  }
580 
591  public function execute() {
592  $this->mParams = $this->extractRequestParams();
593 
594  // Instantiate requested modules
595  $allModules = [];
596  $this->instantiateModules( $allModules, 'prop' );
597  $propModules = array_keys( $allModules );
598  $this->instantiateModules( $allModules, 'list' );
599  $this->instantiateModules( $allModules, 'meta' );
600 
601  // Filter modules based on continue parameter
602  $continuationManager = new ApiContinuationManager( $this, $allModules, $propModules );
603  $this->setContinuationManager( $continuationManager );
605  $modules = $continuationManager->getRunModules();
606  '@phan-var ApiQueryBase[] $modules';
607 
608  if ( !$continuationManager->isGeneratorDone() ) {
609  // Query modules may optimize data requests through the $this->getPageSet()
610  // object by adding extra fields from the page table.
611  foreach ( $modules as $module ) {
612  $module->requestExtraData( $this->mPageSet );
613  }
614  // Populate page/revision information
615  $this->mPageSet->execute();
616  // Record page information (title, namespace, if exists, etc)
617  $this->outputGeneralPageInfo();
618  } else {
619  $this->mPageSet->executeDryRun();
620  }
621 
622  $cacheMode = $this->mPageSet->getCacheMode();
623 
624  // Execute all unfinished modules
625  foreach ( $modules as $module ) {
626  $params = $module->extractRequestParams();
627  $cacheMode = $this->mergeCacheMode(
628  $cacheMode, $module->getCacheMode( $params ) );
629  $module->execute();
630  $this->getHookRunner()->onAPIQueryAfterExecute( $module );
631  }
632 
633  // Set the cache mode
634  $this->getMain()->setCacheMode( $cacheMode );
635 
636  // Write the continuation data into the result
637  $this->setContinuationManager( null );
638  if ( $this->mParams['rawcontinue'] ) {
639  $data = $continuationManager->getRawNonContinuation();
640  if ( $data ) {
641  $this->getResult()->addValue( null, 'query-noncontinue', $data,
643  }
644  $data = $continuationManager->getRawContinuation();
645  if ( $data ) {
646  $this->getResult()->addValue( null, 'query-continue', $data,
648  }
649  } else {
650  $continuationManager->setContinuationIntoResult( $this->getResult() );
651  }
652  }
653 
663  protected function mergeCacheMode( $cacheMode, $modCacheMode ) {
664  if ( $modCacheMode === 'anon-public-user-private' ) {
665  if ( $cacheMode !== 'private' ) {
666  $cacheMode = 'anon-public-user-private';
667  }
668  } elseif ( $modCacheMode === 'public' ) {
669  // do nothing, if it's public already it will stay public
670  } else {
671  $cacheMode = 'private';
672  }
673 
674  return $cacheMode;
675  }
676 
682  private function instantiateModules( &$modules, $param ) {
683  $wasPosted = $this->getRequest()->wasPosted();
684  if ( isset( $this->mParams[$param] ) ) {
685  foreach ( $this->mParams[$param] as $moduleName ) {
686  $instance = $this->mModuleMgr->getModule( $moduleName, $param );
687  if ( $instance === null ) {
688  ApiBase::dieDebug( __METHOD__, 'Error instantiating module' );
689  }
690  if ( !$wasPosted && $instance->mustBePosted() ) {
691  $this->dieWithErrorOrDebug( [ 'apierror-mustbeposted', $moduleName ] );
692  }
693  // Ignore duplicates. TODO 2.0: die()?
694  if ( !array_key_exists( $moduleName, $modules ) ) {
695  $modules[$moduleName] = $instance;
696  }
697  }
698  }
699  }
700 
706  private function outputGeneralPageInfo() {
707  $pageSet = $this->getPageSet();
708  $result = $this->getResult();
709 
710  // We can't really handle max-result-size failure here, but we need to
711  // check anyway in case someone set the limit stupidly low.
712  $fit = true;
713 
714  $values = $pageSet->getNormalizedTitlesAsResult( $result );
715  if ( $values ) {
716  // @phan-suppress-next-line PhanRedundantCondition
717  $fit = $fit && $result->addValue( 'query', 'normalized', $values );
718  }
719  $values = $pageSet->getConvertedTitlesAsResult( $result );
720  if ( $values ) {
721  $fit = $fit && $result->addValue( 'query', 'converted', $values );
722  }
723  $values = $pageSet->getInterwikiTitlesAsResult( $result, $this->mParams['iwurl'] );
724  if ( $values ) {
725  $fit = $fit && $result->addValue( 'query', 'interwiki', $values );
726  }
727  $values = $pageSet->getRedirectTitlesAsResult( $result );
728  if ( $values ) {
729  $fit = $fit && $result->addValue( 'query', 'redirects', $values );
730  }
731  $values = $pageSet->getMissingRevisionIDsAsResult( $result );
732  if ( $values ) {
733  $fit = $fit && $result->addValue( 'query', 'badrevids', $values );
734  }
735 
736  // Page elements
737  $pages = [];
738 
739  // Report any missing titles
740  foreach ( $pageSet->getMissingTitles() as $fakeId => $title ) {
741  $vals = [];
743  $vals['missing'] = true;
744  if ( $title->isKnown() ) {
745  $vals['known'] = true;
746  }
747  $pages[$fakeId] = $vals;
748  }
749  // Report any invalid titles
750  foreach ( $pageSet->getInvalidTitlesAndReasons() as $fakeId => $data ) {
751  $pages[$fakeId] = $data + [ 'invalid' => true ];
752  }
753  // Report any missing page ids
754  foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
755  $pages[$pageid] = [
756  'pageid' => $pageid,
757  'missing' => true,
758  ];
759  }
760  // Report special pages
762  foreach ( $pageSet->getSpecialTitles() as $fakeId => $title ) {
763  $vals = [];
765  $vals['special'] = true;
766  if ( !$title->isKnown() ) {
767  $vals['missing'] = true;
768  }
769  $pages[$fakeId] = $vals;
770  }
771 
772  // Output general page information for found titles
773  foreach ( $pageSet->getGoodTitles() as $pageid => $title ) {
774  $vals = [];
775  $vals['pageid'] = $pageid;
777  $pages[$pageid] = $vals;
778  }
779 
780  if ( count( $pages ) ) {
781  $pageSet->populateGeneratorData( $pages );
782  ApiResult::setArrayType( $pages, 'BCarray' );
783 
784  if ( $this->mParams['indexpageids'] ) {
785  $pageIDs = array_keys( ApiResult::stripMetadataNonRecursive( $pages ) );
786  // json treats all map keys as strings - converting to match
787  $pageIDs = array_map( 'strval', $pageIDs );
788  ApiResult::setIndexedTagName( $pageIDs, 'id' );
789  $fit = $fit && $result->addValue( 'query', 'pageids', $pageIDs );
790  }
791 
792  ApiResult::setIndexedTagName( $pages, 'page' );
793  $fit = $fit && $result->addValue( 'query', 'pages', $pages );
794  }
795 
796  if ( !$fit ) {
797  $this->dieWithError( 'apierror-badconfig-resulttoosmall', 'badconfig' );
798  }
799 
800  if ( $this->mParams['export'] ) {
801  $this->doExport( $pageSet, $result );
802  }
803  }
804 
809  private function doExport( $pageSet, $result ) {
810  $exportTitles = [];
811  $titles = $pageSet->getGoodPages();
812  if ( count( $titles ) ) {
814  foreach ( $titles as $title ) {
815  if ( $this->getAuthority()->authorizeRead( 'read', $title ) ) {
816  $exportTitles[] = $title;
817  }
818  }
819  }
820 
821  $exporter = $this->wikiExporterFactory->getWikiExporter( $this->getDB() );
822  $sink = new DumpStringOutput;
823  $exporter->setOutputSink( $sink );
824  $exporter->setSchemaVersion( $this->mParams['exportschema'] );
825  $exporter->openStream();
826  foreach ( $exportTitles as $title ) {
827  $exporter->pageByTitle( $title );
828  }
829  $exporter->closeStream();
830 
831  // Don't check the size of exported stuff
832  // It's not continuable, so it would cause more
833  // problems than it'd solve
834  if ( $this->mParams['exportnowrap'] ) {
835  $result->reset();
836  // Raw formatter will handle this
837  $result->addValue( null, 'text', $sink, ApiResult::NO_SIZE_CHECK );
838  $result->addValue( null, 'mime', 'text/xml', ApiResult::NO_SIZE_CHECK );
839  $result->addValue( null, 'filename', 'export.xml', ApiResult::NO_SIZE_CHECK );
840  } else {
841  $result->addValue( 'query', 'export', $sink, ApiResult::NO_SIZE_CHECK );
842  $result->addValue( 'query', ApiResult::META_BC_SUBELEMENTS, [ 'export' ] );
843  }
844  }
845 
846  public function getAllowedParams( $flags = 0 ) {
847  $result = [
848  'prop' => [
849  ApiBase::PARAM_ISMULTI => true,
850  ApiBase::PARAM_TYPE => 'submodule',
851  ],
852  'list' => [
853  ApiBase::PARAM_ISMULTI => true,
854  ApiBase::PARAM_TYPE => 'submodule',
855  ],
856  'meta' => [
857  ApiBase::PARAM_ISMULTI => true,
858  ApiBase::PARAM_TYPE => 'submodule',
859  ],
860  'indexpageids' => false,
861  'export' => false,
862  'exportnowrap' => false,
863  'exportschema' => [
866  ],
867  'iwurl' => false,
868  'continue' => [
869  ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
870  ],
871  'rawcontinue' => false,
872  ];
873  if ( $flags ) {
874  $result += $this->getPageSet()->getFinalParams( $flags );
875  }
876 
877  return $result;
878  }
879 
880  public function isReadMode() {
881  // We need to make an exception for certain meta modules that should be
882  // accessible even without the 'read' right. Restrict the exception as
883  // much as possible: no other modules allowed, and no pageset
884  // parameters either. We do allow the 'rawcontinue' and 'indexpageids'
885  // parameters since frameworks might add these unconditionally and they
886  // can't expose anything here.
887  $allowedParams = [ 'rawcontinue' => 1, 'indexpageids' => 1 ];
888  $this->mParams = $this->extractRequestParams();
889  $request = $this->getRequest();
890  foreach ( $this->mParams + $this->getPageSet()->extractRequestParams() as $param => $value ) {
891  $needed = $param === 'meta';
892  if ( !isset( $allowedParams[$param] ) && $request->getCheck( $param ) !== $needed ) {
893  return true;
894  }
895  }
896 
897  // Ask each module if it requires read mode. Any true => this returns
898  // true.
899  $modules = [];
900  $this->instantiateModules( $modules, 'meta' );
901  foreach ( $modules as $module ) {
902  if ( $module->isReadMode() ) {
903  return true;
904  }
905  }
906 
907  return false;
908  }
909 
910  protected function getExamplesMessages() {
911  return [
912  'action=query&prop=revisions&meta=siteinfo&' .
913  'titles=Main%20Page&rvprop=user|comment&continue='
914  => 'apihelp-query-example-revisions',
915  'action=query&generator=allpages&gapprefix=API/&prop=revisions&continue='
916  => 'apihelp-query-example-allpages',
917  ];
918  }
919 
920  public function getHelpUrls() {
921  return [
922  'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Query',
923  'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Meta',
924  'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Properties',
925  'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Lists',
926  ];
927  }
928 }
ApiMain
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:49
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:72
ApiQuery\isReadMode
isReadMode()
Indicates whether this module requires read rights.
Definition: ApiQuery.php:880
WikiExporter\schemaVersion
static schemaVersion()
Returns the default export schema version, as defined by the XmlDumpSchemaVersion setting.
Definition: WikiExporter.php:98
ApiQuery\$mParams
$mParams
Definition: ApiQuery.php:484
ApiQuery
This is the main query class.
Definition: ApiQuery.php:39
ApiQuery\getPageSet
getPageSet()
Gets the set of pages the user has requested (or generated)
Definition: ApiQuery.php:562
ApiQuery\$wikiExporterFactory
WikiExporterFactory $wikiExporterFactory
Definition: ApiQuery.php:492
ApiContinuationManager
This manages continuation state.
Definition: ApiContinuationManager.php:26
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1436
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:162
true
return true
Definition: router.php:90
ApiResult\META_BC_SUBELEMENTS
const META_BC_SUBELEMENTS
Key for the 'BC subelements' metadata item.
Definition: ApiResult.php:143
ApiBase\PARAM_TYPE
const PARAM_TYPE
Definition: ApiBase.php:81
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:628
ApiBase\dieWithErrorOrDebug
dieWithErrorOrDebug( $msg, $code=null, $data=null, $httpCode=null)
Will only set a warning instead of failing if the global $wgDebugAPI is set to true.
Definition: ApiBase.php:1608
ApiBase\setContinuationManager
setContinuationManager(ApiContinuationManager $manager=null)
Definition: ApiBase.php:672
ApiQuery\QUERY_LIST_MODULES
const QUERY_LIST_MODULES
List of Api Query list modules.
Definition: ApiQuery.php:173
ApiBase\getDB
getDB()
Gets a default replica DB connection object.
Definition: ApiBase.php:651
ApiResult\NO_SIZE_CHECK
const NO_SIZE_CHECK
For addValue() and similar functions, do not check size while adding a value Don't use this unless yo...
Definition: ApiResult.php:58
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:81
XmlDumpWriter\$supportedSchemas
static string[] $supportedSchemas
the schema versions supported for output @final
Definition: XmlDumpWriter.php:57
ApiQuery\getHelpUrls
getHelpUrls()
Return links to more detailed help pages about the module.
Definition: ApiQuery.php:920
ApiPageSet
This class contains a list of pages that the client has requested.
Definition: ApiPageSet.php:45
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:55
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
ApiQuery\QUERY_META_MODULES
const QUERY_META_MODULES
List of Api Query meta modules.
Definition: ApiQuery.php:413
MediaWiki\Export\WikiExporterFactory
Factory service for WikiExporter instances.
Definition: WikiExporterFactory.php:35
ApiResult\setArrayType
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
Definition: ApiResult.php:715
$modules
$modules
Definition: HTMLFormElement.php:15
ApiFormatRaw
Formatter that spits out anything you like with any desired MIME type.
Definition: ApiFormatRaw.php:27
ApiQuery\getNamedDB
getNamedDB( $name, $db, $groups)
Get the query database connection with the given name.
Definition: ApiQuery.php:550
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:764
ApiResult\stripMetadataNonRecursive
static stripMetadataNonRecursive( $data, &$metadata=null)
Remove metadata keys from a data array or object, non-recursive.
Definition: ApiResult.php:1045
$title
$title
Definition: testCompression.php:38
ApiQuery\$loadBalancer
ILoadBalancer $loadBalancer
Definition: ApiQuery.php:489
ApiModuleManager
This class holds a list of modules and handles instantiation.
Definition: ApiModuleManager.php:33
ApiResult\setIndexedTagName
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:603
ContextSource\getAuthority
getAuthority()
Definition: ContextSource.php:144
ApiQuery\doExport
doExport( $pageSet, $result)
Definition: ApiQuery.php:809
ApiQuery\getModuleManager
getModuleManager()
Overrides to return this instance's module manager.
Definition: ApiQuery.php:536
Title
Represents a title within MediaWiki.
Definition: Title.php:47
ApiQuery\getCustomPrinter
getCustomPrinter()
Definition: ApiQuery.php:569
ApiResult\ADD_ON_TOP
const ADD_ON_TOP
For addValue(), setValue() and similar functions, if the value does not exist, add it as the first el...
Definition: ApiResult.php:49
ApiQuery\QUERY_PROP_MODULES
const QUERY_PROP_MODULES
List of Api Query prop modules.
Definition: ApiQuery.php:44
ApiQuery\__construct
__construct(ApiMain $main, $action, ObjectFactory $objectFactory, ILoadBalancer $loadBalancer, WikiExporterFactory $wikiExporterFactory)
Definition: ApiQuery.php:501
ApiQuery\mergeCacheMode
mergeCacheMode( $cacheMode, $modCacheMode)
Update a cache mode string, applying the cache mode of a new module to it.
Definition: ApiQuery.php:663
ApiQuery\$mPageSet
ApiPageSet $mPageSet
Definition: ApiQuery.php:482
ApiBase\PARAM_DFLT
const PARAM_DFLT
Definition: ApiBase.php:73
ApiQuery\outputGeneralPageInfo
outputGeneralPageInfo()
Appends an element for each page in the current pageSet with the most general information (id,...
Definition: ApiQuery.php:706
ApiQuery\getAllowedParams
getAllowedParams( $flags=0)
Definition: ApiQuery.php:846
ApiBase\getParameter
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
Definition: ApiBase.php:884
ApiQuery\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiQuery.php:910
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
Definition: ApiBase.php:77
ApiQuery\$mModuleMgr
$mModuleMgr
Definition: ApiQuery.php:486
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:513
ApiBase\getHookRunner
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition: ApiBase.php:710
ApiQuery\execute
execute()
Query execution happens in the following steps: #1 Create a PageSet object with any pages requested b...
Definition: ApiQuery.php:591
ApiBase\dieDebug
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
Definition: ApiBase.php:1639
ApiQuery\$mNamedDB
$mNamedDB
Definition: ApiQuery.php:485
DumpStringOutput
Definition: DumpStringOutput.php:27
ApiQuery\instantiateModules
instantiateModules(&$modules, $param)
Create instances of all modules requested by the client.
Definition: ApiQuery.php:682
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
ApiQueryBase\addTitleInfo
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
Definition: ApiQueryBase.php:466