This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * |
||
4 | * |
||
5 | * Created on Jul 2, 2007 |
||
6 | * |
||
7 | * Copyright © 2007 Roan Kattouw "<Firstname>.<Lastname>@gmail.com" |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or modify |
||
10 | * it under the terms of the GNU General Public License as published by |
||
11 | * the Free Software Foundation; either version 2 of the License, or |
||
12 | * (at your option) any later version. |
||
13 | * |
||
14 | * This program is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | * GNU General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU General Public License along |
||
20 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
22 | * http://www.gnu.org/copyleft/gpl.html |
||
23 | * |
||
24 | * @file |
||
25 | */ |
||
26 | |||
27 | /** |
||
28 | * Query module to enumerate all deleted revisions. |
||
29 | * |
||
30 | * @ingroup API |
||
31 | * @deprecated since 1.25 |
||
32 | */ |
||
33 | class ApiQueryDeletedrevs extends ApiQueryBase { |
||
34 | |||
35 | public function __construct( ApiQuery $query, $moduleName ) { |
||
36 | parent::__construct( $query, $moduleName, 'dr' ); |
||
37 | } |
||
38 | |||
39 | public function execute() { |
||
40 | $user = $this->getUser(); |
||
41 | // Before doing anything at all, let's check permissions |
||
42 | if ( !$user->isAllowed( 'deletedhistory' ) ) { |
||
43 | $this->dieUsage( |
||
44 | 'You don\'t have permission to view deleted revision information', |
||
45 | 'permissiondenied' |
||
46 | ); |
||
47 | } |
||
48 | |||
49 | $this->setWarning( |
||
50 | 'list=deletedrevs has been deprecated. Please use prop=deletedrevisions or ' . |
||
51 | 'list=alldeletedrevisions instead.' |
||
52 | ); |
||
53 | $this->logFeatureUsage( 'action=query&list=deletedrevs' ); |
||
54 | |||
55 | $db = $this->getDB(); |
||
56 | $params = $this->extractRequestParams( false ); |
||
57 | $prop = array_flip( $params['prop'] ); |
||
58 | $fld_parentid = isset( $prop['parentid'] ); |
||
59 | $fld_revid = isset( $prop['revid'] ); |
||
60 | $fld_user = isset( $prop['user'] ); |
||
61 | $fld_userid = isset( $prop['userid'] ); |
||
62 | $fld_comment = isset( $prop['comment'] ); |
||
63 | $fld_parsedcomment = isset( $prop['parsedcomment'] ); |
||
64 | $fld_minor = isset( $prop['minor'] ); |
||
65 | $fld_len = isset( $prop['len'] ); |
||
66 | $fld_sha1 = isset( $prop['sha1'] ); |
||
67 | $fld_content = isset( $prop['content'] ); |
||
68 | $fld_token = isset( $prop['token'] ); |
||
69 | $fld_tags = isset( $prop['tags'] ); |
||
70 | |||
71 | if ( isset( $prop['token'] ) ) { |
||
72 | $p = $this->getModulePrefix(); |
||
73 | $this->setWarning( |
||
74 | "{$p}prop=token has been deprecated. Please use action=query&meta=tokens instead." |
||
75 | ); |
||
76 | } |
||
77 | |||
78 | // If we're in a mode that breaks the same-origin policy, no tokens can |
||
79 | // be obtained |
||
80 | if ( $this->lacksSameOriginSecurity() ) { |
||
81 | $fld_token = false; |
||
82 | } |
||
83 | |||
84 | // If user can't undelete, no tokens |
||
85 | if ( !$user->isAllowed( 'undelete' ) ) { |
||
86 | $fld_token = false; |
||
87 | } |
||
88 | |||
89 | $result = $this->getResult(); |
||
90 | $pageSet = $this->getPageSet(); |
||
91 | $titles = $pageSet->getTitles(); |
||
92 | |||
93 | // This module operates in three modes: |
||
94 | // 'revs': List deleted revs for certain titles (1) |
||
95 | // 'user': List deleted revs by a certain user (2) |
||
96 | // 'all': List all deleted revs in NS (3) |
||
97 | $mode = 'all'; |
||
98 | if ( count( $titles ) > 0 ) { |
||
99 | $mode = 'revs'; |
||
100 | } elseif ( !is_null( $params['user'] ) ) { |
||
101 | $mode = 'user'; |
||
102 | } |
||
103 | |||
104 | if ( $mode == 'revs' || $mode == 'user' ) { |
||
105 | // Ignore namespace and unique due to inability to know whether they were purposely set |
||
106 | foreach ( [ 'from', 'to', 'prefix', /*'namespace', 'unique'*/ ] as $p ) { |
||
107 | if ( !is_null( $params[$p] ) ) { |
||
108 | $this->dieUsage( "The '{$p}' parameter cannot be used in modes 1 or 2", 'badparams' ); |
||
109 | } |
||
110 | } |
||
111 | } else { |
||
112 | foreach ( [ 'start', 'end' ] as $p ) { |
||
113 | if ( !is_null( $params[$p] ) ) { |
||
114 | $this->dieUsage( "The {$p} parameter cannot be used in mode 3", 'badparams' ); |
||
115 | } |
||
116 | } |
||
117 | } |
||
118 | |||
119 | View Code Duplication | if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) ) { |
|
120 | $this->dieUsage( 'user and excludeuser cannot be used together', 'badparams' ); |
||
121 | } |
||
122 | |||
123 | $this->addTables( 'archive' ); |
||
124 | $this->addFields( [ 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_deleted', 'ar_id' ] ); |
||
125 | |||
126 | $this->addFieldsIf( 'ar_parent_id', $fld_parentid ); |
||
127 | $this->addFieldsIf( 'ar_rev_id', $fld_revid ); |
||
128 | $this->addFieldsIf( 'ar_user_text', $fld_user ); |
||
129 | $this->addFieldsIf( 'ar_user', $fld_userid ); |
||
130 | $this->addFieldsIf( 'ar_comment', $fld_comment || $fld_parsedcomment ); |
||
131 | $this->addFieldsIf( 'ar_minor_edit', $fld_minor ); |
||
132 | $this->addFieldsIf( 'ar_len', $fld_len ); |
||
133 | $this->addFieldsIf( 'ar_sha1', $fld_sha1 ); |
||
134 | |||
135 | View Code Duplication | if ( $fld_tags ) { |
|
136 | $this->addTables( 'tag_summary' ); |
||
137 | $this->addJoinConds( |
||
138 | [ 'tag_summary' => [ 'LEFT JOIN', [ 'ar_rev_id=ts_rev_id' ] ] ] |
||
139 | ); |
||
140 | $this->addFields( 'ts_tags' ); |
||
141 | } |
||
142 | |||
143 | View Code Duplication | if ( !is_null( $params['tag'] ) ) { |
|
144 | $this->addTables( 'change_tag' ); |
||
145 | $this->addJoinConds( |
||
146 | [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ] |
||
147 | ); |
||
148 | $this->addWhereFld( 'ct_tag', $params['tag'] ); |
||
149 | } |
||
150 | |||
151 | View Code Duplication | if ( $fld_content ) { |
|
152 | // Modern MediaWiki has the content for deleted revs in the 'text' |
||
153 | // table using fields old_text and old_flags. But revisions deleted |
||
154 | // pre-1.5 store the content in the 'archive' table directly using |
||
155 | // fields ar_text and ar_flags, and no corresponding 'text' row. So |
||
156 | // we have to LEFT JOIN and fetch all four fields, plus ar_text_id |
||
157 | // to be able to tell the difference. |
||
158 | $this->addTables( 'text' ); |
||
159 | $this->addJoinConds( |
||
160 | [ 'text' => [ 'LEFT JOIN', [ 'ar_text_id=old_id' ] ] ] |
||
161 | ); |
||
162 | $this->addFields( [ 'ar_text', 'ar_flags', 'ar_text_id', 'old_text', 'old_flags' ] ); |
||
163 | |||
164 | // This also means stricter restrictions |
||
165 | if ( !$user->isAllowedAny( 'undelete', 'deletedtext' ) ) { |
||
166 | $this->dieUsage( |
||
167 | 'You don\'t have permission to view deleted revision content', |
||
168 | 'permissiondenied' |
||
169 | ); |
||
170 | } |
||
171 | } |
||
172 | // Check limits |
||
173 | $userMax = $fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1; |
||
174 | $botMax = $fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2; |
||
175 | |||
176 | $limit = $params['limit']; |
||
177 | |||
178 | if ( $limit == 'max' ) { |
||
179 | $limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax; |
||
180 | $this->getResult()->addParsedLimit( $this->getModuleName(), $limit ); |
||
181 | } |
||
182 | |||
183 | $this->validateLimit( 'limit', $limit, 1, $userMax, $botMax ); |
||
184 | |||
185 | if ( $fld_token ) { |
||
186 | // Undelete tokens are identical for all pages, so we cache one here |
||
187 | $token = $user->getEditToken( '', $this->getMain()->getRequest() ); |
||
188 | } |
||
189 | |||
190 | $dir = $params['dir']; |
||
191 | |||
192 | // We need a custom WHERE clause that matches all titles. |
||
193 | if ( $mode == 'revs' ) { |
||
194 | $lb = new LinkBatch( $titles ); |
||
195 | $where = $lb->constructSet( 'ar', $db ); |
||
196 | $this->addWhere( $where ); |
||
0 ignored issues
–
show
|
|||
197 | } elseif ( $mode == 'all' ) { |
||
198 | $this->addWhereFld( 'ar_namespace', $params['namespace'] ); |
||
199 | |||
200 | $from = $params['from'] === null |
||
201 | ? null |
||
202 | : $this->titlePartToKey( $params['from'], $params['namespace'] ); |
||
203 | $to = $params['to'] === null |
||
204 | ? null |
||
205 | : $this->titlePartToKey( $params['to'], $params['namespace'] ); |
||
206 | $this->addWhereRange( 'ar_title', $dir, $from, $to ); |
||
207 | |||
208 | View Code Duplication | if ( isset( $params['prefix'] ) ) { |
|
209 | $this->addWhere( 'ar_title' . $db->buildLike( |
||
210 | $this->titlePartToKey( $params['prefix'], $params['namespace'] ), |
||
211 | $db->anyString() ) ); |
||
212 | } |
||
213 | } |
||
214 | |||
215 | View Code Duplication | if ( !is_null( $params['user'] ) ) { |
|
216 | $this->addWhereFld( 'ar_user_text', $params['user'] ); |
||
217 | } elseif ( !is_null( $params['excludeuser'] ) ) { |
||
218 | $this->addWhere( 'ar_user_text != ' . |
||
219 | $db->addQuotes( $params['excludeuser'] ) ); |
||
220 | } |
||
221 | |||
222 | View Code Duplication | if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) { |
|
223 | // Paranoia: avoid brute force searches (bug 17342) |
||
224 | // (shouldn't be able to get here without 'deletedhistory', but |
||
225 | // check it again just in case) |
||
226 | if ( !$user->isAllowed( 'deletedhistory' ) ) { |
||
227 | $bitmask = Revision::DELETED_USER; |
||
228 | } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) { |
||
229 | $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED; |
||
230 | } else { |
||
231 | $bitmask = 0; |
||
232 | } |
||
233 | if ( $bitmask ) { |
||
234 | $this->addWhere( $db->bitAnd( 'ar_deleted', $bitmask ) . " != $bitmask" ); |
||
235 | } |
||
236 | } |
||
237 | |||
238 | if ( !is_null( $params['continue'] ) ) { |
||
239 | $cont = explode( '|', $params['continue'] ); |
||
240 | $op = ( $dir == 'newer' ? '>' : '<' ); |
||
241 | if ( $mode == 'all' || $mode == 'revs' ) { |
||
242 | $this->dieContinueUsageIf( count( $cont ) != 4 ); |
||
243 | $ns = intval( $cont[0] ); |
||
244 | $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] ); |
||
245 | $title = $db->addQuotes( $cont[1] ); |
||
246 | $ts = $db->addQuotes( $db->timestamp( $cont[2] ) ); |
||
247 | $ar_id = (int)$cont[3]; |
||
248 | $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[3] ); |
||
249 | $this->addWhere( "ar_namespace $op $ns OR " . |
||
250 | "(ar_namespace = $ns AND " . |
||
251 | "(ar_title $op $title OR " . |
||
252 | "(ar_title = $title AND " . |
||
253 | "(ar_timestamp $op $ts OR " . |
||
254 | "(ar_timestamp = $ts AND " . |
||
255 | "ar_id $op= $ar_id)))))" ); |
||
256 | } else { |
||
257 | $this->dieContinueUsageIf( count( $cont ) != 2 ); |
||
258 | $ts = $db->addQuotes( $db->timestamp( $cont[0] ) ); |
||
259 | $ar_id = (int)$cont[1]; |
||
260 | $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[1] ); |
||
261 | $this->addWhere( "ar_timestamp $op $ts OR " . |
||
262 | "(ar_timestamp = $ts AND " . |
||
263 | "ar_id $op= $ar_id)" ); |
||
264 | } |
||
265 | } |
||
266 | |||
267 | $this->addOption( 'LIMIT', $limit + 1 ); |
||
268 | $this->addOption( |
||
269 | 'USE INDEX', |
||
270 | [ 'archive' => ( $mode == 'user' ? 'usertext_timestamp' : 'name_title_timestamp' ) ] |
||
271 | ); |
||
272 | if ( $mode == 'all' ) { |
||
273 | if ( $params['unique'] ) { |
||
274 | // @todo Does this work on non-MySQL? |
||
275 | $this->addOption( 'GROUP BY', 'ar_title' ); |
||
276 | } else { |
||
277 | $sort = ( $dir == 'newer' ? '' : ' DESC' ); |
||
278 | $this->addOption( 'ORDER BY', [ |
||
279 | 'ar_title' . $sort, |
||
280 | 'ar_timestamp' . $sort, |
||
281 | 'ar_id' . $sort, |
||
282 | ] ); |
||
283 | } |
||
284 | } else { |
||
285 | if ( $mode == 'revs' ) { |
||
286 | // Sort by ns and title in the same order as timestamp for efficiency |
||
287 | $this->addWhereRange( 'ar_namespace', $dir, null, null ); |
||
288 | $this->addWhereRange( 'ar_title', $dir, null, null ); |
||
289 | } |
||
290 | $this->addTimestampWhereRange( 'ar_timestamp', $dir, $params['start'], $params['end'] ); |
||
291 | // Include in ORDER BY for uniqueness |
||
292 | $this->addWhereRange( 'ar_id', $dir, null, null ); |
||
293 | } |
||
294 | $res = $this->select( __METHOD__ ); |
||
295 | $pageMap = []; // Maps ns&title to (fake) pageid |
||
296 | $count = 0; |
||
297 | $newPageID = 0; |
||
298 | foreach ( $res as $row ) { |
||
299 | View Code Duplication | if ( ++$count > $limit ) { |
|
300 | // We've had enough |
||
301 | if ( $mode == 'all' || $mode == 'revs' ) { |
||
302 | $this->setContinueEnumParameter( 'continue', |
||
303 | "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id" |
||
304 | ); |
||
305 | } else { |
||
306 | $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" ); |
||
307 | } |
||
308 | break; |
||
309 | } |
||
310 | |||
311 | $rev = []; |
||
312 | $anyHidden = false; |
||
313 | |||
314 | $rev['timestamp'] = wfTimestamp( TS_ISO_8601, $row->ar_timestamp ); |
||
315 | if ( $fld_revid ) { |
||
316 | $rev['revid'] = intval( $row->ar_rev_id ); |
||
317 | } |
||
318 | if ( $fld_parentid && !is_null( $row->ar_parent_id ) ) { |
||
319 | $rev['parentid'] = intval( $row->ar_parent_id ); |
||
320 | } |
||
321 | if ( $fld_user || $fld_userid ) { |
||
322 | if ( $row->ar_deleted & Revision::DELETED_USER ) { |
||
323 | $rev['userhidden'] = true; |
||
324 | $anyHidden = true; |
||
325 | } |
||
326 | if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_USER, $user ) ) { |
||
327 | if ( $fld_user ) { |
||
328 | $rev['user'] = $row->ar_user_text; |
||
329 | } |
||
330 | if ( $fld_userid ) { |
||
331 | $rev['userid'] = (int)$row->ar_user; |
||
332 | } |
||
333 | } |
||
334 | } |
||
335 | |||
336 | if ( $fld_comment || $fld_parsedcomment ) { |
||
337 | if ( $row->ar_deleted & Revision::DELETED_COMMENT ) { |
||
338 | $rev['commenthidden'] = true; |
||
339 | $anyHidden = true; |
||
340 | } |
||
341 | if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_COMMENT, $user ) ) { |
||
342 | if ( $fld_comment ) { |
||
343 | $rev['comment'] = $row->ar_comment; |
||
344 | } |
||
345 | if ( $fld_parsedcomment ) { |
||
346 | $title = Title::makeTitle( $row->ar_namespace, $row->ar_title ); |
||
347 | $rev['parsedcomment'] = Linker::formatComment( $row->ar_comment, $title ); |
||
348 | } |
||
349 | } |
||
350 | } |
||
351 | |||
352 | if ( $fld_minor ) { |
||
353 | $rev['minor'] = $row->ar_minor_edit == 1; |
||
354 | } |
||
355 | if ( $fld_len ) { |
||
356 | $rev['len'] = $row->ar_len; |
||
357 | } |
||
358 | if ( $fld_sha1 ) { |
||
359 | if ( $row->ar_deleted & Revision::DELETED_TEXT ) { |
||
360 | $rev['sha1hidden'] = true; |
||
361 | $anyHidden = true; |
||
362 | } |
||
363 | View Code Duplication | if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) { |
|
364 | if ( $row->ar_sha1 != '' ) { |
||
365 | $rev['sha1'] = Wikimedia\base_convert( $row->ar_sha1, 36, 16, 40 ); |
||
366 | } else { |
||
367 | $rev['sha1'] = ''; |
||
368 | } |
||
369 | } |
||
370 | } |
||
371 | if ( $fld_content ) { |
||
372 | if ( $row->ar_deleted & Revision::DELETED_TEXT ) { |
||
373 | $rev['texthidden'] = true; |
||
374 | $anyHidden = true; |
||
375 | } |
||
376 | if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) { |
||
377 | if ( isset( $row->ar_text ) && !$row->ar_text_id ) { |
||
378 | // Pre-1.5 ar_text row (if condition from Revision::newFromArchiveRow) |
||
379 | ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row, 'ar_' ) ); |
||
380 | } else { |
||
381 | ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row ) ); |
||
382 | } |
||
383 | } |
||
384 | } |
||
385 | |||
386 | View Code Duplication | if ( $fld_tags ) { |
|
387 | if ( $row->ts_tags ) { |
||
388 | $tags = explode( ',', $row->ts_tags ); |
||
389 | ApiResult::setIndexedTagName( $tags, 'tag' ); |
||
390 | $rev['tags'] = $tags; |
||
391 | } else { |
||
392 | $rev['tags'] = []; |
||
393 | } |
||
394 | } |
||
395 | |||
396 | if ( $anyHidden && ( $row->ar_deleted & Revision::DELETED_RESTRICTED ) ) { |
||
397 | $rev['suppressed'] = true; |
||
398 | } |
||
399 | |||
400 | if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) { |
||
401 | $pageID = $newPageID++; |
||
402 | $pageMap[$row->ar_namespace][$row->ar_title] = $pageID; |
||
403 | $a['revisions'] = [ $rev ]; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$a was never initialized. Although not strictly required by PHP, it is generally a good practice to add $a = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
404 | ApiResult::setIndexedTagName( $a['revisions'], 'rev' ); |
||
0 ignored issues
–
show
The variable
$a does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
405 | $title = Title::makeTitle( $row->ar_namespace, $row->ar_title ); |
||
406 | ApiQueryBase::addTitleInfo( $a, $title ); |
||
407 | if ( $fld_token ) { |
||
408 | $a['token'] = $token; |
||
0 ignored issues
–
show
The variable
$token does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
409 | } |
||
410 | $fit = $result->addValue( [ 'query', $this->getModuleName() ], $pageID, $a ); |
||
411 | View Code Duplication | } else { |
|
412 | $pageID = $pageMap[$row->ar_namespace][$row->ar_title]; |
||
413 | $fit = $result->addValue( |
||
414 | [ 'query', $this->getModuleName(), $pageID, 'revisions' ], |
||
415 | null, $rev ); |
||
416 | } |
||
417 | View Code Duplication | if ( !$fit ) { |
|
418 | if ( $mode == 'all' || $mode == 'revs' ) { |
||
419 | $this->setContinueEnumParameter( 'continue', |
||
420 | "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id" |
||
421 | ); |
||
422 | } else { |
||
423 | $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" ); |
||
424 | } |
||
425 | break; |
||
426 | } |
||
427 | } |
||
428 | $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'page' ); |
||
429 | } |
||
430 | |||
431 | public function isDeprecated() { |
||
432 | return true; |
||
433 | } |
||
434 | |||
435 | public function getAllowedParams() { |
||
436 | return [ |
||
437 | 'start' => [ |
||
438 | ApiBase::PARAM_TYPE => 'timestamp', |
||
439 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 1, 2 ] ], |
||
440 | ], |
||
441 | 'end' => [ |
||
442 | ApiBase::PARAM_TYPE => 'timestamp', |
||
443 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 1, 2 ] ], |
||
444 | ], |
||
445 | 'dir' => [ |
||
446 | ApiBase::PARAM_TYPE => [ |
||
447 | 'newer', |
||
448 | 'older' |
||
449 | ], |
||
450 | ApiBase::PARAM_DFLT => 'older', |
||
451 | ApiBase::PARAM_HELP_MSG => 'api-help-param-direction', |
||
452 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 1, 3 ] ], |
||
453 | ], |
||
454 | 'from' => [ |
||
455 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 3 ] ], |
||
456 | ], |
||
457 | 'to' => [ |
||
458 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 3 ] ], |
||
459 | ], |
||
460 | 'prefix' => [ |
||
461 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 3 ] ], |
||
462 | ], |
||
463 | 'unique' => [ |
||
464 | ApiBase::PARAM_DFLT => false, |
||
465 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 3 ] ], |
||
466 | ], |
||
467 | 'namespace' => [ |
||
468 | ApiBase::PARAM_TYPE => 'namespace', |
||
469 | ApiBase::PARAM_DFLT => NS_MAIN, |
||
470 | ApiBase::PARAM_HELP_MSG_INFO => [ [ 'modes', 3 ] ], |
||
471 | ], |
||
472 | 'tag' => null, |
||
473 | 'user' => [ |
||
474 | ApiBase::PARAM_TYPE => 'user' |
||
475 | ], |
||
476 | 'excludeuser' => [ |
||
477 | ApiBase::PARAM_TYPE => 'user' |
||
478 | ], |
||
479 | 'prop' => [ |
||
480 | ApiBase::PARAM_DFLT => 'user|comment', |
||
481 | ApiBase::PARAM_TYPE => [ |
||
482 | 'revid', |
||
483 | 'parentid', |
||
484 | 'user', |
||
485 | 'userid', |
||
486 | 'comment', |
||
487 | 'parsedcomment', |
||
488 | 'minor', |
||
489 | 'len', |
||
490 | 'sha1', |
||
491 | 'content', |
||
492 | 'token', |
||
493 | 'tags' |
||
494 | ], |
||
495 | ApiBase::PARAM_ISMULTI => true |
||
496 | ], |
||
497 | 'limit' => [ |
||
498 | ApiBase::PARAM_DFLT => 10, |
||
499 | ApiBase::PARAM_TYPE => 'limit', |
||
500 | ApiBase::PARAM_MIN => 1, |
||
501 | ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, |
||
502 | ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2 |
||
503 | ], |
||
504 | 'continue' => [ |
||
505 | ApiBase::PARAM_HELP_MSG => 'api-help-param-continue', |
||
506 | ], |
||
507 | ]; |
||
508 | } |
||
509 | |||
510 | View Code Duplication | protected function getExamplesMessages() { |
|
511 | return [ |
||
512 | 'action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&' . |
||
513 | 'drprop=user|comment|content' |
||
514 | => 'apihelp-query+deletedrevs-example-mode1', |
||
515 | 'action=query&list=deletedrevs&druser=Bob&drlimit=50' |
||
516 | => 'apihelp-query+deletedrevs-example-mode2', |
||
517 | 'action=query&list=deletedrevs&drdir=newer&drlimit=50' |
||
518 | => 'apihelp-query+deletedrevs-example-mode3-main', |
||
519 | 'action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=1&drunique=' |
||
520 | => 'apihelp-query+deletedrevs-example-mode3-talk', |
||
521 | ]; |
||
522 | } |
||
523 | |||
524 | public function getHelpUrls() { |
||
525 | return 'https://www.mediawiki.org/wiki/API:Deletedrevs'; |
||
526 | } |
||
527 | } |
||
528 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.