* API: implemented generator function
authorYuri Astrakhan <yurik@users.mediawiki.org>
Mon, 2 Oct 2006 23:56:19 +0000 (23:56 +0000)
committerYuri Astrakhan <yurik@users.mediawiki.org>
Mon, 2 Oct 2006 23:56:19 +0000 (23:56 +0000)
* API: enabled allpages to function as a generator

includes/api/ApiBase.php
includes/api/ApiPageSet.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllpages.php
includes/api/ApiQueryBase.php

index b4a18a9..bde8b87 100644 (file)
@@ -176,18 +176,26 @@ abstract class ApiBase {
        * Using getAllowedParams(), makes an array of the values provided by the user,
        * with key being the name of the variable, and value - validated value from user or default.
        * This method can be used to generate local variables using extract().
+       * 
+       * @param $prefix String: prepend this prefix to all parameter names. 
        */
-       public function extractRequestParams() {
+       public function extractRequestParams($prefix = '') {
                $params = $this->getAllowedParams();
                $results = array ();
 
                foreach ($params as $paramName => $paramSettings)
-                       $results[$paramName] = $this->getParameter($paramName, $paramSettings);
+                       $results[$paramName] = $this->getParameterFromSettings($prefix . $paramName, $paramSettings);
 
                return $results;
        }
 
-       public function getParameter($paramName, $paramSettings) {
+       protected function getParameter($paramName, $prefix = '') {
+               $params = $this->getAllowedParams();
+               $paramSettings = $params[$paramName];
+               return $this->getParameterFromSettings($prefix . $paramName, $paramSettings);
+       }
+       
+       protected function getParameterFromSettings($paramName, $paramSettings) {
                global $wgRequest;
 
                if (!is_array($paramSettings)) {
index 0c1b7c4..9e34ce7 100644 (file)
@@ -233,7 +233,7 @@ class ApiPageSet extends ApiQueryBase {
                        // Resolve redirects by querying the pagelinks table, and repeat the process
                        // Create a new linkBatch object for the next pass
                        //
-                       $linkBatch = $this->ResolveRedirectList($redirectIds);
+                       $linkBatch = $this->resolveRedirectList($redirectIds);
 
                        // Redirects are always titles
                        $processTitles = true;
@@ -241,7 +241,7 @@ class ApiPageSet extends ApiQueryBase {
                while (false !== ($set = $linkBatch->constructSet('page', $db)));
        }
 
-       private function ResolveRedirectList($redirectIds) {
+       private function resolveRedirectList($redirectIds) {
 
                $linkBatch = new LinkBatch();
                $db = $this->getDB();
@@ -342,6 +342,7 @@ class ApiPageSet extends ApiQueryBase {
        }
 
        public function execute() {
+               $this->profileIn();
                $titles = $pageids = $revids = $redirects = null;
                extract($this->extractRequestParams());
 
@@ -372,8 +373,19 @@ class ApiPageSet extends ApiQueryBase {
                                // Do nothing - some queries do not need any of the data sources.
                                break;
                }
+               $this->profileOut();
        }
 
+       /**
+        * This method is used by generators to pass the list of pageIDs internaly
+        */
+       public function executeForPageIDs($pageIDs) {
+               $this->profileIn();
+               $pageIDs = array_map( 'intval', $pageIDs );     // paranoia
+               $this->populatePages(null, $pageIDs, $this->getParameter('redirects'));
+               $this->profileOut();
+       }
+       
        protected function getAllowedParams() {
                return array (
                        'titles' => array (
index 4fc2b9e..4137b1b 100644 (file)
@@ -131,9 +131,7 @@ class ApiQuery extends ApiBase {
                //
                // Get page information for the given pageSet
                //
-               $this->mPageSet->profileIn();
                $this->mPageSet->execute();
-               $this->mPageSet->profileOut();
 
                //
                // Record page information
@@ -212,27 +210,27 @@ class ApiQuery extends ApiBase {
                }
        }
 
-       protected function executeGenerator($generator) {
+       protected function executeGenerator($generatorName) {
 
                // Find class that implements requested generator
-               if (isset ($this->mQueryListModules[$generator]))
-                       $className = $this->mQueryListModules[$generator];
-               elseif (isset ($this->mQueryPropModules[$generator])) $className = $this->mQueryPropModules[$generator];
+               if (isset ($this->mQueryListModules[$generatorName]))
+                       $className = $this->mQueryListModules[$generatorName];
+               elseif (isset ($this->mQueryPropModules[$generatorName])) $className = $this->mQueryPropModules[$generatorName];
                else
-                       ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generator");
+                       ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generatorName");
 
-               $module = new $className ($this, $generator, true);
-               $module->requestExtraData();
+               $generator = new $className ($this, $generatorName, true);
+               if (!$generator->getCanGenerate())
+                       $this->dieUsage("Module $generatorName cannot be used as a generator", "badgenerator");
+                       
+               $generator->requestExtraData();
 
                // execute pageSet here to get the data required by the generator module
-               $this->mPageSet->profileIn();
                $this->mPageSet->execute();
-               $this->mPageSet->profileOut();
-
-               // change $this->mPageSet
 
-               // TODO: implement
-               $this->dieUsage('Generator execution has not been implemented', 'notimplemented');
+               $generator->profileIn();
+               $this->mPageSet = $generator->execute();
+               $generator->profileOut();
        }
 
        protected function getAllowedParams() {
@@ -248,12 +246,10 @@ class ApiQuery extends ApiBase {
                        'meta' => array (
                                ApiBase :: PARAM_ISMULTI => true,
                                ApiBase :: PARAM_TYPE => $this->mMetaModuleNames
-                       )
-                       //                      'generator' => array (
-                       //                              ApiBase::PARAM_TYPE => $this->mAllowedGenerators
-                       //                      ),
-
-                       
+                       ),
+                       'generator' => array (
+                           ApiBase::PARAM_TYPE => $this->mAllowedGenerators
+                       )                       
                );
        }
 
@@ -337,4 +333,4 @@ class ApiQuery extends ApiBase {
                return $vers;
        }
 }
-?>
+?>
\ No newline at end of file
index d499e24..2a48eee 100644 (file)
@@ -63,13 +63,15 @@ class ApiQueryAllpages extends ApiQueryBase {
                $this->profileDBOut();
 
                $data = array ();
-               ApiResult :: setIndexedTagName($data, 'p');
+               if(!$this->isGenerator())
+                       ApiResult :: setIndexedTagName($data, 'p');
+                       
                $count = 0;
                while ($row = $db->fetchObject($res)) {
                        if (++ $count > $aplimit) {
                                // We've reached the one extra which shows that there are additional pages to be had. Stop here...
                                $msg = array (
-                                       'continue' => 'apfrom=' . ApiQueryBase :: keyToTitle($row->page_title
+                                       'continue' => ($this->isGenerator() ? 'g' : '') . 'apfrom=' . ApiQueryBase :: keyToTitle($row->page_title
                                ));
                                $this->getResult()->addValue('query-status', 'allpages', $msg);
                                break;
@@ -78,19 +80,30 @@ class ApiQueryAllpages extends ApiQueryBase {
                        $title = Title :: makeTitle($row->page_namespace, $row->page_title);
                        // skip any pages that user has no rights to read
                        if ($title->userCanRead()) {
-
                                $id = intval($row->page_id);
-                               $pagedata = array ();
-                               $pagedata['id'] = $id;
-                               if ($title->getNamespace() !== 0)
-                                       $pagedata['ns'] = $title->getNamespace();
-                               $pagedata['title'] = $title->getPrefixedText();
 
-                               $data[$id] = $pagedata;
+                               if ($this->isGenerator()) {
+                                       $data[] = $id;  // in generator mode, just assemble a list of page IDs.
+                               } else {
+                                       $pagedata = array ();
+                                       $pagedata['id'] = $id;
+                                       if ($title->getNamespace() !== 0)
+                                               $pagedata['ns'] = $title->getNamespace();
+                                       $pagedata['title'] = $title->getPrefixedText();
+       
+                                       $data[$id] = $pagedata;
+                               }
                        }
                }
                $db->freeResult($res);
-               $this->getResult()->addValue('query', 'allpages', $data);
+
+               if ($this->isGenerator()) {
+                       $pageSet = new ApiPageSet($this->getQuery());
+                       $pageSet->executeForPageIDs($data);
+                       return $pageSet;
+               } else {
+                       $this->getResult()->addValue('query', 'allpages', $data);
+               }
        }
 
        protected function getAllowedParams() {
@@ -142,7 +155,8 @@ class ApiQueryAllpages extends ApiQueryBase {
        protected function getExamples() {
                return array (
                        'api.php?action=query&list=allpages',
-                       'api.php?action=query&list=allpages&apfrom=B&aplimit=5'
+                       'api.php?action=query&list=allpages&apfrom=B&aplimit=5',
+                       'api.php?action=query&generator=allpages&gaplimit=4&prop=info (generator)'
                );
        }
 
index 3928a2f..4f11520 100644 (file)
@@ -31,13 +31,13 @@ if (!defined('MEDIAWIKI')) {
 
 abstract class ApiQueryBase extends ApiBase {
 
-       private $mQueryModule, $mModuleName, $mGenerator;
+       private $mQueryModule, $mModuleName, $mIsGenerator;
 
-       public function __construct($query, $moduleName, $generator = false) {
+       public function __construct($query, $moduleName, $isGenerator = false) {
                parent :: __construct($query->getMain());
                $this->mQueryModule = $query;
                $this->mModuleName = $moduleName;
-               $this->mGenerator = $generator;
+               $this->mIsGenerator = $isGenerator;
        }
 
        /**
@@ -61,6 +61,16 @@ abstract class ApiQueryBase extends ApiBase {
                return $this->mModuleName;
        }
 
+       /**
+        * Overrides base class to prepend 'g' to every generator parameter
+        */
+       public function extractRequestParams() {
+               $prefix = '';
+               if($this->isGenerator())
+                       $prefix = 'g';
+               return parent :: extractRequestParams($prefix);
+       }
+       
        /**
         * Get the Query database connection (readonly)
         */
@@ -79,8 +89,8 @@ abstract class ApiQueryBase extends ApiBase {
        /**
         * Return true if this instance is being used as a generator.
         */
-       protected function getIsGenerator() {
-               return $this->mGenerator;
+       protected function isGenerator() {
+               return $this->mIsGenerator;
        }
 
        /**