Index: trunk/phase3/includes/api/ApiQuery.php |
— | — | @@ -59,6 +59,7 @@ |
60 | 60 | |
61 | 61 | private $mQueryListModules = array ( |
62 | 62 | 'allpages' => 'ApiQueryAllpages', |
| 63 | + 'alllinks' => 'ApiQueryAllLinks', |
63 | 64 | 'backlinks' => 'ApiQueryBacklinks', |
64 | 65 | 'categorymembers' => 'ApiQueryCategoryMembers', |
65 | 66 | 'embeddedin' => 'ApiQueryBacklinks', |
Index: trunk/phase3/includes/api/ApiQueryAllpages.php |
— | — | @@ -54,17 +54,16 @@ |
55 | 55 | |
56 | 56 | $db = $this->getDB(); |
57 | 57 | |
58 | | - $limit = $from = $namespace = $filterredir = $prefix = null; |
59 | | - extract($this->extractRequestParams()); |
| 58 | + $params = $this->extractRequestParams(); |
60 | 59 | |
61 | 60 | $this->addTables('page'); |
62 | | - if (!$this->addWhereIf('page_is_redirect = 1', $filterredir === 'redirects')) |
63 | | - $this->addWhereIf('page_is_redirect = 0', $filterredir === 'nonredirects'); |
64 | | - $this->addWhereFld('page_namespace', $namespace); |
65 | | - if (isset ($from)) |
66 | | - $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($from))); |
67 | | - if (isset ($prefix)) |
68 | | - $this->addWhere("page_title LIKE '{$db->strencode(ApiQueryBase :: titleToKey($prefix))}%'"); |
| 61 | + if (!$this->addWhereIf('page_is_redirect = 1', $params['filterredir'] === 'redirects')) |
| 62 | + $this->addWhereIf('page_is_redirect = 0', $params['filterredir'] === 'nonredirects'); |
| 63 | + $this->addWhereFld('page_namespace', $params['namespace']); |
| 64 | + if (!is_null($params['from'])) |
| 65 | + $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from']))); |
| 66 | + if (isset ($params['prefix'])) |
| 67 | + $this->addWhere("page_title LIKE '" . $db->strencode(ApiQueryBase :: titleToKey($params['prefix'])) . "%'"); |
69 | 68 | |
70 | 69 | if (is_null($resultPageSet)) { |
71 | 70 | $this->addFields(array ( |
— | — | @@ -77,7 +76,8 @@ |
78 | 77 | } |
79 | 78 | |
80 | 79 | $this->addOption('USE INDEX', 'name_title'); |
81 | | - $this->addOption('LIMIT', $limit +1); |
| 80 | + $limit = $params['limit']; |
| 81 | + $this->addOption('LIMIT', $limit+1); |
82 | 82 | $this->addOption('ORDER BY', 'page_namespace, page_title'); |
83 | 83 | |
84 | 84 | $res = $this->select(__METHOD__); |
— | — | @@ -87,6 +87,7 @@ |
88 | 88 | while ($row = $db->fetchObject($res)) { |
89 | 89 | if (++ $count > $limit) { |
90 | 90 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
| 91 | + // TODO: Security issue - if the user has no right to view next title, it will still be shown |
91 | 92 | $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title)); |
92 | 93 | break; |
93 | 94 | } |
Index: trunk/phase3/includes/api/ApiQueryCategoryMembers.php |
— | — | @@ -92,6 +92,7 @@ |
93 | 93 | while ($row = $db->fetchObject($res)) { |
94 | 94 | if (++ $count > $limit) { |
95 | 95 | // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
| 96 | + // TODO: Security issue - if the user has no right to view next title, it will still be shown |
96 | 97 | $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey)); |
97 | 98 | break; |
98 | 99 | } |
Index: trunk/phase3/includes/api/ApiPageSet.php |
— | — | @@ -266,7 +266,6 @@ |
267 | 267 | */ |
268 | 268 | public function populateFromPageIDs($pageIDs) { |
269 | 269 | $this->profileIn(); |
270 | | - $pageIDs = array_map('intval', $pageIDs); // paranoia |
271 | 270 | $this->initFromPageIds($pageIDs); |
272 | 271 | $this->profileOut(); |
273 | 272 | } |
— | — | @@ -361,7 +360,8 @@ |
362 | 361 | private function initFromPageIds($pageids) { |
363 | 362 | if(empty($pageids)) |
364 | 363 | return; |
365 | | - |
| 364 | + |
| 365 | + $pageids = array_map('intval', $pageids); // paranoia |
366 | 366 | $set = array ( |
367 | 367 | 'page_id' => $pageids |
368 | 368 | ); |
Index: trunk/phase3/includes/api/ApiQueryBacklinks.php |
— | — | @@ -162,6 +162,7 @@ |
163 | 163 | $continue = $this->getContinueRedirStr(false, 0, $ns, $t, $row->page_id); |
164 | 164 | } else |
165 | 165 | $continue = $this->getContinueStr($row->page_id); |
| 166 | + // TODO: Security issue - if the user has no right to view next title, it will still be shown |
166 | 167 | $this->setContinueEnumParameter('continue', $continue); |
167 | 168 | break; |
168 | 169 | } |
Index: trunk/phase3/includes/api/ApiQueryAllLinks.php |
— | — | @@ -0,0 +1,181 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * Created on July 7, 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 | + * Query module to enumerate all available pages. |
| 34 | + * |
| 35 | + * @addtogroup API |
| 36 | + */ |
| 37 | +class ApiQueryAllLinks extends ApiQueryGeneratorBase { |
| 38 | + |
| 39 | + public function __construct($query, $moduleName) { |
| 40 | + parent :: __construct($query, $moduleName, 'al'); |
| 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 | + $db = $this->getDB(); |
| 54 | + $params = $this->extractRequestParams(); |
| 55 | + $this->debugPrint($params); |
| 56 | + |
| 57 | + $prop = array_flip($params['prop']); |
| 58 | + $fld_ids = isset($prop['ids']); |
| 59 | + $fld_title = isset($prop['title']); |
| 60 | + |
| 61 | + if ($params['unique']) { |
| 62 | + if (!is_null($resultPageSet)) |
| 63 | + $this->dieUsage($this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params'); |
| 64 | + if ($fld_ids) |
| 65 | + $this->dieUsage($this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params'); |
| 66 | + $this->addOption('DISTINCT'); |
| 67 | + } |
| 68 | + |
| 69 | + $this->addTables('pagelinks'); |
| 70 | + $this->addWhereFld('pl_namespace', $params['namespace']); |
| 71 | + |
| 72 | + if (!is_null($params['from'])) |
| 73 | + $this->addWhere('pl_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from']))); |
| 74 | + if (isset ($params['prefix'])) |
| 75 | + $this->addWhere("pl_title LIKE '" . $db->strencode(ApiQueryBase :: titleToKey($params['prefix'])) . "%'"); |
| 76 | + |
| 77 | + if (is_null($resultPageSet)) { |
| 78 | + $this->addFields(array ( |
| 79 | + 'pl_namespace', |
| 80 | + 'pl_title' |
| 81 | + )); |
| 82 | + $this->addFieldsIf('pl_from', $fld_ids); |
| 83 | + } else { |
| 84 | + $this->addFields('pl_from'); |
| 85 | + $pageids = array(); |
| 86 | + } |
| 87 | + |
| 88 | + $this->addOption('USE INDEX', 'pl_namespace'); |
| 89 | + $limit = $params['limit']; |
| 90 | + $this->addOption('LIMIT', $limit+1); |
| 91 | + $this->addOption('ORDER BY', 'pl_namespace, pl_title'); |
| 92 | + |
| 93 | + $res = $this->select(__METHOD__); |
| 94 | + |
| 95 | + $data = array (); |
| 96 | + $count = 0; |
| 97 | + while ($row = $db->fetchObject($res)) { |
| 98 | + if (++ $count > $limit) { |
| 99 | + // We've reached the one extra which shows that there are additional pages to be had. Stop here... |
| 100 | + // TODO: Security issue - if the user has no right to view next title, it will still be shown |
| 101 | + $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->pl_title)); |
| 102 | + break; |
| 103 | + } |
| 104 | + |
| 105 | + if (is_null($resultPageSet)) { |
| 106 | + $title = Title :: makeTitle($row->pl_namespace, $row->pl_title); |
| 107 | + if ($title->userCanRead()) { |
| 108 | + $vals = array(); |
| 109 | + if ($fld_ids) |
| 110 | + $vals['fromid'] = intval($row->pl_from); |
| 111 | + if ($fld_title) { |
| 112 | + $vals['ns'] = intval($title->getNamespace()); |
| 113 | + $vals['title'] = $title->getPrefixedText(); |
| 114 | + } |
| 115 | + $data[] = $vals; |
| 116 | + } |
| 117 | + } else { |
| 118 | + $pageids[] = $row->pl_from; |
| 119 | + } |
| 120 | + } |
| 121 | + $db->freeResult($res); |
| 122 | + |
| 123 | + if (is_null($resultPageSet)) { |
| 124 | + $result = $this->getResult(); |
| 125 | + $result->setIndexedTagName($data, 'l'); |
| 126 | + $result->addValue('query', $this->getModuleName(), $data); |
| 127 | + } else { |
| 128 | + $resultPageSet->populateFromPageIDs($pageids); |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + protected function getAllowedParams() { |
| 133 | + return array ( |
| 134 | + 'from' => null, |
| 135 | + 'prefix' => null, |
| 136 | + 'unique' => false, |
| 137 | + 'prop' => array ( |
| 138 | + ApiBase :: PARAM_ISMULTI => true, |
| 139 | + ApiBase :: PARAM_DFLT => 'title', |
| 140 | + ApiBase :: PARAM_TYPE => array ( |
| 141 | + 'ids', |
| 142 | + 'title' |
| 143 | + ) |
| 144 | + ), |
| 145 | + 'namespace' => array ( |
| 146 | + ApiBase :: PARAM_DFLT => 0, |
| 147 | + ApiBase :: PARAM_TYPE => 'namespace' |
| 148 | + ), |
| 149 | + 'limit' => array ( |
| 150 | + ApiBase :: PARAM_DFLT => 10, |
| 151 | + ApiBase :: PARAM_TYPE => 'limit', |
| 152 | + ApiBase :: PARAM_MIN => 1, |
| 153 | + ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1, |
| 154 | + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 |
| 155 | + ) |
| 156 | + ); |
| 157 | + } |
| 158 | + |
| 159 | + protected function getParamDescription() { |
| 160 | + return array ( |
| 161 | + 'from' => 'The page title to start enumerating from.', |
| 162 | + 'prefix' => 'Search for all page titles that begin with this value.', |
| 163 | + 'unique' => 'Only show unique links. Cannot be used with generator or prop=ids', |
| 164 | + 'namespace' => 'The namespace to enumerate.', |
| 165 | + 'limit' => 'How many total links to return.' |
| 166 | + ); |
| 167 | + } |
| 168 | + |
| 169 | + protected function getDescription() { |
| 170 | + return 'Enumerate all pages sequentially in a given namespace'; |
| 171 | + } |
| 172 | + |
| 173 | + protected function getExamples() { |
| 174 | + return array ( |
| 175 | + 'api.php?action=query&list=alllinks&alunique&alfrom=B', |
| 176 | + ); |
| 177 | + } |
| 178 | + |
| 179 | + public function getVersion() { |
| 180 | + return __CLASS__ . ': $Id$'; |
| 181 | + } |
| 182 | +} |
Property changes on: trunk/phase3/includes/api/ApiQueryAllLinks.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 183 | + native |
Added: svn:keywords |
2 | 184 | + Id |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -306,6 +306,7 @@ |
307 | 307 | 'ApiPageSet' => 'includes/api/ApiPageSet.php', |
308 | 308 | 'ApiQuery' => 'includes/api/ApiQuery.php', |
309 | 309 | 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php', |
| 310 | + 'ApiQueryAllLinks' => 'includes/api/ApiQueryAllLinks.php', |
310 | 311 | 'ApiQueryBase' => 'includes/api/ApiQueryBase.php', |
311 | 312 | 'ApiQueryGeneratorBase' => 'includes/api/ApiQueryBase.php', |
312 | 313 | 'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -308,6 +308,7 @@ |
309 | 309 | * Added prop=imageinfo - gets image properties and upload history |
310 | 310 | * (bug 10211) Added db server replication lag information in meta=siteinfo |
311 | 311 | * Added external url search within wiki pages (list=exturlusage) |
| 312 | +* Added link enumeration (list=alllinks) |
312 | 313 | |
313 | 314 | == Maintenance script changes since 1.10 == |
314 | 315 | |