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 Oct 16, 2006 |
||
6 | * |
||
7 | * Copyright © 2006 Yuri Astrakhan "<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 | * This is a three-in-one module to query: |
||
29 | * * backlinks - links pointing to the given page, |
||
30 | * * embeddedin - what pages transclude the given page within themselves, |
||
31 | * * imageusage - what pages use the given image |
||
32 | * |
||
33 | * @ingroup API |
||
34 | */ |
||
35 | class ApiQueryBacklinks extends ApiQueryGeneratorBase { |
||
36 | |||
37 | /** |
||
38 | * @var Title |
||
39 | */ |
||
40 | private $rootTitle; |
||
41 | |||
42 | private $params, $cont, $redirect; |
||
0 ignored issues
–
show
|
|||
43 | private $bl_ns, $bl_from, $bl_from_ns, $bl_table, $bl_code, $bl_title, $bl_fields, $hasNS; |
||
0 ignored issues
–
show
|
|||
44 | |||
45 | /** |
||
46 | * Maps ns and title to pageid |
||
47 | * |
||
48 | * @var array |
||
49 | */ |
||
50 | private $pageMap = []; |
||
51 | private $resultArr; |
||
52 | |||
53 | private $redirTitles = []; |
||
54 | private $continueStr = null; |
||
55 | |||
56 | // output element name, database column field prefix, database table |
||
57 | private $backlinksSettings = [ |
||
58 | 'backlinks' => [ |
||
59 | 'code' => 'bl', |
||
60 | 'prefix' => 'pl', |
||
61 | 'linktbl' => 'pagelinks', |
||
62 | 'helpurl' => 'https://www.mediawiki.org/wiki/API:Backlinks', |
||
63 | ], |
||
64 | 'embeddedin' => [ |
||
65 | 'code' => 'ei', |
||
66 | 'prefix' => 'tl', |
||
67 | 'linktbl' => 'templatelinks', |
||
68 | 'helpurl' => 'https://www.mediawiki.org/wiki/API:Embeddedin', |
||
69 | ], |
||
70 | 'imageusage' => [ |
||
71 | 'code' => 'iu', |
||
72 | 'prefix' => 'il', |
||
73 | 'linktbl' => 'imagelinks', |
||
74 | 'helpurl' => 'https://www.mediawiki.org/wiki/API:Imageusage', |
||
75 | ] |
||
76 | ]; |
||
77 | |||
78 | public function __construct( ApiQuery $query, $moduleName ) { |
||
79 | $settings = $this->backlinksSettings[$moduleName]; |
||
80 | $prefix = $settings['prefix']; |
||
81 | $code = $settings['code']; |
||
82 | $this->resultArr = []; |
||
83 | |||
84 | parent::__construct( $query, $moduleName, $code ); |
||
85 | $this->bl_ns = $prefix . '_namespace'; |
||
86 | $this->bl_from = $prefix . '_from'; |
||
87 | $this->bl_from_ns = $prefix . '_from_namespace'; |
||
88 | $this->bl_table = $settings['linktbl']; |
||
89 | $this->bl_code = $code; |
||
90 | $this->helpUrl = $settings['helpurl']; |
||
0 ignored issues
–
show
The property
helpUrl does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
91 | |||
92 | $this->hasNS = $moduleName !== 'imageusage'; |
||
93 | if ( $this->hasNS ) { |
||
94 | $this->bl_title = $prefix . '_title'; |
||
95 | $this->bl_fields = [ |
||
96 | $this->bl_ns, |
||
97 | $this->bl_title |
||
98 | ]; |
||
99 | } else { |
||
100 | $this->bl_title = $prefix . '_to'; |
||
101 | $this->bl_fields = [ |
||
102 | $this->bl_title |
||
103 | ]; |
||
104 | } |
||
105 | } |
||
106 | |||
107 | public function execute() { |
||
108 | $this->run(); |
||
109 | } |
||
110 | |||
111 | public function getCacheMode( $params ) { |
||
112 | return 'public'; |
||
113 | } |
||
114 | |||
115 | public function executeGenerator( $resultPageSet ) { |
||
116 | $this->run( $resultPageSet ); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * @param ApiPageSet $resultPageSet |
||
121 | * @return void |
||
122 | */ |
||
123 | private function runFirstQuery( $resultPageSet = null ) { |
||
124 | $this->addTables( [ $this->bl_table, 'page' ] ); |
||
125 | $this->addWhere( "{$this->bl_from}=page_id" ); |
||
126 | if ( is_null( $resultPageSet ) ) { |
||
127 | $this->addFields( [ 'page_id', 'page_title', 'page_namespace' ] ); |
||
128 | } else { |
||
129 | $this->addFields( $resultPageSet->getPageTableFields() ); |
||
130 | } |
||
131 | $this->addFields( [ 'page_is_redirect', 'from_ns' => 'page_namespace' ] ); |
||
132 | |||
133 | $this->addWhereFld( $this->bl_title, $this->rootTitle->getDBkey() ); |
||
134 | if ( $this->hasNS ) { |
||
135 | $this->addWhereFld( $this->bl_ns, $this->rootTitle->getNamespace() ); |
||
136 | } |
||
137 | $this->addWhereFld( $this->bl_from_ns, $this->params['namespace'] ); |
||
138 | |||
139 | if ( count( $this->cont ) >= 2 ) { |
||
140 | $op = $this->params['dir'] == 'descending' ? '<' : '>'; |
||
141 | if ( count( $this->params['namespace'] ) > 1 ) { |
||
142 | $this->addWhere( |
||
143 | "{$this->bl_from_ns} $op {$this->cont[0]} OR " . |
||
144 | "({$this->bl_from_ns} = {$this->cont[0]} AND " . |
||
145 | "{$this->bl_from} $op= {$this->cont[1]})" |
||
146 | ); |
||
147 | } else { |
||
148 | $this->addWhere( "{$this->bl_from} $op= {$this->cont[1]}" ); |
||
149 | } |
||
150 | } |
||
151 | |||
152 | View Code Duplication | if ( $this->params['filterredir'] == 'redirects' ) { |
|
153 | $this->addWhereFld( 'page_is_redirect', 1 ); |
||
154 | } elseif ( $this->params['filterredir'] == 'nonredirects' && !$this->redirect ) { |
||
155 | // bug 22245 - Check for !redirect, as filtering nonredirects, when |
||
156 | // getting what links to them is contradictory |
||
157 | $this->addWhereFld( 'page_is_redirect', 0 ); |
||
158 | } |
||
159 | |||
160 | $this->addOption( 'LIMIT', $this->params['limit'] + 1 ); |
||
161 | $sort = ( $this->params['dir'] == 'descending' ? ' DESC' : '' ); |
||
162 | $orderBy = []; |
||
163 | View Code Duplication | if ( count( $this->params['namespace'] ) > 1 ) { |
|
164 | $orderBy[] = $this->bl_from_ns . $sort; |
||
165 | } |
||
166 | $orderBy[] = $this->bl_from . $sort; |
||
167 | $this->addOption( 'ORDER BY', $orderBy ); |
||
168 | $this->addOption( 'STRAIGHT_JOIN' ); |
||
169 | |||
170 | $res = $this->select( __METHOD__ ); |
||
171 | $count = 0; |
||
172 | foreach ( $res as $row ) { |
||
173 | if ( ++$count > $this->params['limit'] ) { |
||
174 | // We've reached the one extra which shows that there are |
||
175 | // additional pages to be had. Stop here... |
||
176 | // Continue string may be overridden at a later step |
||
177 | $this->continueStr = "{$row->from_ns}|{$row->page_id}"; |
||
178 | break; |
||
179 | } |
||
180 | |||
181 | // Fill in continuation fields for later steps |
||
182 | if ( count( $this->cont ) < 2 ) { |
||
183 | $this->cont[] = $row->from_ns; |
||
184 | $this->cont[] = $row->page_id; |
||
185 | } |
||
186 | |||
187 | $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id; |
||
188 | $t = Title::makeTitle( $row->page_namespace, $row->page_title ); |
||
189 | if ( $row->page_is_redirect ) { |
||
190 | $this->redirTitles[] = $t; |
||
191 | } |
||
192 | |||
193 | if ( is_null( $resultPageSet ) ) { |
||
194 | $a = [ 'pageid' => intval( $row->page_id ) ]; |
||
195 | ApiQueryBase::addTitleInfo( $a, $t ); |
||
196 | if ( $row->page_is_redirect ) { |
||
197 | $a['redirect'] = true; |
||
198 | } |
||
199 | // Put all the results in an array first |
||
200 | $this->resultArr[$a['pageid']] = $a; |
||
201 | } else { |
||
202 | $resultPageSet->processDbRow( $row ); |
||
203 | } |
||
204 | } |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * @param ApiPageSet $resultPageSet |
||
209 | * @return void |
||
210 | */ |
||
211 | private function runSecondQuery( $resultPageSet = null ) { |
||
212 | $db = $this->getDB(); |
||
213 | $this->addTables( [ 'page', $this->bl_table ] ); |
||
214 | $this->addWhere( "{$this->bl_from}=page_id" ); |
||
215 | |||
216 | if ( is_null( $resultPageSet ) ) { |
||
217 | $this->addFields( [ 'page_id', 'page_title', 'page_namespace', 'page_is_redirect' ] ); |
||
218 | } else { |
||
219 | $this->addFields( $resultPageSet->getPageTableFields() ); |
||
220 | } |
||
221 | |||
222 | $this->addFields( [ $this->bl_title, 'from_ns' => 'page_namespace' ] ); |
||
223 | if ( $this->hasNS ) { |
||
224 | $this->addFields( $this->bl_ns ); |
||
225 | } |
||
226 | |||
227 | // We can't use LinkBatch here because $this->hasNS may be false |
||
228 | $titleWhere = []; |
||
229 | $allRedirNs = []; |
||
230 | $allRedirDBkey = []; |
||
231 | /** @var $t Title */ |
||
232 | foreach ( $this->redirTitles as $t ) { |
||
233 | $redirNs = $t->getNamespace(); |
||
234 | $redirDBkey = $t->getDBkey(); |
||
235 | $titleWhere[] = "{$this->bl_title} = " . $db->addQuotes( $redirDBkey ) . |
||
236 | ( $this->hasNS ? " AND {$this->bl_ns} = {$redirNs}" : '' ); |
||
237 | $allRedirNs[$redirNs] = true; |
||
238 | $allRedirDBkey[$redirDBkey] = true; |
||
239 | } |
||
240 | $this->addWhere( $db->makeList( $titleWhere, LIST_OR ) ); |
||
241 | $this->addWhereFld( 'page_namespace', $this->params['namespace'] ); |
||
242 | |||
243 | if ( count( $this->cont ) >= 6 ) { |
||
244 | $op = $this->params['dir'] == 'descending' ? '<' : '>'; |
||
245 | |||
246 | $where = "{$this->bl_from} $op= {$this->cont[5]}"; |
||
247 | // Don't bother with namespace, title, or from_namespace if it's |
||
248 | // otherwise constant in the where clause. |
||
249 | if ( count( $this->params['namespace'] ) > 1 ) { |
||
250 | $where = "{$this->bl_from_ns} $op {$this->cont[4]} OR " . |
||
251 | "({$this->bl_from_ns} = {$this->cont[4]} AND ($where))"; |
||
252 | } |
||
253 | if ( count( $allRedirDBkey ) > 1 ) { |
||
254 | $title = $db->addQuotes( $this->cont[3] ); |
||
255 | $where = "{$this->bl_title} $op $title OR " . |
||
256 | "({$this->bl_title} = $title AND ($where))"; |
||
257 | } |
||
258 | if ( $this->hasNS && count( $allRedirNs ) > 1 ) { |
||
259 | $where = "{$this->bl_ns} $op {$this->cont[2]} OR " . |
||
260 | "({$this->bl_ns} = {$this->cont[2]} AND ($where))"; |
||
261 | } |
||
262 | |||
263 | $this->addWhere( $where ); |
||
264 | } |
||
265 | View Code Duplication | if ( $this->params['filterredir'] == 'redirects' ) { |
|
266 | $this->addWhereFld( 'page_is_redirect', 1 ); |
||
267 | } elseif ( $this->params['filterredir'] == 'nonredirects' ) { |
||
268 | $this->addWhereFld( 'page_is_redirect', 0 ); |
||
269 | } |
||
270 | |||
271 | $this->addOption( 'LIMIT', $this->params['limit'] + 1 ); |
||
272 | $orderBy = []; |
||
273 | $sort = ( $this->params['dir'] == 'descending' ? ' DESC' : '' ); |
||
274 | // Don't order by namespace/title/from_namespace if it's constant in the WHERE clause |
||
275 | if ( $this->hasNS && count( $allRedirNs ) > 1 ) { |
||
276 | $orderBy[] = $this->bl_ns . $sort; |
||
277 | } |
||
278 | if ( count( $allRedirDBkey ) > 1 ) { |
||
279 | $orderBy[] = $this->bl_title . $sort; |
||
280 | } |
||
281 | View Code Duplication | if ( count( $this->params['namespace'] ) > 1 ) { |
|
282 | $orderBy[] = $this->bl_from_ns . $sort; |
||
283 | } |
||
284 | $orderBy[] = $this->bl_from . $sort; |
||
285 | $this->addOption( 'ORDER BY', $orderBy ); |
||
286 | $this->addOption( 'USE INDEX', [ 'page' => 'PRIMARY' ] ); |
||
287 | |||
288 | $res = $this->select( __METHOD__ ); |
||
289 | $count = 0; |
||
290 | foreach ( $res as $row ) { |
||
291 | $ns = $this->hasNS ? $row->{$this->bl_ns} : NS_FILE; |
||
292 | |||
293 | if ( ++$count > $this->params['limit'] ) { |
||
294 | // We've reached the one extra which shows that there are |
||
295 | // additional pages to be had. Stop here... |
||
296 | // Note we must keep the parameters for the first query constant |
||
297 | // This may be overridden at a later step |
||
298 | $title = $row->{$this->bl_title}; |
||
299 | $this->continueStr = implode( '|', array_slice( $this->cont, 0, 2 ) ) . |
||
300 | "|$ns|$title|{$row->from_ns}|{$row->page_id}"; |
||
301 | break; |
||
302 | } |
||
303 | |||
304 | // Fill in continuation fields for later steps |
||
305 | if ( count( $this->cont ) < 6 ) { |
||
306 | $this->cont[] = $ns; |
||
307 | $this->cont[] = $row->{$this->bl_title}; |
||
308 | $this->cont[] = $row->from_ns; |
||
309 | $this->cont[] = $row->page_id; |
||
310 | } |
||
311 | |||
312 | if ( is_null( $resultPageSet ) ) { |
||
313 | $a['pageid'] = intval( $row->page_id ); |
||
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. ![]() |
|||
314 | ApiQueryBase::addTitleInfo( $a, Title::makeTitle( $row->page_namespace, $row->page_title ) ); |
||
315 | if ( $row->page_is_redirect ) { |
||
316 | $a['redirect'] = true; |
||
317 | } |
||
318 | $parentID = $this->pageMap[$ns][$row->{$this->bl_title}]; |
||
319 | // Put all the results in an array first |
||
320 | $this->resultArr[$parentID]['redirlinks'][$row->page_id] = $a; |
||
321 | } else { |
||
322 | $resultPageSet->processDbRow( $row ); |
||
0 ignored issues
–
show
It seems like
$row defined by $row on line 290 can be null ; however, ApiPageSet::processDbRow() does not accept null , maybe add an additional type check?
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: /** @return stdClass|null */
function mayReturnNull() { }
function doesNotAcceptNull(stdClass $x) { }
// With potential error.
function withoutCheck() {
$x = mayReturnNull();
doesNotAcceptNull($x); // Potential error here.
}
// Safe - Alternative 1
function withCheck1() {
$x = mayReturnNull();
if ( ! $x instanceof stdClass) {
throw new \LogicException('$x must be defined.');
}
doesNotAcceptNull($x);
}
// Safe - Alternative 2
function withCheck2() {
$x = mayReturnNull();
if ($x instanceof stdClass) {
doesNotAcceptNull($x);
}
}
![]() |
|||
323 | } |
||
324 | } |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * @param ApiPageSet $resultPageSet |
||
329 | * @return void |
||
330 | */ |
||
331 | private function run( $resultPageSet = null ) { |
||
332 | $this->params = $this->extractRequestParams( false ); |
||
333 | $this->redirect = isset( $this->params['redirect'] ) && $this->params['redirect']; |
||
334 | $userMax = ( $this->redirect ? ApiBase::LIMIT_BIG1 / 2 : ApiBase::LIMIT_BIG1 ); |
||
335 | $botMax = ( $this->redirect ? ApiBase::LIMIT_BIG2 / 2 : ApiBase::LIMIT_BIG2 ); |
||
336 | |||
337 | $result = $this->getResult(); |
||
338 | |||
339 | if ( $this->params['limit'] == 'max' ) { |
||
340 | $this->params['limit'] = $this->getMain()->canApiHighLimits() ? $botMax : $userMax; |
||
341 | $result->addParsedLimit( $this->getModuleName(), $this->params['limit'] ); |
||
342 | } else { |
||
343 | $this->params['limit'] = intval( $this->params['limit'] ); |
||
344 | $this->validateLimit( 'limit', $this->params['limit'], 1, $userMax, $botMax ); |
||
345 | } |
||
346 | |||
347 | $this->rootTitle = $this->getTitleOrPageId( $this->params )->getTitle(); |
||
348 | |||
349 | // only image titles are allowed for the root in imageinfo mode |
||
350 | if ( !$this->hasNS && $this->rootTitle->getNamespace() !== NS_FILE ) { |
||
351 | $this->dieUsage( |
||
352 | "The title for {$this->getModuleName()} query must be a file", |
||
353 | 'bad_image_title' |
||
354 | ); |
||
355 | } |
||
356 | |||
357 | // Parse and validate continuation parameter |
||
358 | $this->cont = []; |
||
359 | if ( $this->params['continue'] !== null ) { |
||
360 | $cont = explode( '|', $this->params['continue'] ); |
||
361 | |||
362 | switch ( count( $cont ) ) { |
||
363 | View Code Duplication | case 8: |
|
364 | // redirect page ID for result adding |
||
365 | $this->cont[7] = (int)$cont[7]; |
||
366 | $this->dieContinueUsageIf( $cont[7] !== (string)$this->cont[7] ); |
||
367 | |||
368 | /* Fall through */ |
||
369 | |||
370 | View Code Duplication | case 7: |
|
371 | // top-level page ID for result adding |
||
372 | $this->cont[6] = (int)$cont[6]; |
||
373 | $this->dieContinueUsageIf( $cont[6] !== (string)$this->cont[6] ); |
||
374 | |||
375 | /* Fall through */ |
||
376 | |||
377 | case 6: |
||
378 | // ns for 2nd query (even for imageusage) |
||
379 | $this->cont[2] = (int)$cont[2]; |
||
380 | $this->dieContinueUsageIf( $cont[2] !== (string)$this->cont[2] ); |
||
381 | |||
382 | // title for 2nd query |
||
383 | $this->cont[3] = $cont[3]; |
||
384 | |||
385 | // from_ns for 2nd query |
||
386 | $this->cont[4] = (int)$cont[4]; |
||
387 | $this->dieContinueUsageIf( $cont[4] !== (string)$this->cont[4] ); |
||
388 | |||
389 | // from_id for 1st query |
||
390 | $this->cont[5] = (int)$cont[5]; |
||
391 | $this->dieContinueUsageIf( $cont[5] !== (string)$this->cont[5] ); |
||
392 | |||
393 | /* Fall through */ |
||
394 | |||
395 | case 2: |
||
396 | // from_ns for 1st query |
||
397 | $this->cont[0] = (int)$cont[0]; |
||
398 | $this->dieContinueUsageIf( $cont[0] !== (string)$this->cont[0] ); |
||
399 | |||
400 | // from_id for 1st query |
||
401 | $this->cont[1] = (int)$cont[1]; |
||
402 | $this->dieContinueUsageIf( $cont[1] !== (string)$this->cont[1] ); |
||
403 | |||
404 | break; |
||
405 | |||
406 | default: |
||
407 | $this->dieContinueUsageIf( true ); |
||
408 | } |
||
409 | |||
410 | ksort( $this->cont ); |
||
411 | } |
||
412 | |||
413 | $this->runFirstQuery( $resultPageSet ); |
||
414 | if ( $this->redirect && count( $this->redirTitles ) ) { |
||
415 | $this->resetQueryParams(); |
||
416 | $this->runSecondQuery( $resultPageSet ); |
||
417 | } |
||
418 | |||
419 | // Fill in any missing fields in case it's needed below |
||
420 | $this->cont += [ 0, 0, 0, '', 0, 0, 0 ]; |
||
421 | |||
422 | if ( is_null( $resultPageSet ) ) { |
||
423 | // Try to add the result data in one go and pray that it fits |
||
424 | $code = $this->bl_code; |
||
425 | $data = array_map( function ( $arr ) use ( $result, $code ) { |
||
426 | if ( isset( $arr['redirlinks'] ) ) { |
||
427 | $arr['redirlinks'] = array_values( $arr['redirlinks'] ); |
||
428 | ApiResult::setIndexedTagName( $arr['redirlinks'], $code ); |
||
429 | } |
||
430 | return $arr; |
||
431 | }, array_values( $this->resultArr ) ); |
||
432 | $fit = $result->addValue( 'query', $this->getModuleName(), $data ); |
||
433 | if ( !$fit ) { |
||
434 | // It didn't fit. Add elements one by one until the |
||
435 | // result is full. |
||
436 | ksort( $this->resultArr ); |
||
437 | if ( count( $this->cont ) >= 7 ) { |
||
438 | $startAt = $this->cont[6]; |
||
439 | } else { |
||
440 | reset( $this->resultArr ); |
||
441 | $startAt = key( $this->resultArr ); |
||
442 | } |
||
443 | $idx = 0; |
||
444 | foreach ( $this->resultArr as $pageID => $arr ) { |
||
445 | if ( $pageID < $startAt ) { |
||
446 | continue; |
||
447 | } |
||
448 | |||
449 | // Add the basic entry without redirlinks first |
||
450 | $fit = $result->addValue( |
||
451 | [ 'query', $this->getModuleName() ], |
||
452 | $idx, array_diff_key( $arr, [ 'redirlinks' => '' ] ) ); |
||
453 | View Code Duplication | if ( !$fit ) { |
|
454 | $this->continueStr = implode( '|', array_slice( $this->cont, 0, 6 ) ) . |
||
455 | "|$pageID"; |
||
456 | break; |
||
457 | } |
||
458 | |||
459 | $hasRedirs = false; |
||
460 | $redirLinks = isset( $arr['redirlinks'] ) ? (array)$arr['redirlinks'] : []; |
||
461 | ksort( $redirLinks ); |
||
462 | if ( count( $this->cont ) >= 8 && $pageID == $startAt ) { |
||
463 | $redirStartAt = $this->cont[7]; |
||
464 | } else { |
||
465 | reset( $redirLinks ); |
||
466 | $redirStartAt = key( $redirLinks ); |
||
467 | } |
||
468 | foreach ( $redirLinks as $key => $redir ) { |
||
469 | if ( $key < $redirStartAt ) { |
||
470 | continue; |
||
471 | } |
||
472 | |||
473 | $fit = $result->addValue( |
||
474 | [ 'query', $this->getModuleName(), $idx, 'redirlinks' ], |
||
475 | null, $redir ); |
||
476 | View Code Duplication | if ( !$fit ) { |
|
477 | $this->continueStr = implode( '|', array_slice( $this->cont, 0, 6 ) ) . |
||
478 | "|$pageID|$key"; |
||
479 | break; |
||
480 | } |
||
481 | $hasRedirs = true; |
||
482 | } |
||
483 | if ( $hasRedirs ) { |
||
484 | $result->addIndexedTagName( |
||
485 | [ 'query', $this->getModuleName(), $idx, 'redirlinks' ], |
||
486 | $this->bl_code ); |
||
487 | } |
||
488 | if ( !$fit ) { |
||
489 | break; |
||
490 | } |
||
491 | |||
492 | $idx++; |
||
493 | } |
||
494 | } |
||
495 | |||
496 | $result->addIndexedTagName( |
||
497 | [ 'query', $this->getModuleName() ], |
||
498 | $this->bl_code |
||
499 | ); |
||
500 | } |
||
501 | if ( !is_null( $this->continueStr ) ) { |
||
502 | $this->setContinueEnumParameter( 'continue', $this->continueStr ); |
||
503 | } |
||
504 | } |
||
505 | |||
506 | public function getAllowedParams() { |
||
507 | $retval = [ |
||
508 | 'title' => [ |
||
509 | ApiBase::PARAM_TYPE => 'string', |
||
510 | ], |
||
511 | 'pageid' => [ |
||
512 | ApiBase::PARAM_TYPE => 'integer', |
||
513 | ], |
||
514 | 'continue' => [ |
||
515 | ApiBase::PARAM_HELP_MSG => 'api-help-param-continue', |
||
516 | ], |
||
517 | 'namespace' => [ |
||
518 | ApiBase::PARAM_ISMULTI => true, |
||
519 | ApiBase::PARAM_TYPE => 'namespace' |
||
520 | ], |
||
521 | 'dir' => [ |
||
522 | ApiBase::PARAM_DFLT => 'ascending', |
||
523 | ApiBase::PARAM_TYPE => [ |
||
524 | 'ascending', |
||
525 | 'descending' |
||
526 | ] |
||
527 | ], |
||
528 | 'filterredir' => [ |
||
529 | ApiBase::PARAM_DFLT => 'all', |
||
530 | ApiBase::PARAM_TYPE => [ |
||
531 | 'all', |
||
532 | 'redirects', |
||
533 | 'nonredirects' |
||
534 | ] |
||
535 | ], |
||
536 | 'limit' => [ |
||
537 | ApiBase::PARAM_DFLT => 10, |
||
538 | ApiBase::PARAM_TYPE => 'limit', |
||
539 | ApiBase::PARAM_MIN => 1, |
||
540 | ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, |
||
541 | ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2 |
||
542 | ] |
||
543 | ]; |
||
544 | if ( $this->getModuleName() == 'embeddedin' ) { |
||
545 | return $retval; |
||
546 | } |
||
547 | $retval['redirect'] = false; |
||
548 | |||
549 | return $retval; |
||
550 | } |
||
551 | |||
552 | protected function getExamplesMessages() { |
||
553 | static $examples = [ |
||
554 | 'backlinks' => [ |
||
555 | 'action=query&list=backlinks&bltitle=Main%20Page' |
||
556 | => 'apihelp-query+backlinks-example-simple', |
||
557 | 'action=query&generator=backlinks&gbltitle=Main%20Page&prop=info' |
||
558 | => 'apihelp-query+backlinks-example-generator', |
||
559 | ], |
||
560 | 'embeddedin' => [ |
||
561 | 'action=query&list=embeddedin&eititle=Template:Stub' |
||
562 | => 'apihelp-query+embeddedin-example-simple', |
||
563 | 'action=query&generator=embeddedin&geititle=Template:Stub&prop=info' |
||
564 | => 'apihelp-query+embeddedin-example-generator', |
||
565 | ], |
||
566 | 'imageusage' => [ |
||
567 | 'action=query&list=imageusage&iutitle=File:Albert%20Einstein%20Head.jpg' |
||
568 | => 'apihelp-query+imageusage-example-simple', |
||
569 | 'action=query&generator=imageusage&giutitle=File:Albert%20Einstein%20Head.jpg&prop=info' |
||
570 | => 'apihelp-query+imageusage-example-generator', |
||
571 | ] |
||
572 | ]; |
||
573 | |||
574 | return $examples[$this->getModuleName()]; |
||
575 | } |
||
576 | |||
577 | public function getHelpUrls() { |
||
578 | return $this->helpUrl; |
||
579 | } |
||
580 | } |
||
581 |
Only declaring a single property per statement allows you to later on add doc comments more easily.
It is also recommended by PSR2, so it is a common style that many people expect.