Index: trunk/phase3/includes/api/ApiQueryDeletedrevs.php |
— | — | @@ -56,11 +56,24 @@ |
57 | 57 | $fld_len = isset($prop['len']); |
58 | 58 | $fld_content = isset($prop['content']); |
59 | 59 | $fld_token = isset($prop['token']); |
60 | | - |
| 60 | + |
61 | 61 | $result = $this->getResult(); |
62 | 62 | $pageSet = $this->getPageSet(); |
63 | 63 | $titles = $pageSet->getTitles(); |
64 | 64 | $data = array(); |
| 65 | + |
| 66 | + // This module operates in three modes: |
| 67 | + // 'revs': List deleted revs for certain titles |
| 68 | + // 'user': List deleted revs by a certain user |
| 69 | + // 'all': List all deleted revs |
| 70 | + $mode = 'all'; |
| 71 | + if(count($titles) > 0) |
| 72 | + $mode = 'revs'; |
| 73 | + else if(!is_null($params['user'])) |
| 74 | + $mode = 'user'; |
| 75 | + |
| 76 | + if(!is_null($params['user']) && !is_null($params['excludeuser'])) |
| 77 | + $this->dieUsage('user and excludeuser cannot be used together', 'badparams'); |
65 | 78 | |
66 | 79 | $this->addTables('archive'); |
67 | 80 | $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp')); |
— | — | @@ -102,17 +115,63 @@ |
103 | 116 | $token = $wgUser->editToken(); |
104 | 117 | |
105 | 118 | // We need a custom WHERE clause that matches all titles. |
106 | | - if(count($titles) > 0) |
| 119 | + if($mode == 'revs') |
107 | 120 | { |
108 | 121 | $lb = new LinkBatch($titles); |
109 | 122 | $where = $lb->constructSet('ar', $db); |
110 | 123 | $this->addWhere($where); |
111 | | - } else { |
112 | | - $this->dieUsage('You have to specify a page title or titles'); |
113 | 124 | } |
| 125 | + elseif($mode == 'all') |
| 126 | + { |
| 127 | + $this->addWhereFld('ar_namespace', $params['namespace']); |
| 128 | + if(!is_null($params['from'])) |
| 129 | + { |
| 130 | + $from = $this->getDB()->strencode($this->titleToKey($params['from'])); |
| 131 | + $this->addWhere("ar_title >= '$from'"); |
| 132 | + } |
| 133 | + } |
| 134 | + |
| 135 | + if(!is_null($params['user'])) { |
| 136 | + $this->addWhereFld('ar_user_text', $params['user']); |
| 137 | + } elseif(!is_null($params['excludeuser'])) { |
| 138 | + $this->addWhere('ar_user_text != ' . |
| 139 | + $this->getDB()->addQuotes($params['excludeuser'])); |
| 140 | + } |
| 141 | + |
| 142 | + if(!is_null($params['continue']) && $mode == 'all') |
| 143 | + { |
| 144 | + $cont = explode('|', $params['continue']); |
| 145 | + if(count($cont) != 2) |
| 146 | + $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue"); |
| 147 | + $title = $this->getDB()->strencode($this->titleToKey($cont[0])); |
| 148 | + $ts = $this->getDB()->strencode($cont[1]); |
| 149 | + $this->addWhere("ar_title > '$title' OR " . |
| 150 | + "(ar_title = '$title' AND " . |
| 151 | + "ar_timestamp >= '$ts')"); |
| 152 | + } |
114 | 153 | |
115 | 154 | $this->addOption('LIMIT', $limit + 1); |
116 | | - $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']); |
| 155 | + $this->addOption('USE INDEX', array('archive' => ($mode == 'user' ? 'usertext_timestamp' : 'name_title_timestamp'))); |
| 156 | + if($mode == 'all') |
| 157 | + { |
| 158 | + if($params['unique']) |
| 159 | + { |
| 160 | + $this->addOption('GROUP BY', 'ar_title'); |
| 161 | + $this->addOption('ORDER BY', 'ar_title'); |
| 162 | + } |
| 163 | + else |
| 164 | + $this->addOption('ORDER BY', 'ar_title, ar_timestamp'); |
| 165 | + } |
| 166 | + else |
| 167 | + { |
| 168 | + if($mode == 'revs') |
| 169 | + { |
| 170 | + // Sort by ns and title in the same order as timestamp for efficiency |
| 171 | + $this->addWhereRange('ar_namespace', $params['dir'], null, null); |
| 172 | + $this->addWhereRange('ar_title', $params['dir'], null, null); |
| 173 | + } |
| 174 | + $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']); |
| 175 | + } |
117 | 176 | $res = $this->select(__METHOD__); |
118 | 177 | $pages = array(); |
119 | 178 | $count = 0; |
— | — | @@ -122,7 +181,11 @@ |
123 | 182 | if(++$count > $limit) |
124 | 183 | { |
125 | 184 | // We've had enough |
126 | | - $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp)); |
| 185 | + if($mode == 'all') |
| 186 | + $this->setContinueEnumParameter('continue', $this->keyToTitle($row->ar_title) . '|' . |
| 187 | + $row->ar_timestamp); |
| 188 | + else |
| 189 | + $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp)); |
127 | 190 | break; |
128 | 191 | } |
129 | 192 | |
— | — | @@ -183,6 +246,19 @@ |
184 | 247 | ), |
185 | 248 | ApiBase :: PARAM_DFLT => 'older' |
186 | 249 | ), |
| 250 | + 'from' => null, |
| 251 | + 'continue' => null, |
| 252 | + 'unique' => false, |
| 253 | + 'user' => array( |
| 254 | + ApiBase :: PARAM_TYPE => 'user' |
| 255 | + ), |
| 256 | + 'excludeuser' => array( |
| 257 | + ApiBase :: PARAM_TYPE => 'user' |
| 258 | + ), |
| 259 | + 'namespace' => array( |
| 260 | + ApiBase :: PARAM_TYPE => 'namespace', |
| 261 | + ApiBase :: PARAM_DFLT => 0, |
| 262 | + ), |
187 | 263 | 'limit' => array( |
188 | 264 | ApiBase :: PARAM_DFLT => 10, |
189 | 265 | ApiBase :: PARAM_TYPE => 'limit', |
— | — | @@ -202,30 +278,47 @@ |
203 | 279 | 'token' |
204 | 280 | ), |
205 | 281 | ApiBase :: PARAM_ISMULTI => true |
206 | | - ) |
| 282 | + ), |
207 | 283 | ); |
208 | 284 | } |
209 | 285 | |
210 | 286 | public function getParamDescription() { |
211 | 287 | return array ( |
212 | | - 'start' => 'The timestamp to start enumerating from', |
213 | | - 'end' => 'The timestamp to stop enumerating at', |
214 | | - 'dir' => 'The direction in which to enumerate', |
| 288 | + 'start' => 'The timestamp to start enumerating from. (1,2)', |
| 289 | + 'end' => 'The timestamp to stop enumerating at. (1,2)', |
| 290 | + 'dir' => 'The direction in which to enumerate. (1,2)', |
215 | 291 | 'limit' => 'The maximum amount of revisions to list', |
216 | | - 'prop' => 'Which properties to get' |
| 292 | + 'prop' => 'Which properties to get', |
| 293 | + 'namespace' => 'Only list pages in this namespace (3)', |
| 294 | + 'user' => 'Only list revisions by this user', |
| 295 | + 'excludeuser' => 'Don\'t list revisions by this user', |
| 296 | + 'from' => 'Start listing at this title (3)', |
| 297 | + 'continue' => 'When more results are available, use this to continue (3)', |
| 298 | + 'unique' => 'List only one revision for each page (3)', |
217 | 299 | ); |
218 | 300 | } |
219 | 301 | |
220 | 302 | public function getDescription() { |
221 | | - return 'List deleted revisions.'; |
| 303 | + return array( 'List deleted revisions.', |
| 304 | + 'This module operates in three modes:', |
| 305 | + '1) List deleted revisions for the given title(s), sorted by timestamp', |
| 306 | + '2) List deleted contributions for the given user, sorted by timestamp (no titles specified)', |
| 307 | + '3) List all deleted revisions in the given namespace, sorted by title and timestamp (no titles specified, druser not set)', |
| 308 | + 'Certain parameters only apply to some modes and are ignored in others.', |
| 309 | + 'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3.', |
| 310 | + ); |
222 | 311 | } |
223 | 312 | |
224 | 313 | protected function getExamples() { |
225 | 314 | return array ( |
226 | | - 'List the first 50 deleted revisions', |
| 315 | + 'List the last deleted revisions of Main Page and Talk:Main Page, with content (mode 1):', |
| 316 | + ' api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&drprop=user|comment|content', |
| 317 | + 'List the last 50 deleted contributions by Bob (mode 2):', |
| 318 | + ' api.php?action=query&list=deletedrevs&druser=Bob&drlimit=50', |
| 319 | + 'List the first 50 deleted revisions in the main namespace (mode 3):', |
227 | 320 | ' api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50', |
228 | | - 'List the last deleted revisions of Main Page and Talk:Main Page, with content:', |
229 | | - ' api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&drprop=user|comment|content' |
| 321 | + 'List the first 50 deleted pages in the Talk namespace (mode 3):', |
| 322 | + ' api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=1&drunique', |
230 | 323 | ); |
231 | 324 | } |
232 | 325 | |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -44,6 +44,8 @@ |
45 | 45 | * (bug 16798) JSON encoding errors for some characters outside the BMP |
46 | 46 | * (bug 16629) prop=info&inprop=protection lists empty legacy protections |
47 | 47 | incorrectly |
| 48 | +* (bug 16858) Revamped list=deletedrevs to make listing deleted contributions |
| 49 | + and listing all deleted pages possible |
48 | 50 | |
49 | 51 | === Languages updated in 1.15 === |
50 | 52 | |