MediaWiki  master
ApiQuery.php
Go to the documentation of this file.
00001 <?php
00038 class ApiQuery extends ApiBase {
00039 
00040         private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
00041 
00045         private $mPageSet;
00046 
00047         private $params, $redirects, $convertTitles, $iwUrl;
00048 
00053         private $mQueryPropModules = array(
00054                 'categories' => 'ApiQueryCategories',
00055                 'categoryinfo' => 'ApiQueryCategoryInfo',
00056                 'duplicatefiles' => 'ApiQueryDuplicateFiles',
00057                 'extlinks' => 'ApiQueryExternalLinks',
00058                 'images' => 'ApiQueryImages',
00059                 'imageinfo' => 'ApiQueryImageInfo',
00060                 'info' => 'ApiQueryInfo',
00061                 'links' => 'ApiQueryLinks',
00062                 'iwlinks' => 'ApiQueryIWLinks',
00063                 'langlinks' => 'ApiQueryLangLinks',
00064                 'pageprops' => 'ApiQueryPageProps',
00065                 'revisions' => 'ApiQueryRevisions',
00066                 'stashimageinfo' => 'ApiQueryStashImageInfo',
00067                 'templates' => 'ApiQueryLinks',
00068         );
00069 
00074         private $mQueryListModules = array(
00075                 'allcategories' => 'ApiQueryAllCategories',
00076                 'allimages' => 'ApiQueryAllImages',
00077                 'alllinks' => 'ApiQueryAllLinks',
00078                 'allpages' => 'ApiQueryAllPages',
00079                 'allusers' => 'ApiQueryAllUsers',
00080                 'backlinks' => 'ApiQueryBacklinks',
00081                 'blocks' => 'ApiQueryBlocks',
00082                 'categorymembers' => 'ApiQueryCategoryMembers',
00083                 'deletedrevs' => 'ApiQueryDeletedrevs',
00084                 'embeddedin' => 'ApiQueryBacklinks',
00085                 'exturlusage' => 'ApiQueryExtLinksUsage',
00086                 'filearchive' => 'ApiQueryFilearchive',
00087                 'imageusage' => 'ApiQueryBacklinks',
00088                 'iwbacklinks' => 'ApiQueryIWBacklinks',
00089                 'langbacklinks' => 'ApiQueryLangBacklinks',
00090                 'logevents' => 'ApiQueryLogEvents',
00091                 'protectedtitles' => 'ApiQueryProtectedTitles',
00092                 'querypage' => 'ApiQueryQueryPage',
00093                 'random' => 'ApiQueryRandom',
00094                 'recentchanges' => 'ApiQueryRecentChanges',
00095                 'search' => 'ApiQuerySearch',
00096                 'tags' => 'ApiQueryTags',
00097                 'usercontribs' => 'ApiQueryContributions',
00098                 'users' => 'ApiQueryUsers',
00099                 'watchlist' => 'ApiQueryWatchlist',
00100                 'watchlistraw' => 'ApiQueryWatchlistRaw',
00101         );
00102 
00107         private $mQueryMetaModules = array(
00108                 'allmessages' => 'ApiQueryAllMessages',
00109                 'siteinfo' => 'ApiQuerySiteinfo',
00110                 'userinfo' => 'ApiQueryUserInfo',
00111         );
00112 
00119         private $mQueryGenerators = array(
00120                 'allcategories' => 'ApiQueryAllCategories',
00121                 'allimages' => 'ApiQueryAllImages',
00122                 'alllinks' => 'ApiQueryAllLinks',
00123                 'allpages' => 'ApiQueryAllPages',
00124                 'backlinks' => 'ApiQueryBacklinks',
00125                 'categories' => 'ApiQueryCategories',
00126                 'categorymembers' => 'ApiQueryCategoryMembers',
00127                 'duplicatefiles' => 'ApiQueryDuplicateFiles',
00128                 'embeddedin' => 'ApiQueryBacklinks',
00129                 'exturlusage' => 'ApiQueryExtLinksUsage',
00130                 'images' => 'ApiQueryImages',
00131                 'imageusage' => 'ApiQueryBacklinks',
00132                 'iwbacklinks' => 'ApiQueryIWBacklinks',
00133                 'langbacklinks' => 'ApiQueryLangBacklinks',
00134                 'links' => 'ApiQueryLinks',
00135                 'protectedtitles' => 'ApiQueryProtectedTitles',
00136                 'querypage' => 'ApiQueryQueryPage',
00137                 'random' => 'ApiQueryRandom',
00138                 'recentchanges' => 'ApiQueryRecentChanges',
00139                 'search' => 'ApiQuerySearch',
00140                 'templates' => 'ApiQueryLinks',
00141                 'watchlist' => 'ApiQueryWatchlist',
00142                 'watchlistraw' => 'ApiQueryWatchlistRaw',
00143         );
00144 
00145         private $mSlaveDB = null;
00146         private $mNamedDB = array();
00147 
00148         protected $mAllowedGenerators;
00149 
00154         public function __construct( $main, $action ) {
00155                 parent::__construct( $main, $action );
00156 
00157                 // Allow custom modules to be added in LocalSettings.php
00158                 global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules, $wgAPIGeneratorModules;
00159                 self::appendUserModules( $this->mQueryPropModules, $wgAPIPropModules );
00160                 self::appendUserModules( $this->mQueryListModules, $wgAPIListModules );
00161                 self::appendUserModules( $this->mQueryMetaModules, $wgAPIMetaModules );
00162                 self::appendUserModules( $this->mQueryGenerators, $wgAPIGeneratorModules );
00163 
00164                 $this->mPropModuleNames = array_keys( $this->mQueryPropModules );
00165                 $this->mListModuleNames = array_keys( $this->mQueryListModules );
00166                 $this->mMetaModuleNames = array_keys( $this->mQueryMetaModules );
00167                 $this->mAllowedGenerators = array_keys( $this->mQueryGenerators );
00168         }
00169 
00175         private static function appendUserModules( &$modules, $newModules ) {
00176                 if ( is_array( $newModules ) ) {
00177                         foreach ( $newModules as $moduleName => $moduleClass ) {
00178                                 $modules[$moduleName] = $moduleClass;
00179                         }
00180                 }
00181         }
00182 
00187         public function getDB() {
00188                 if ( !isset( $this->mSlaveDB ) ) {
00189                         $this->profileDBIn();
00190                         $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
00191                         $this->profileDBOut();
00192                 }
00193                 return $this->mSlaveDB;
00194         }
00195 
00206         public function getNamedDB( $name, $db, $groups ) {
00207                 if ( !array_key_exists( $name, $this->mNamedDB ) ) {
00208                         $this->profileDBIn();
00209                         $this->mNamedDB[$name] = wfGetDB( $db, $groups );
00210                         $this->profileDBOut();
00211                 }
00212                 return $this->mNamedDB[$name];
00213         }
00214 
00219         public function getPageSet() {
00220                 return $this->mPageSet;
00221         }
00222 
00227         public function getModules() {
00228                 return array_merge( $this->mQueryPropModules, $this->mQueryListModules, $this->mQueryMetaModules );
00229         }
00230 
00235         public function getGenerators() {
00236                 return $this->mQueryGenerators;
00237         }
00238 
00244         function getModuleType( $moduleName ) {
00245                 if ( isset( $this->mQueryPropModules[$moduleName] ) ) {
00246                         return 'prop';
00247                 }
00248 
00249                 if ( isset( $this->mQueryListModules[$moduleName] ) ) {
00250                         return 'list';
00251                 }
00252 
00253                 if ( isset( $this->mQueryMetaModules[$moduleName] ) ) {
00254                         return 'meta';
00255                 }
00256 
00257                 return null;
00258         }
00259 
00263         public function getCustomPrinter() {
00264                 // If &exportnowrap is set, use the raw formatter
00265                 if ( $this->getParameter( 'export' ) &&
00266                                 $this->getParameter( 'exportnowrap' ) )
00267                 {
00268                         return new ApiFormatRaw( $this->getMain(),
00269                                 $this->getMain()->createPrinterByName( 'xml' ) );
00270                 } else {
00271                         return null;
00272                 }
00273         }
00274 
00285         public function execute() {
00286                 $this->params = $this->extractRequestParams();
00287                 $this->redirects = $this->params['redirects'];
00288                 $this->convertTitles = $this->params['converttitles'];
00289                 $this->iwUrl = $this->params['iwurl'];
00290 
00291                 // Create PageSet
00292                 $this->mPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
00293 
00294                 // Instantiate requested modules
00295                 $modules = array();
00296                 $this->instantiateModules( $modules, 'prop', $this->mQueryPropModules );
00297                 $this->instantiateModules( $modules, 'list', $this->mQueryListModules );
00298                 $this->instantiateModules( $modules, 'meta', $this->mQueryMetaModules );
00299 
00300                 $cacheMode = 'public';
00301 
00302                 // If given, execute generator to substitute user supplied data with generated data.
00303                 if ( isset( $this->params['generator'] ) ) {
00304                         $generator = $this->newGenerator( $this->params['generator'] );
00305                         $params = $generator->extractRequestParams();
00306                         $cacheMode = $this->mergeCacheMode( $cacheMode,
00307                                 $generator->getCacheMode( $params ) );
00308                         $this->executeGeneratorModule( $generator, $modules );
00309                 } else {
00310                         // Append custom fields and populate page/revision information
00311                         $this->addCustomFldsToPageSet( $modules, $this->mPageSet );
00312                         $this->mPageSet->execute();
00313                 }
00314 
00315                 // Record page information (title, namespace, if exists, etc)
00316                 $this->outputGeneralPageInfo();
00317 
00318                 // Execute all requested modules.
00322                 foreach ( $modules as $module ) {
00323                         $params = $module->extractRequestParams();
00324                         $cacheMode = $this->mergeCacheMode(
00325                                 $cacheMode, $module->getCacheMode( $params ) );
00326                         $module->profileIn();
00327                         $module->execute();
00328                         wfRunHooks( 'APIQueryAfterExecute', array( &$module ) );
00329                         $module->profileOut();
00330                 }
00331 
00332                 // Set the cache mode
00333                 $this->getMain()->setCacheMode( $cacheMode );
00334         }
00335 
00345         protected function mergeCacheMode( $cacheMode, $modCacheMode ) {
00346                 if ( $modCacheMode === 'anon-public-user-private' ) {
00347                         if ( $cacheMode !== 'private' ) {
00348                                 $cacheMode = 'anon-public-user-private';
00349                         }
00350                 } elseif ( $modCacheMode === 'public' ) {
00351                         // do nothing, if it's public already it will stay public
00352                 } else { // private
00353                         $cacheMode = 'private';
00354                 }
00355                 return $cacheMode;
00356         }
00357 
00365         private function addCustomFldsToPageSet( $modules, $pageSet ) {
00366                 // Query all requested modules.
00370                 foreach ( $modules as $module ) {
00371                         $module->requestExtraData( $pageSet );
00372                 }
00373         }
00374 
00381         private function instantiateModules( &$modules, $param, $moduleList ) {
00382                 if ( isset( $this->params[$param] ) ) {
00383                         foreach ( $this->params[$param] as $moduleName ) {
00384                                 $modules[] = new $moduleList[$moduleName] ( $this, $moduleName );
00385                         }
00386                 }
00387         }
00388 
00394         private function outputGeneralPageInfo() {
00395                 $pageSet = $this->getPageSet();
00396                 $result = $this->getResult();
00397 
00398                 // We don't check for a full result set here because we can't be adding
00399                 // more than 380K. The maximum revision size is in the megabyte range,
00400                 // and the maximum result size must be even higher than that.
00401 
00402                 // Title normalizations
00403                 $normValues = array();
00404                 foreach ( $pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
00405                         $normValues[] = array(
00406                                 'from' => $rawTitleStr,
00407                                 'to' => $titleStr
00408                         );
00409                 }
00410 
00411                 if ( count( $normValues ) ) {
00412                         $result->setIndexedTagName( $normValues, 'n' );
00413                         $result->addValue( 'query', 'normalized', $normValues );
00414                 }
00415 
00416                 // Title conversions
00417                 $convValues = array();
00418                 foreach ( $pageSet->getConvertedTitles() as $rawTitleStr => $titleStr ) {
00419                         $convValues[] = array(
00420                                 'from' => $rawTitleStr,
00421                                 'to' => $titleStr
00422                         );
00423                 }
00424 
00425                 if ( count( $convValues ) ) {
00426                         $result->setIndexedTagName( $convValues, 'c' );
00427                         $result->addValue( 'query', 'converted', $convValues );
00428                 }
00429 
00430                 // Interwiki titles
00431                 $intrwValues = array();
00432                 foreach ( $pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
00433                         $item = array(
00434                                 'title' => $rawTitleStr,
00435                                 'iw' => $interwikiStr,
00436                         );
00437                         if ( $this->iwUrl ) {
00438                                 $title = Title::newFromText( $rawTitleStr );
00439                                 $item['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
00440                         }
00441                         $intrwValues[] = $item;
00442                 }
00443 
00444                 if ( count( $intrwValues ) ) {
00445                         $result->setIndexedTagName( $intrwValues, 'i' );
00446                         $result->addValue( 'query', 'interwiki', $intrwValues );
00447                 }
00448 
00449                 // Show redirect information
00450                 $redirValues = array();
00454                 foreach ( $pageSet->getRedirectTitles() as $titleStrFrom => $titleTo ) {
00455                         $r = array(
00456                                 'from' => strval( $titleStrFrom ),
00457                                 'to' => $titleTo->getPrefixedText(),
00458                         );
00459                         if ( $titleTo->getFragment() !== '' ) {
00460                                 $r['tofragment'] = $titleTo->getFragment();
00461                         }
00462                         $redirValues[] = $r;
00463                 }
00464 
00465                 if ( count( $redirValues ) ) {
00466                         $result->setIndexedTagName( $redirValues, 'r' );
00467                         $result->addValue( 'query', 'redirects', $redirValues );
00468                 }
00469 
00470                 // Missing revision elements
00471                 $missingRevIDs = $pageSet->getMissingRevisionIDs();
00472                 if ( count( $missingRevIDs ) ) {
00473                         $revids = array();
00474                         foreach ( $missingRevIDs as $revid ) {
00475                                 $revids[$revid] = array(
00476                                         'revid' => $revid
00477                                 );
00478                         }
00479                         $result->setIndexedTagName( $revids, 'rev' );
00480                         $result->addValue( 'query', 'badrevids', $revids );
00481                 }
00482 
00483                 // Page elements
00484                 $pages = array();
00485 
00486                 // Report any missing titles
00487                 foreach ( $pageSet->getMissingTitles() as $fakeId => $title ) {
00488                         $vals = array();
00489                         ApiQueryBase::addTitleInfo( $vals, $title );
00490                         $vals['missing'] = '';
00491                         $pages[$fakeId] = $vals;
00492                 }
00493                 // Report any invalid titles
00494                 foreach ( $pageSet->getInvalidTitles() as $fakeId => $title ) {
00495                         $pages[$fakeId] = array( 'title' => $title, 'invalid' => '' );
00496                 }
00497                 // Report any missing page ids
00498                 foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
00499                         $pages[$pageid] = array(
00500                                 'pageid' => $pageid,
00501                                 'missing' => ''
00502                         );
00503                 }
00504                 // Report special pages
00505                 foreach ( $pageSet->getSpecialTitles() as $fakeId => $title ) {
00506                         $vals = array();
00507                         ApiQueryBase::addTitleInfo( $vals, $title );
00508                         $vals['special'] = '';
00509                         if ( $title->isSpecialPage() &&
00510                                         !SpecialPageFactory::exists( $title->getDbKey() ) ) {
00511                                 $vals['missing'] = '';
00512                         } elseif ( $title->getNamespace() == NS_MEDIA &&
00513                                         !wfFindFile( $title ) ) {
00514                                 $vals['missing'] = '';
00515                         }
00516                         $pages[$fakeId] = $vals;
00517                 }
00518 
00519                 // Output general page information for found titles
00520                 foreach ( $pageSet->getGoodTitles() as $pageid => $title ) {
00521                         $vals = array();
00522                         $vals['pageid'] = $pageid;
00523                         ApiQueryBase::addTitleInfo( $vals, $title );
00524                         $pages[$pageid] = $vals;
00525                 }
00526 
00527                 if ( count( $pages ) ) {
00528                         if ( $this->params['indexpageids'] ) {
00529                                 $pageIDs = array_keys( $pages );
00530                                 // json treats all map keys as strings - converting to match
00531                                 $pageIDs = array_map( 'strval', $pageIDs );
00532                                 $result->setIndexedTagName( $pageIDs, 'id' );
00533                                 $result->addValue( 'query', 'pageids', $pageIDs );
00534                         }
00535 
00536                         $result->setIndexedTagName( $pages, 'page' );
00537                         $result->addValue( 'query', 'pages', $pages );
00538                 }
00539                 if ( $this->params['export'] ) {
00540                         $this->doExport( $pageSet, $result );
00541                 }
00542         }
00543 
00548         private function doExport( $pageSet, $result ) {
00549                 $exportTitles = array();
00550                 $titles = $pageSet->getGoodTitles();
00551                 if ( count( $titles ) ) {
00552                         $user = $this->getUser();
00553                         foreach ( $titles as $title ) {
00554                                 if ( $title->userCan( 'read', $user ) ) {
00555                                         $exportTitles[] = $title;
00556                                 }
00557                         }
00558                 }
00559 
00560                 $exporter = new WikiExporter( $this->getDB() );
00561                 // WikiExporter writes to stdout, so catch its
00562                 // output with an ob
00563                 ob_start();
00564                 $exporter->openStream();
00565                 foreach ( $exportTitles as $title ) {
00566                         $exporter->pageByTitle( $title );
00567                 }
00568                 $exporter->closeStream();
00569                 $exportxml = ob_get_contents();
00570                 ob_end_clean();
00571 
00572                 // Don't check the size of exported stuff
00573                 // It's not continuable, so it would cause more
00574                 // problems than it'd solve
00575                 $result->disableSizeCheck();
00576                 if ( $this->params['exportnowrap'] ) {
00577                         $result->reset();
00578                         // Raw formatter will handle this
00579                         $result->addValue( null, 'text', $exportxml );
00580                         $result->addValue( null, 'mime', 'text/xml' );
00581                 } else {
00582                         $r = array();
00583                         ApiResult::setContent( $r, $exportxml );
00584                         $result->addValue( 'query', 'export', $r );
00585                 }
00586                 $result->enableSizeCheck();
00587         }
00588 
00594         public function newGenerator( $generatorName ) {
00595                 // Find class that implements requested generator
00596                 if ( isset( $this->mQueryListModules[$generatorName] ) ) {
00597                         $className = $this->mQueryListModules[$generatorName];
00598                 } elseif ( isset( $this->mQueryPropModules[$generatorName] ) ) {
00599                         $className = $this->mQueryPropModules[$generatorName];
00600                 } else {
00601                         ApiBase::dieDebug( __METHOD__, "Unknown generator=$generatorName" );
00602                 }
00603                 $generator = new $className ( $this, $generatorName );
00604                 if ( !$generator instanceof ApiQueryGeneratorBase ) {
00605                         $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
00606                 }
00607                 $generator->setGeneratorMode();
00608                 return $generator;
00609         }
00610 
00617         protected function executeGeneratorModule( $generator, $modules ) {
00618                 // Generator results
00619                 $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
00620 
00621                 // Add any additional fields modules may need
00622                 $generator->requestExtraData( $this->mPageSet );
00623                 $this->addCustomFldsToPageSet( $modules, $resultPageSet );
00624 
00625                 // Populate page information with the original user input
00626                 $this->mPageSet->execute();
00627 
00628                 // populate resultPageSet with the generator output
00629                 $generator->profileIn();
00630                 $generator->executeGenerator( $resultPageSet );
00631                 wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$resultPageSet ) );
00632                 $resultPageSet->finishPageSetGeneration();
00633                 $generator->profileOut();
00634 
00635                 // Swap the resulting pageset back in
00636                 $this->mPageSet = $resultPageSet;
00637         }
00638 
00639         public function getAllowedParams() {
00640                 return array(
00641                         'prop' => array(
00642                                 ApiBase::PARAM_ISMULTI => true,
00643                                 ApiBase::PARAM_TYPE => $this->mPropModuleNames
00644                         ),
00645                         'list' => array(
00646                                 ApiBase::PARAM_ISMULTI => true,
00647                                 ApiBase::PARAM_TYPE => $this->mListModuleNames
00648                         ),
00649                         'meta' => array(
00650                                 ApiBase::PARAM_ISMULTI => true,
00651                                 ApiBase::PARAM_TYPE => $this->mMetaModuleNames
00652                         ),
00653                         'generator' => array(
00654                                 ApiBase::PARAM_TYPE => $this->mAllowedGenerators
00655                         ),
00656                         'redirects' => false,
00657                         'converttitles' => false,
00658                         'indexpageids' => false,
00659                         'export' => false,
00660                         'exportnowrap' => false,
00661                         'iwurl' => false,
00662                 );
00663         }
00664 
00669         public function makeHelpMsg() {
00670                 // Make sure the internal object is empty
00671                 // (just in case a sub-module decides to optimize during instantiation)
00672                 $this->mPageSet = null;
00673 
00674                 $querySeparator = str_repeat( '--- ', 12 );
00675                 $moduleSeparator = str_repeat( '*** ', 14 );
00676                 $msg = "\n$querySeparator Query: Prop  $querySeparator\n\n";
00677                 $msg .= $this->makeHelpMsgHelper( $this->mQueryPropModules, 'prop' );
00678                 $msg .= "\n$querySeparator Query: List  $querySeparator\n\n";
00679                 $msg .= $this->makeHelpMsgHelper( $this->mQueryListModules, 'list' );
00680                 $msg .= "\n$querySeparator Query: Meta  $querySeparator\n\n";
00681                 $msg .= $this->makeHelpMsgHelper( $this->mQueryMetaModules, 'meta' );
00682                 $msg .= "\n\n$moduleSeparator Modules: continuation  $moduleSeparator\n\n";
00683 
00684                 // Use parent to make default message for the query module
00685                 $msg = parent::makeHelpMsg() . $msg;
00686 
00687                 return $msg;
00688         }
00689 
00696         private function makeHelpMsgHelper( $moduleList, $paramName ) {
00697                 $moduleDescriptions = array();
00698 
00699                 foreach ( $moduleList as $moduleName => $moduleClass ) {
00703                         $module = new $moduleClass( $this, $moduleName, null );
00704 
00705                         $msg = ApiMain::makeHelpMsgHeader( $module, $paramName );
00706                         $msg2 = $module->makeHelpMsg();
00707                         if ( $msg2 !== false ) {
00708                                 $msg .= $msg2;
00709                         }
00710                         if ( $module instanceof ApiQueryGeneratorBase ) {
00711                                 $msg .= "Generator:\n  This module may be used as a generator\n";
00712                         }
00713                         $moduleDescriptions[] = $msg;
00714                 }
00715 
00716                 return implode( "\n", $moduleDescriptions );
00717         }
00718 
00723         public function makeHelpMsgParameters() {
00724                 $psModule = new ApiPageSet( $this );
00725                 return $psModule->makeHelpMsgParameters() . parent::makeHelpMsgParameters();
00726         }
00727 
00728         public function shouldCheckMaxlag() {
00729                 return true;
00730         }
00731 
00732         public function getParamDescription() {
00733                 return array(
00734                         'prop' => 'Which properties to get for the titles/revisions/pageids. Module help is available below',
00735                         'list' => 'Which lists to get. Module help is available below',
00736                         'meta' => 'Which metadata to get about the site. Module help is available below',
00737                         'generator' => array( 'Use the output of a list as the input for other prop/list/meta items',
00738                                         'NOTE: generator parameter names must be prefixed with a \'g\', see examples' ),
00739                         'redirects' => 'Automatically resolve redirects',
00740                         'converttitles' => array( "Convert titles to other variants if necessary. Only works if the wiki's content language supports variant conversion.",
00741                                         'Languages that support variant conversion include ' . implode( ', ', LanguageConverter::$languagesWithVariants ) ),
00742                         'indexpageids' => 'Include an additional pageids section listing all returned page IDs',
00743                         'export' => 'Export the current revisions of all given or generated pages',
00744                         'exportnowrap' => 'Return the export XML without wrapping it in an XML result (same format as Special:Export). Can only be used with export',
00745                         'iwurl' => 'Whether to get the full URL if the title is an interwiki link',
00746                 );
00747         }
00748 
00749         public function getDescription() {
00750                 return array(
00751                         'Query API module allows applications to get needed pieces of data from the MediaWiki databases,',
00752                         'and is loosely based on the old query.php interface.',
00753                         'All data modifications will first have to use query to acquire a token to prevent abuse from malicious sites'
00754                 );
00755         }
00756 
00757         public function getPossibleErrors() {
00758                 return array_merge( parent::getPossibleErrors(), array(
00759                         array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
00760                 ) );
00761         }
00762 
00763         public function getExamples() {
00764                 return array(
00765                         'api.php?action=query&prop=revisions&meta=siteinfo&titles=Main%20Page&rvprop=user|comment',
00766                         'api.php?action=query&generator=allpages&gapprefix=API/&prop=revisions',
00767                 );
00768         }
00769 
00770         public function getHelpUrls() {
00771                 return array(
00772                         'https://www.mediawiki.org/wiki/API:Meta',
00773                         'https://www.mediawiki.org/wiki/API:Properties',
00774                         'https://www.mediawiki.org/wiki/API:Lists',
00775                 );
00776         }
00777 
00778         public function getVersion() {
00779                 $psModule = new ApiPageSet( $this );
00780                 $vers = array();
00781                 $vers[] = __CLASS__ . ': $Id$';
00782                 $vers[] = $psModule->getVersion();
00783                 return $vers;
00784         }
00785 }