Index: trunk/phase3/includes/api/ApiQuery.php |
— | — | @@ -61,15 +61,15 @@ |
62 | 62 | |
63 | 63 | private $mQueryListModules = array ( |
64 | 64 | 'allpages' => 'ApiQueryAllpages', |
65 | | - 'logevents' => 'ApiQueryLogEvents', |
66 | | - 'watchlist' => 'ApiQueryWatchlist', |
67 | | - 'recentchanges' => 'ApiQueryRecentChanges', |
68 | 65 | 'backlinks' => 'ApiQueryBacklinks', |
| 66 | + 'categorymembers' => 'ApiQueryCategoryMembers', |
69 | 67 | 'embeddedin' => 'ApiQueryBacklinks', |
70 | 68 | 'imageusage' => 'ApiQueryBacklinks', |
71 | | - 'usercontribs' => 'ApiQueryContributions' |
| 69 | + 'logevents' => 'ApiQueryLogEvents', |
| 70 | + 'recentchanges' => 'ApiQueryRecentChanges', |
| 71 | + 'usercontribs' => 'ApiQueryContributions', |
| 72 | + 'watchlist' => 'ApiQueryWatchlist', |
72 | 73 | ); |
73 | | - // 'categorymembers' => 'ApiQueryCategorymembers', |
74 | 74 | // 'recentchanges' => 'ApiQueryRecentchanges', |
75 | 75 | // 'users' => 'ApiQueryUsers', |
76 | 76 | // 'watchlist' => 'ApiQueryWatchlist', |
Index: trunk/phase3/includes/api/ApiQueryCategories.php |
— | — | @@ -150,12 +150,12 @@ |
151 | 151 | } |
152 | 152 | |
153 | 153 | protected function getDescription() { |
154 | | - return 'Returns all links from the given page(s)'; |
| 154 | + return 'List all categories the page(s) belong to'; |
155 | 155 | } |
156 | 156 | |
157 | 157 | protected function getExamples() { |
158 | 158 | return array ( |
159 | | - "Get a list of categories used in the [[Albert Einstein]]:", |
| 159 | + "Get a list of categories [[Albert Einstein]] belongs to:", |
160 | 160 | " api.php?action=query&prop=categories&titles=Albert%20Einstein", |
161 | 161 | "Get information about all categories used in the [[Albert Einstein]]:", |
162 | 162 | " api.php?action=query&generator=categories&titles=Albert%20Einstein&prop=info" |
Index: trunk/phase3/includes/api/ApiQueryCategoryMembers.php |
— | — | @@ -0,0 +1,210 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * Created on June 14, 2007 |
| 6 | + * |
| 7 | + * API for MediaWiki 1.8+ |
| 8 | + * |
| 9 | + * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com |
| 10 | + * |
| 11 | + * This program is free software; you can redistribute it and/or modify |
| 12 | + * it under the terms of the GNU General Public License as published by |
| 13 | + * the Free Software Foundation; either version 2 of the License, or |
| 14 | + * (at your option) any later version. |
| 15 | + * |
| 16 | + * This program is distributed in the hope that it will be useful, |
| 17 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | + * GNU General Public License for more details. |
| 20 | + * |
| 21 | + * You should have received a copy of the GNU General Public License along |
| 22 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 23 | + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 24 | + * http://www.gnu.org/copyleft/gpl.html |
| 25 | + */ |
| 26 | + |
| 27 | +if (!defined('MEDIAWIKI')) { |
| 28 | + // Eclipse helper - will be ignored in production |
| 29 | + require_once ("ApiQueryBase.php"); |
| 30 | +} |
| 31 | + |
| 32 | +/** |
| 33 | + * A query module to enumerate pages that belong to a category. |
| 34 | + * |
| 35 | + * @addtogroup API |
| 36 | + */ |
| 37 | +class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { |
| 38 | + |
| 39 | + public function __construct($query, $moduleName) { |
| 40 | + parent :: __construct($query, $moduleName, 'cm'); |
| 41 | + } |
| 42 | + |
| 43 | + public function execute() { |
| 44 | + $this->run(); |
| 45 | + } |
| 46 | + |
| 47 | + public function executeGenerator($resultPageSet) { |
| 48 | + $this->run($resultPageSet); |
| 49 | + } |
| 50 | + |
| 51 | + private function run($resultPageSet = null) { |
| 52 | + |
| 53 | + $params = $this->extractRequestParams(); |
| 54 | + |
| 55 | + $category = $params['category']; |
| 56 | + if (is_null($category)) |
| 57 | + $this->dieUsage("Category parameter is required", 'param_category'); |
| 58 | + $categoryTitle = Title::makeTitleSafe( NS_CATEGORY, $category ); |
| 59 | + if ( is_null( $categoryTitle ) ) |
| 60 | + $this->dieUsage("Category name $category is not valid", 'param_category'); |
| 61 | + |
| 62 | + $prop = array_flip($params['prop']); |
| 63 | + $fld_ids = isset($prop['ids']); |
| 64 | + $fld_title = isset($prop['title']); |
| 65 | + $fld_sortkey = isset($prop['sortkey']); |
| 66 | + |
| 67 | + if (is_null($resultPageSet)) { |
| 68 | + $this->addFields(array('cl_sortkey', 'page_namespace', 'page_title')); |
| 69 | + $this->addFieldsIf('page_id', $fld_ids); |
| 70 | + } else { |
| 71 | + $this->addFields($resultPageSet->getPageTableFields()); // will include page_ id, ns, title |
| 72 | + $this->addFields('cl_sortkey'); |
| 73 | + } |
| 74 | + |
| 75 | + $this->addTables(array('page','categorylinks')); // must be in this order for 'USE INDEX' |
| 76 | + $this->addOption('USE INDEX', 'cl_sortkey'); // Not needed after bug 10280 is applied to servers |
| 77 | + |
| 78 | + $this->addWhere('cl_from=page_id'); |
| 79 | + $this->setContinuation($params['continue']); |
| 80 | + $this->addWhereFld('cl_to', $categoryTitle->getDBkey()); |
| 81 | + $this->addWhereFld('page_namespace', $params['namespace']); |
| 82 | + $this->addOption('ORDER BY', "cl_to, cl_sortkey, cl_from"); |
| 83 | + |
| 84 | + $limit = $params['limit']; |
| 85 | + $this->addOption('LIMIT', $limit +1); |
| 86 | + |
| 87 | + $db = $this->getDB(); |
| 88 | + |
| 89 | + $data = array (); |
| 90 | + $count = 0; |
| 91 | + $lastSortKey = null; |
| 92 | + $res = $this->select(__METHOD__); |
| 93 | + while ($row = $db->fetchObject($res)) { |
| 94 | + if (++ $count > $limit) { |
| 95 | + // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
| 96 | + $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey)); |
| 97 | + break; |
| 98 | + } |
| 99 | + |
| 100 | + $lastSortKey = $row->cl_sortkey; // detect duplicate sortkeys |
| 101 | + |
| 102 | + if (is_null($resultPageSet)) { |
| 103 | + $title = Title :: makeTitle($row->page_namespace, $row->page_title); |
| 104 | + if ($title->userCanRead()) { |
| 105 | + $vals = array(); |
| 106 | + if ($fld_ids) |
| 107 | + $vals['pageid'] = intval($row->page_id); |
| 108 | + if ($fld_title) { |
| 109 | + $vals['ns'] = intval($title->getNamespace()); |
| 110 | + $vals['title'] = $title->getPrefixedText(); |
| 111 | + } |
| 112 | + if ($fld_sortkey) |
| 113 | + $vals['sortkey'] = $row->cl_sortkey; |
| 114 | + $data[] = $vals; |
| 115 | + } |
| 116 | + } else { |
| 117 | + $resultPageSet->processDbRow($row); |
| 118 | + } |
| 119 | + } |
| 120 | + $db->freeResult($res); |
| 121 | + |
| 122 | + if (is_null($resultPageSet)) { |
| 123 | + $this->getResult()->setIndexedTagName($data, 'cm'); |
| 124 | + $this->getResult()->addValue('query', $this->getModuleName(), $data); |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + private function getContinueStr($row, $lastSortKey) { |
| 129 | + $ret = $row->cl_sortkey . '|'; |
| 130 | + if ($row->cl_sortkey == $lastSortKey) // duplicate sort key, add cl_from |
| 131 | + $ret .= $row->cl_from; |
| 132 | + return $ret; |
| 133 | + } |
| 134 | + |
| 135 | + /** |
| 136 | + * Add DB WHERE clause to continue previous query based on 'continue' parameter |
| 137 | + */ |
| 138 | + private function setContinuation($continue) { |
| 139 | + if (is_null($continue)) |
| 140 | + return; // This is not a continuation request |
| 141 | + |
| 142 | + $continueList = explode('|', $continue); |
| 143 | + if (count($continueList) != 2) |
| 144 | + $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue"); |
| 145 | + |
| 146 | + $sortKey = $this->getDB()->addQuotes($continueList[0]); |
| 147 | + $from = intval($continueList[1]); |
| 148 | + |
| 149 | + if ($from != 0) { |
| 150 | + // Duplicate sort key continue |
| 151 | + $this->addWhere( "cl_sortkey>$sortKey OR (cl_sortkey=$sortKey AND cl_from>=$from)" ); |
| 152 | + } else { |
| 153 | + $this->addWhere( "cl_sortkey>=$sortKey" ); |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + protected function getAllowedParams() { |
| 158 | + return array ( |
| 159 | + 'category' => null, |
| 160 | + 'prop' => array ( |
| 161 | + ApiBase :: PARAM_DFLT => 'ids|title', |
| 162 | + ApiBase :: PARAM_ISMULTI => true, |
| 163 | + ApiBase :: PARAM_TYPE => array ( |
| 164 | + 'ids', |
| 165 | + 'title', |
| 166 | + 'sortkey', |
| 167 | + ) |
| 168 | + ), |
| 169 | + 'namespace' => array ( |
| 170 | + ApiBase :: PARAM_ISMULTI => true, |
| 171 | + ApiBase :: PARAM_TYPE => 'namespace', |
| 172 | + ), |
| 173 | + 'continue' => null, |
| 174 | + 'limit' => array ( |
| 175 | + ApiBase :: PARAM_TYPE => 'limit', |
| 176 | + ApiBase :: PARAM_DFLT => 10, |
| 177 | + ApiBase :: PARAM_MIN => 1, |
| 178 | + ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1, |
| 179 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
| 180 | + ), |
| 181 | + ); |
| 182 | + } |
| 183 | + |
| 184 | + protected function getParamDescription() { |
| 185 | + return array ( |
| 186 | + 'category' => 'Which category to enumerate (required)', |
| 187 | + 'prop' => 'What pieces of infromation to include', |
| 188 | + 'namespace' => 'Only include pages in these namespaces', |
| 189 | + 'continue' => 'For large categories, give the value retured from previous query', |
| 190 | + 'limit' => 'The maximum number of pages to return.', |
| 191 | + ); |
| 192 | + } |
| 193 | + |
| 194 | + protected function getDescription() { |
| 195 | + return 'List all pages in a given category'; |
| 196 | + } |
| 197 | + |
| 198 | + protected function getExamples() { |
| 199 | + return array ( |
| 200 | + "Get first 10 pages in the categories [[Physics]]:", |
| 201 | + " api.php?action=query&list=categorymembers&cmcategory=Physics", |
| 202 | + "Get page info about first 10 pages in the categories [[Physics]]:", |
| 203 | + " api.php?action=query&generator=categorymembers&gcmcategory=Physics&prop=info", |
| 204 | + ); |
| 205 | + } |
| 206 | + |
| 207 | + public function getVersion() { |
| 208 | + return __CLASS__ . ': $Id$'; |
| 209 | + } |
| 210 | +} |
| 211 | +?> |
Property changes on: trunk/phase3/includes/api/ApiQueryCategoryMembers.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 212 | + native |
Added: svn:keywords |
2 | 213 | + Id |
Index: trunk/phase3/includes/api/ApiQueryUserContributions.php |
— | — | @@ -47,17 +47,14 @@ |
48 | 48 | |
49 | 49 | // Parse some parameters |
50 | 50 | $this->params = $this->extractRequestParams(); |
51 | | - $prop = $this->params['prop']; |
52 | | - if (!is_null($prop)) { |
53 | | - $prop = array_flip($prop); |
54 | | - |
55 | | - $this->fld_ids = isset($prop['ids']); |
56 | | - $this->fld_title = isset($prop['title']); |
57 | | - $this->fld_comment = isset($prop['comment']); |
58 | | - $this->fld_flags = isset($prop['flags']); |
59 | | - $this->fld_timestamp = isset($prop['timestamp']); |
60 | | - } |
61 | 51 | |
| 52 | + $prop = array_flip($this->params['prop']); |
| 53 | + $this->fld_ids = isset($prop['ids']); |
| 54 | + $this->fld_title = isset($prop['title']); |
| 55 | + $this->fld_comment = isset($prop['comment']); |
| 56 | + $this->fld_flags = isset($prop['flags']); |
| 57 | + $this->fld_timestamp = isset($prop['timestamp']); |
| 58 | + |
62 | 59 | // TODO: if the query is going only against the revision table, should this be done? |
63 | 60 | $this->selectNamedDB('contributions', DB_SLAVE, 'contributions'); |
64 | 61 | $db = $this->getDB(); |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -305,6 +305,7 @@ |
306 | 306 | 'ApiQueryBase' => 'includes/api/ApiQueryBase.php', |
307 | 307 | 'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php', |
308 | 308 | 'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php', |
| 309 | + 'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php', |
309 | 310 | 'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php', |
310 | 311 | 'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php', |
311 | 312 | 'ApiQueryImages' => 'includes/api/ApiQueryImages.php', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -206,6 +206,7 @@ |
207 | 207 | values of all returned page items |
208 | 208 | * (bug 10147) Now interwiki titles are not processed but added to a separate |
209 | 209 | "interwiki" section of the output. |
| 210 | +* Added categorymembers list to query for pages in a category. |
210 | 211 | |
211 | 212 | == Maintenance script changes since 1.10 == |
212 | 213 | |