* API: pageSet now supports pageids, revised revisions listings, lots of examples.
[lhc/web/wiklou.git] / includes / api / ApiQuery.php
index 458007b..533c95c 100644 (file)
@@ -31,13 +31,8 @@ if (!defined('MEDIAWIKI')) {
 
 class ApiQuery extends ApiBase {
 
-       private $mMetaModuleNames, $mPropModuleNames, $mListModuleNames;
-       private $mData;
-
-       private $mQueryMetaModules = array (
-               'siteinfo' => 'ApiQuerySiteinfo'
-       );
-       //      'userinfo' => 'ApiQueryUserinfo',
+       private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
+       private $mPageSet;
 
        private $mQueryPropModules = array (
                'info' => 'ApiQueryInfo',
@@ -62,13 +57,18 @@ class ApiQuery extends ApiBase {
        //      'users' => 'ApiQueryUsers',
        //      'watchlist' => 'ApiQueryWatchlist',
 
+       private $mQueryMetaModules = array (
+               'siteinfo' => 'ApiQuerySiteinfo'
+       );
+       //      'userinfo' => 'ApiQueryUserinfo',
+
        private $mSlaveDB = null;
 
        public function __construct($main, $action) {
                parent :: __construct($main);
-               $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
                $this->mPropModuleNames = array_keys($this->mQueryPropModules);
                $this->mListModuleNames = array_keys($this->mQueryListModules);
+               $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
 
                // Allow the entire list of modules at first,
                // but during module instantiation check if it can be used as a generator.
@@ -81,8 +81,8 @@ class ApiQuery extends ApiBase {
                return $this->mSlaveDB;
        }
 
-       public function getData() {
-               return $this->mData;
+       public function getPageSet() {
+               return $this->mPageSet;
        }
 
        /**
@@ -96,13 +96,13 @@ class ApiQuery extends ApiBase {
         * #5 Execute all requested modules
         */
        public function execute() {
-               $meta = $prop = $list = $generator = null;
+               $prop = $list = $meta = $generator = null;
                extract($this->extractRequestParams());
 
                //
                // Create PageSet
                //
-               $this->mData = new ApiPageSet($this);
+               $this->mPageSet = new ApiPageSet($this);
 
                //
                // If generator is provided, get a new dataset to work on
@@ -111,29 +111,50 @@ class ApiQuery extends ApiBase {
                        $this->executeGenerator($generator);
 
                // Instantiate required modules
-               // During instantiation, modules may optimize data requests through the $this->mData object 
-               // $this->mData will be lazy loaded when modules begin to request data during execution
                $modules = array ();
-               if (isset ($meta))
-                       foreach ($meta as $moduleName)
-                               $modules[] = new $this->mQueryMetaModules[$moduleName] ($this, $moduleName);
                if (isset ($prop))
                        foreach ($prop as $moduleName)
                                $modules[] = new $this->mQueryPropModules[$moduleName] ($this, $moduleName);
                if (isset ($list))
                        foreach ($list as $moduleName)
                                $modules[] = new $this->mQueryListModules[$moduleName] ($this, $moduleName);
+               if (isset ($meta))
+                       foreach ($meta as $moduleName)
+                               $modules[] = new $this->mQueryMetaModules[$moduleName] ($this, $moduleName);
+
+               // Modules may optimize data requests through the $this->getPageSet() object 
+               // Execute all requested modules.
+               foreach ($modules as $module) {
+                       $module->requestExtraData();
+               }
 
                //
                // Get page information for the given pageSet
                //
-               $this->mData->profileIn();
-               $this->mData->execute();
-               $this->mData->profileOut();
+               $this->mPageSet->profileIn();
+               $this->mPageSet->execute();
+               $this->mPageSet->profileOut();
+
+               //
+               // Record page information
+               //
+               $this->outputGeneralPageInfo();
+
+               // Execute all requested modules.
+               foreach ($modules as $module) {
+                       $module->profileIn();
+                       $module->execute();
+                       $module->profileOut();
+               }
+       }
+
+       private function outputGeneralPageInfo() {
+
+               $pageSet = $this->getPageSet();
 
                // Title normalizations
                $normValues = array ();
-               foreach ($this->mData->getNormalizedTitles() as $rawTitleStr => $titleStr) {
+               foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) {
                        $normValues[] = array (
                                'from' => $rawTitleStr,
                                'to' => $titleStr
@@ -147,7 +168,7 @@ class ApiQuery extends ApiBase {
 
                // Show redirect information
                $redirValues = array ();
-               foreach ($this->mData->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
+               foreach ($pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
                        $redirValues[] = array (
                                'from' => $titleStrFrom,
                                'to' => $titleStrTo
@@ -159,17 +180,35 @@ class ApiQuery extends ApiBase {
                        $this->getResult()->addValue('query', 'redirects', $redirValues);
                }
 
-               // Execute all requested modules.
-               foreach ($modules as $module) {
-                       $module->profileIn();
-                       $module->execute();
-                       $module->profileOut();
+               //
+               // Page elements
+               //
+               $pages = array ();
+
+               // Report any missing titles
+               $fakepageid = -1;
+               foreach ($pageSet->getMissingTitles() as $title) {
+                       $pages[$fakepageid--] = array (
+                       'ns' => $title->getNamespace(), 'title' => $title->getPrefixedText(), 'missing' => '');
                }
 
-               // Ensure that pages are shown as '<page>' elements
-               $data = & $this->getResultData();
-               if (isset ($data['query']['pages'])) {
-                       ApiResult :: setIndexedTagName($data['query']['pages'], 'page');
+               // Report any missing page ids
+               foreach ($pageSet->getMissingPageIDs() as $pageid) {
+                       $pages[$pageid] = array (
+                               'id' => $pageid,
+                               'missing' => ''
+                       );
+               }
+
+               // Output general page information for found titles
+               foreach ($pageSet->getGoodTitles() as $pageid => $title) {
+                       $pages[$pageid] = array (
+                       'ns' => $title->getNamespace(), 'title' => $title->getPrefixedText(), 'id' => $pageid);
+               }
+
+               if (!empty ($pages)) {
+                       ApiResult :: setIndexedTagName($pages, 'page');
+                       $this->getResult()->addValue('query', 'pages', $pages);
                }
        }
 
@@ -178,20 +217,19 @@ class ApiQuery extends ApiBase {
                // Find class that implements requested generator
                if (isset ($this->mQueryListModules[$generator]))
                        $className = $this->mQueryListModules[$generator];
+               elseif (isset ($this->mQueryPropModules[$generator])) $className = $this->mQueryPropModules[$generator];
                else
-                       if (isset ($this->mQueryPropModules[$generator]))
-                               $className = $this->mQueryPropModules[$generator];
-                       else
-                               ApiBase :: dieDebug("Unknown generator=$generator");
+                       ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generator");
 
                $module = new $className ($this, $generator, true);
+               $module->requestExtraData();
 
                // execute pageSet here to get the data required by the generator module
-               $this->mData->profileIn();
-               $this->mData->execute();
-               $this->mData->profileOut();
+               $this->mPageSet->profileIn();
+               $this->mPageSet->execute();
+               $this->mPageSet->profileOut();
 
-               // change $this->mData
+               // change $this->mPageSet
 
                // TODO: implement
                $this->dieUsage('Generator execution has not been implemented', 'notimplemented');
@@ -199,17 +237,17 @@ class ApiQuery extends ApiBase {
 
        protected function getAllowedParams() {
                return array (
-                       'meta' => array (
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mMetaModuleNames
-                       ),
                        'prop' => array (
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mPropModuleNames
+                               ApiBase :: PARAM_ISMULTI => true,
+                               ApiBase :: PARAM_TYPE => $this->mPropModuleNames
                        ),
                        'list' => array (
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mListModuleNames
+                               ApiBase :: PARAM_ISMULTI => true,
+                               ApiBase :: PARAM_TYPE => $this->mListModuleNames
+                       ),
+                       'meta' => array (
+                               ApiBase :: PARAM_ISMULTI => true,
+                               ApiBase :: PARAM_TYPE => $this->mMetaModuleNames
                        )
                        //                      'generator' => array (
                        //                              ApiBase::PARAM_TYPE => $this->mAllowedGenerators
@@ -229,34 +267,35 @@ class ApiQuery extends ApiBase {
 
                // Make sure the internal object is empty
                // (just in case a sub-module decides to optimize during instantiation)
-               $this->mData = null;
+               $this->mPageSet = null;
 
                $astriks = str_repeat('--- ', 8);
-               $msg .= "\n$astriks Query: Meta  $astriks\n\n";
-               $msg .= $this->makeHelpMsgHelper($this->mQueryMetaModules, 'meta');
                $msg .= "\n$astriks Query: Prop  $astriks\n\n";
                $msg .= $this->makeHelpMsgHelper($this->mQueryPropModules, 'prop');
                $msg .= "\n$astriks Query: List  $astriks\n\n";
                $msg .= $this->makeHelpMsgHelper($this->mQueryListModules, 'list');
+               $msg .= "\n$astriks Query: Meta  $astriks\n\n";
+               $msg .= $this->makeHelpMsgHelper($this->mQueryMetaModules, 'meta');
 
                return $msg;
        }
 
        private function makeHelpMsgHelper($moduleList, $paramName) {
-               $msg = '';
+
+               $moduleDscriptions = array ();
 
                foreach ($moduleList as $moduleName => $moduleClass) {
-                       $msg .= "* $paramName=$moduleName *";
+                       $msg = "* $paramName=$moduleName *";
                        $module = new $moduleClass ($this, $moduleName, null);
                        $msg2 = $module->makeHelpMsg();
                        if ($msg2 !== false)
                                $msg .= $msg2;
-                       $msg .= "\n";
                        if ($module->getCanGenerate())
-                               $msg .= "  * Can be used as a generator\n";
+                               $msg .= "Generator:\n  This module may be used as a generator\n";
+                       $moduleDscriptions[] = $msg;
                }
 
-               return $msg;
+               return implode("\n", $moduleDscriptions);
        }
 
        /**
@@ -269,12 +308,10 @@ class ApiQuery extends ApiBase {
 
        protected function getParamDescription() {
                return array (
-                       'meta' => 'Which meta data to get about the site',
                        'prop' => 'Which properties to get for the titles/revisions/pageids',
                        'list' => 'Which lists to get',
-                       'generator' => 'Use the output of a list as the input for other prop/list/meta items',
-
-                       
+                       'meta' => 'Which meta data to get about the site',
+                       'generator' => 'Use the output of a list as the input for other prop/list/meta items'
                );
        }