API: (bug 15579) clshow considers all categories !hidden. Modified patch by Brad...
[lhc/web/wiklou.git] / includes / api / ApiQueryCategories.php
index 9d1d99e..cbff86b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * API for MediaWiki 1.8+
  *
- * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,9 @@ if (!defined('MEDIAWIKI')) {
 }
 
 /**
- * @addtogroup API
+ * A query module to enumerate categories the set of pages belong to.
+ *
+ * @ingroup API
  */
 class ApiQueryCategories extends ApiQueryGeneratorBase {
 
@@ -47,15 +49,19 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
 
        private function run($resultPageSet = null) {
 
+               if ($this->getPageSet()->getGoodTitleCount() == 0)
+                       return; // nothing to do
+
                $params = $this->extractRequestParams();
                $prop = $params['prop'];
+               $show = array_flip((array)$params['show']);
 
                $this->addFields(array (
                        'cl_from',
                        'cl_to'
                ));
-               
-               $fld_sortkey = false;
+
+               $fld_sortkey = $fld_timestamp = false;
                if (!is_null($prop)) {
                        foreach($prop as $p) {
                                switch ($p) {
@@ -63,24 +69,71 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
                                                $this->addFields('cl_sortkey');
                                                $fld_sortkey = true;
                                                break;
+                                       case 'timestamp':
+                                               $this->addFields('cl_timestamp');
+                                               $fld_timestamp = true;
+                                               break;
                                        default :
                                                ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
                                }
                        }
                }
-               
+
                $this->addTables('categorylinks');
                $this->addWhereFld('cl_from', array_keys($this->getPageSet()->getGoodTitles()));
-               $this->addOption('ORDER BY', "cl_from, cl_to");
+               if(!is_null($params['continue'])) {
+                       $cont = explode('|', $params['continue']);
+                       if(count($cont) != 2)
+                               $this->dieUsage("Invalid continue param. You should pass the " .
+                                       "original value returned by the previous query", "_badcontinue");
+                       $clfrom = intval($cont[0]);
+                       $clto = $this->getDB()->strencode($this->titleToKey($cont[1]));
+                       $this->addWhere("cl_from > $clfrom OR ".
+                                       "(cl_from = $clfrom AND ".
+                                       "cl_to >= '$clto')");
+               }
+               if(isset($show['hidden']) && isset($show['!hidden']))
+                       $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
+               if(isset($show['hidden']) || isset($show['!hidden']))
+               {
+                       $this->addOption('STRAIGHT_JOIN');
+                       $this->addTables(array('page', 'page_props'));
+                       $this->addJoinConds(array(
+                               'page' => array('LEFT JOIN', array(
+                                       'page_namespace' => NS_CATEGORY,
+                                       'page_title = cl_to')),
+                               'page_props' => array('LEFT JOIN', array(
+                                       'pp_page=page_id',
+                                       'pp_propname' => 'hiddencat'))
+                       ));
+                       if(isset($show['hidden']))
+                               $this->addWhere(array('pp_propname IS NOT NULL'));
+                       else
+                               $this->addWhere(array('pp_propname IS NULL'));
+               }
+
+               # Don't order by cl_from if it's constant in the WHERE clause
+               if(count($this->getPageSet()->getGoodTitles()) == 1)
+                       $this->addOption('ORDER BY', 'cl_to');
+               else
+                       $this->addOption('ORDER BY', "cl_from, cl_to");
 
                $db = $this->getDB();
                $res = $this->select(__METHOD__);
 
                if (is_null($resultPageSet)) {
-                       
+
                        $data = array();
-                       $lastId = 0;    // database has no ID 0 
+                       $lastId = 0;    // database has no ID 0
+                       $count = 0;
                        while ($row = $db->fetchObject($res)) {
+                               if (++$count > $params['limit']) {
+                                       // We've reached the one extra which shows that
+                                       // there are additional pages to be had. Stop here...
+                                       $this->setContinueEnumParameter('continue', $row->cl_from .
+                                                       '|' . $this->keyToTitle($row->cl_to));
+                                       break;
+                               }
                                if ($lastId != $row->cl_from) {
                                        if($lastId != 0) {
                                                $this->addPageSubItems($lastId, $data);
@@ -88,12 +141,16 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
                                        }
                                        $lastId = $row->cl_from;
                                }
-                               
+
                                $title = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
+
                                $vals = array();
                                ApiQueryBase :: addTitleInfo($vals, $title);
                                if ($fld_sortkey)
                                        $vals['sortkey'] = $row->cl_sortkey;
+                               if ($fld_timestamp)
+                                       $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
+
                                $data[] = $vals;
                        }
 
@@ -105,6 +162,14 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
 
                        $titles = array();
                        while ($row = $db->fetchObject($res)) {
+                               if (++$count > $params['limit']) {
+                                       // We've reached the one extra which shows that
+                                       // there are additional pages to be had. Stop here...
+                                       $this->setContinueEnumParameter('continue', $row->cl_from .
+                                                       '|' . $this->keyToTitle($row->cl_to));
+                                       break;
+                               }
+
                                $titles[] = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
                        }
                        $resultPageSet->populateFromTitles($titles);
@@ -113,40 +178,51 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
                $db->freeResult($res);
        }
 
-       private function addPageSubItems($pageId, $data) {
-               $result = $this->getResult();
-               $result->setIndexedTagName($data, 'cl');
-               $result->addValue(array ('query', 'pages', intval($pageId)),
-                       'categories',
-                       $data);
-       }
-
-       protected function getAllowedParams() {
+       public function getAllowedParams() {
                return array (
                        'prop' => array (
                                ApiBase :: PARAM_ISMULTI => true,
                                ApiBase :: PARAM_TYPE => array (
                                        'sortkey',
+                                       'timestamp',
+                               )
+                       ),
+                       'show' => array(
+                               ApiBase :: PARAM_ISMULTI => true,
+                               ApiBase :: PARAM_TYPE => array(
+                                       'hidden',
+                                       '!hidden',
                                )
-                       )
+                       ),
+                       'limit' => array(
+                               ApiBase :: PARAM_DFLT => 10,
+                               ApiBase :: PARAM_TYPE => 'limit',
+                               ApiBase :: PARAM_MIN => 1,
+                               ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+                               ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+                       ),
+                       'continue' => null,
                );
        }
 
-       protected function getParamDescription() {
+       public function getParamDescription() {
                return array (
                        'prop' => 'Which additional properties to get for each category.',
+                       'limit' => 'How many categories to return',
+                       'show' => 'Which kind of categories to show',
+                       'continue' => 'When more results are available, use this to continue',
                );
        }
 
-       protected function getDescription() {
-               return 'Returns all links from the given page(s)';
+       public function getDescription() {
+               return 'List all categories the page(s) belong to';
        }
 
        protected function getExamples() {
                return array (
-                               "Get a list of categories used in the [[Main Page]]:",
+                               "Get a list of categories [[Albert Einstein]] belongs to:",
                                "  api.php?action=query&prop=categories&titles=Albert%20Einstein",
-                               "Get information about all categories used in the [[Main Page]]:",
+                               "Get information about all categories used in the [[Albert Einstein]]:",
                                "  api.php?action=query&generator=categories&titles=Albert%20Einstein&prop=info"
                        );
        }
@@ -155,4 +231,3 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
                return __CLASS__ . ': $Id$';
        }
 }
-?>