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 Dec 01, 2007 |
||
6 | * |
||
7 | * Copyright © 2008 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 | * @ingroup API |
||
29 | */ |
||
30 | class ApiParamInfo extends ApiBase { |
||
31 | |||
32 | private $helpFormat; |
||
33 | private $context; |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
![]() |
|||
34 | |||
35 | public function __construct( ApiMain $main, $action ) { |
||
36 | parent::__construct( $main, $action ); |
||
37 | } |
||
38 | |||
39 | public function execute() { |
||
40 | // Get parameters |
||
41 | $params = $this->extractRequestParams(); |
||
42 | |||
43 | $this->helpFormat = $params['helpformat']; |
||
44 | $this->context = new RequestContext; |
||
45 | $this->context->setUser( new User ); // anon to avoid caching issues |
||
46 | $this->context->setLanguage( $this->getMain()->getLanguage() ); |
||
47 | |||
48 | if ( is_array( $params['modules'] ) ) { |
||
49 | $modules = []; |
||
50 | foreach ( $params['modules'] as $path ) { |
||
51 | if ( $path === '*' || $path === '**' ) { |
||
52 | $path = "main+$path"; |
||
53 | } |
||
54 | if ( substr( $path, -2 ) === '+*' || substr( $path, -2 ) === ' *' ) { |
||
55 | $submodules = true; |
||
56 | $path = substr( $path, 0, -2 ); |
||
57 | $recursive = false; |
||
58 | } elseif ( substr( $path, -3 ) === '+**' || substr( $path, -3 ) === ' **' ) { |
||
59 | $submodules = true; |
||
60 | $path = substr( $path, 0, -3 ); |
||
61 | $recursive = true; |
||
62 | } else { |
||
63 | $submodules = false; |
||
64 | } |
||
65 | |||
66 | if ( $submodules ) { |
||
67 | try { |
||
68 | $module = $this->getModuleFromPath( $path ); |
||
69 | } catch ( UsageException $ex ) { |
||
70 | $this->setWarning( $ex->getMessage() ); |
||
71 | } |
||
72 | $submodules = $this->listAllSubmodules( $module, $recursive ); |
||
0 ignored issues
–
show
The variable
$recursive 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
![]() It seems like
$module defined by $this->getModuleFromPath($path) on line 68 can be null ; however, ApiParamInfo::listAllSubmodules() 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);
}
}
![]() |
|||
73 | if ( $submodules ) { |
||
74 | $modules = array_merge( $modules, $submodules ); |
||
75 | } else { |
||
76 | $this->setWarning( "Module $path has no submodules" ); |
||
77 | } |
||
78 | } else { |
||
79 | $modules[] = $path; |
||
80 | } |
||
81 | } |
||
82 | } else { |
||
83 | $modules = []; |
||
84 | } |
||
85 | |||
86 | View Code Duplication | if ( is_array( $params['querymodules'] ) ) { |
|
87 | $queryModules = $params['querymodules']; |
||
88 | foreach ( $queryModules as $m ) { |
||
89 | $modules[] = 'query+' . $m; |
||
90 | } |
||
91 | } else { |
||
92 | $queryModules = []; |
||
93 | } |
||
94 | |||
95 | View Code Duplication | if ( is_array( $params['formatmodules'] ) ) { |
|
96 | $formatModules = $params['formatmodules']; |
||
97 | foreach ( $formatModules as $m ) { |
||
98 | $modules[] = $m; |
||
99 | } |
||
100 | } else { |
||
101 | $formatModules = []; |
||
102 | } |
||
103 | |||
104 | $modules = array_unique( $modules ); |
||
105 | |||
106 | $res = []; |
||
107 | |||
108 | foreach ( $modules as $m ) { |
||
109 | try { |
||
110 | $module = $this->getModuleFromPath( $m ); |
||
111 | } catch ( UsageException $ex ) { |
||
112 | $this->setWarning( $ex->getMessage() ); |
||
113 | continue; |
||
114 | } |
||
115 | $key = 'modules'; |
||
116 | |||
117 | // Back compat |
||
118 | $isBCQuery = false; |
||
119 | if ( $module->getParent() && $module->getParent()->getModuleName() == 'query' && |
||
120 | in_array( $module->getModuleName(), $queryModules ) |
||
121 | ) { |
||
122 | $isBCQuery = true; |
||
123 | $key = 'querymodules'; |
||
124 | } |
||
125 | if ( in_array( $module->getModuleName(), $formatModules ) ) { |
||
126 | $key = 'formatmodules'; |
||
127 | } |
||
128 | |||
129 | $item = $this->getModuleInfo( $module ); |
||
0 ignored issues
–
show
It seems like
$module defined by $this->getModuleFromPath($m) on line 110 can be null ; however, ApiParamInfo::getModuleInfo() 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);
}
}
![]() |
|||
130 | if ( $isBCQuery ) { |
||
131 | $item['querytype'] = $item['group']; |
||
132 | } |
||
133 | $res[$key][] = $item; |
||
134 | } |
||
135 | |||
136 | $result = $this->getResult(); |
||
137 | $result->addValue( [ $this->getModuleName() ], 'helpformat', $this->helpFormat ); |
||
138 | |||
139 | foreach ( $res as $key => $stuff ) { |
||
140 | ApiResult::setIndexedTagName( $res[$key], 'module' ); |
||
141 | } |
||
142 | |||
143 | if ( $params['mainmodule'] ) { |
||
144 | $res['mainmodule'] = $this->getModuleInfo( $this->getMain() ); |
||
145 | } |
||
146 | |||
147 | if ( $params['pagesetmodule'] ) { |
||
148 | $pageSet = new ApiPageSet( $this->getMain()->getModuleManager()->getModule( 'query' ) ); |
||
0 ignored issues
–
show
It seems like
$this->getMain()->getMod...r()->getModule('query') can be null ; however, __construct() 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);
}
}
![]() |
|||
149 | $res['pagesetmodule'] = $this->getModuleInfo( $pageSet ); |
||
150 | unset( $res['pagesetmodule']['name'] ); |
||
151 | unset( $res['pagesetmodule']['path'] ); |
||
152 | unset( $res['pagesetmodule']['group'] ); |
||
153 | } |
||
154 | |||
155 | $result->addValue( null, $this->getModuleName(), $res ); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * List all submodules of a module |
||
160 | * @param ApiBase $module |
||
161 | * @param boolean $recursive |
||
162 | * @return string[] |
||
163 | */ |
||
164 | private function listAllSubmodules( ApiBase $module, $recursive ) { |
||
165 | $manager = $module->getModuleManager(); |
||
166 | if ( $manager ) { |
||
167 | $paths = []; |
||
168 | $names = $manager->getNames(); |
||
169 | sort( $names ); |
||
170 | foreach ( $names as $name ) { |
||
171 | $submodule = $manager->getModule( $name ); |
||
172 | $paths[] = $submodule->getModulePath(); |
||
173 | if ( $recursive && $submodule->getModuleManager() ) { |
||
174 | $paths = array_merge( $paths, $this->listAllSubmodules( $submodule, $recursive ) ); |
||
0 ignored issues
–
show
It seems like
$submodule defined by $manager->getModule($name) on line 171 can be null ; however, ApiParamInfo::listAllSubmodules() 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);
}
}
![]() |
|||
175 | } |
||
176 | } |
||
177 | } |
||
178 | return $paths; |
||
0 ignored issues
–
show
The variable
$paths 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
![]() |
|||
179 | } |
||
180 | |||
181 | /** |
||
182 | * @param array $res Result array |
||
183 | * @param string $key Result key |
||
184 | * @param Message[] $msgs |
||
185 | * @param bool $joinLists |
||
186 | */ |
||
187 | protected function formatHelpMessages( array &$res, $key, array $msgs, $joinLists = false ) { |
||
188 | switch ( $this->helpFormat ) { |
||
189 | case 'none': |
||
190 | break; |
||
191 | |||
192 | View Code Duplication | case 'wikitext': |
|
193 | $ret = []; |
||
194 | foreach ( $msgs as $m ) { |
||
195 | $ret[] = $m->setContext( $this->context )->text(); |
||
196 | } |
||
197 | $res[$key] = implode( "\n\n", $ret ); |
||
198 | if ( $joinLists ) { |
||
199 | $res[$key] = preg_replace( '!^(([*#:;])[^\n]*)\n\n(?=\2)!m', "$1\n", $res[$key] ); |
||
200 | } |
||
201 | break; |
||
202 | |||
203 | View Code Duplication | case 'html': |
|
204 | $ret = []; |
||
205 | foreach ( $msgs as $m ) { |
||
206 | $ret[] = $m->setContext( $this->context )->parseAsBlock(); |
||
207 | } |
||
208 | $ret = implode( "\n", $ret ); |
||
209 | if ( $joinLists ) { |
||
210 | $ret = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $ret ); |
||
211 | } |
||
212 | $res[$key] = Parser::stripOuterParagraph( $ret ); |
||
213 | break; |
||
214 | |||
215 | case 'raw': |
||
216 | $res[$key] = []; |
||
217 | View Code Duplication | foreach ( $msgs as $m ) { |
|
218 | $a = [ |
||
219 | 'key' => $m->getKey(), |
||
220 | 'params' => $m->getParams(), |
||
221 | ]; |
||
222 | ApiResult::setIndexedTagName( $a['params'], 'param' ); |
||
223 | if ( $m instanceof ApiHelpParamValueMessage ) { |
||
224 | $a['forvalue'] = $m->getParamValue(); |
||
225 | } |
||
226 | $res[$key][] = $a; |
||
227 | } |
||
228 | ApiResult::setIndexedTagName( $res[$key], 'msg' ); |
||
229 | break; |
||
230 | } |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * @param ApiBase $module |
||
235 | * @return ApiResult |
||
236 | */ |
||
237 | private function getModuleInfo( $module ) { |
||
238 | $ret = []; |
||
239 | $path = $module->getModulePath(); |
||
240 | |||
241 | $ret['name'] = $module->getModuleName(); |
||
242 | $ret['classname'] = get_class( $module ); |
||
243 | $ret['path'] = $path; |
||
244 | if ( !$module->isMain() ) { |
||
245 | $ret['group'] = $module->getParent()->getModuleManager()->getModuleGroup( |
||
246 | $module->getModuleName() |
||
247 | ); |
||
248 | } |
||
249 | $ret['prefix'] = $module->getModulePrefix(); |
||
250 | |||
251 | $sourceInfo = $module->getModuleSourceInfo(); |
||
252 | if ( $sourceInfo ) { |
||
253 | $ret['source'] = $sourceInfo['name']; |
||
254 | if ( isset( $sourceInfo['namemsg'] ) ) { |
||
255 | $ret['sourcename'] = $this->context->msg( $sourceInfo['namemsg'] )->text(); |
||
256 | } else { |
||
257 | $ret['sourcename'] = $ret['source']; |
||
258 | } |
||
259 | |||
260 | $link = SpecialPage::getTitleFor( 'Version', 'License/' . $sourceInfo['name'] )->getFullURL(); |
||
261 | if ( isset( $sourceInfo['license-name'] ) ) { |
||
262 | $ret['licensetag'] = $sourceInfo['license-name']; |
||
263 | $ret['licenselink'] = (string)$link; |
||
264 | } elseif ( SpecialVersion::getExtLicenseFileName( dirname( $sourceInfo['path'] ) ) ) { |
||
0 ignored issues
–
show
The expression
\SpecialVersion::getExtL...e($sourceInfo['path'])) of type false|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
265 | $ret['licenselink'] = (string)$link; |
||
266 | } |
||
267 | } |
||
268 | |||
269 | $this->formatHelpMessages( $ret, 'description', $module->getFinalDescription() ); |
||
270 | |||
271 | foreach ( $module->getHelpFlags() as $flag ) { |
||
272 | $ret[$flag] = true; |
||
273 | } |
||
274 | |||
275 | $ret['helpurls'] = (array)$module->getHelpUrls(); |
||
276 | if ( isset( $ret['helpurls'][0] ) && $ret['helpurls'][0] === false ) { |
||
277 | $ret['helpurls'] = []; |
||
278 | } |
||
279 | ApiResult::setIndexedTagName( $ret['helpurls'], 'helpurl' ); |
||
280 | |||
281 | if ( $this->helpFormat !== 'none' ) { |
||
282 | $ret['examples'] = []; |
||
283 | $examples = $module->getExamplesMessages(); |
||
284 | foreach ( $examples as $qs => $msg ) { |
||
285 | $item = [ |
||
286 | 'query' => $qs |
||
287 | ]; |
||
288 | $msg = ApiBase::makeMessage( $msg, $this->context, [ |
||
289 | $module->getModulePrefix(), |
||
290 | $module->getModuleName(), |
||
291 | $module->getModulePath() |
||
292 | ] ); |
||
293 | $this->formatHelpMessages( $item, 'description', [ $msg ] ); |
||
294 | if ( isset( $item['description'] ) ) { |
||
295 | if ( is_array( $item['description'] ) ) { |
||
296 | $item['description'] = $item['description'][0]; |
||
297 | } else { |
||
298 | ApiResult::setSubelementsList( $item, 'description' ); |
||
299 | } |
||
300 | } |
||
301 | $ret['examples'][] = $item; |
||
302 | } |
||
303 | ApiResult::setIndexedTagName( $ret['examples'], 'example' ); |
||
304 | } |
||
305 | |||
306 | $ret['parameters'] = []; |
||
307 | $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP ); |
||
308 | $paramDesc = $module->getFinalParamDescription(); |
||
309 | foreach ( $params as $name => $settings ) { |
||
0 ignored issues
–
show
The expression
$params of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
310 | if ( !is_array( $settings ) ) { |
||
311 | $settings = [ ApiBase::PARAM_DFLT => $settings ]; |
||
312 | } |
||
313 | |||
314 | $item = [ |
||
315 | 'name' => $name |
||
316 | ]; |
||
317 | if ( isset( $paramDesc[$name] ) ) { |
||
318 | $this->formatHelpMessages( $item, 'description', $paramDesc[$name], true ); |
||
319 | } |
||
320 | |||
321 | $item['required'] = !empty( $settings[ApiBase::PARAM_REQUIRED] ); |
||
322 | |||
323 | if ( !empty( $settings[ApiBase::PARAM_DEPRECATED] ) ) { |
||
324 | $item['deprecated'] = true; |
||
325 | } |
||
326 | |||
327 | if ( $name === 'token' && $module->needsToken() ) { |
||
328 | $item['tokentype'] = $module->needsToken(); |
||
329 | } |
||
330 | |||
331 | View Code Duplication | if ( !isset( $settings[ApiBase::PARAM_TYPE] ) ) { |
|
332 | $dflt = isset( $settings[ApiBase::PARAM_DFLT] ) |
||
333 | ? $settings[ApiBase::PARAM_DFLT] |
||
334 | : null; |
||
335 | if ( is_bool( $dflt ) ) { |
||
336 | $settings[ApiBase::PARAM_TYPE] = 'boolean'; |
||
337 | } elseif ( is_string( $dflt ) || is_null( $dflt ) ) { |
||
338 | $settings[ApiBase::PARAM_TYPE] = 'string'; |
||
339 | } elseif ( is_int( $dflt ) ) { |
||
340 | $settings[ApiBase::PARAM_TYPE] = 'integer'; |
||
341 | } |
||
342 | } |
||
343 | |||
344 | if ( isset( $settings[ApiBase::PARAM_DFLT] ) ) { |
||
345 | switch ( $settings[ApiBase::PARAM_TYPE] ) { |
||
346 | case 'boolean': |
||
347 | $item['default'] = (bool)$settings[ApiBase::PARAM_DFLT]; |
||
348 | break; |
||
349 | case 'string': |
||
350 | case 'text': |
||
351 | case 'password': |
||
352 | $item['default'] = strval( $settings[ApiBase::PARAM_DFLT] ); |
||
353 | break; |
||
354 | case 'integer': |
||
355 | case 'limit': |
||
356 | $item['default'] = intval( $settings[ApiBase::PARAM_DFLT] ); |
||
357 | break; |
||
358 | case 'timestamp': |
||
359 | $item['default'] = wfTimestamp( TS_ISO_8601, $settings[ApiBase::PARAM_DFLT] ); |
||
360 | break; |
||
361 | default: |
||
362 | $item['default'] = $settings[ApiBase::PARAM_DFLT]; |
||
363 | break; |
||
364 | } |
||
365 | } |
||
366 | |||
367 | $item['multi'] = !empty( $settings[ApiBase::PARAM_ISMULTI] ); |
||
368 | if ( $item['multi'] ) { |
||
369 | $item['limit'] = $this->getMain()->canApiHighLimits() ? |
||
370 | ApiBase::LIMIT_SML2 : |
||
371 | ApiBase::LIMIT_SML1; |
||
372 | $item['lowlimit'] = ApiBase::LIMIT_SML1; |
||
373 | $item['highlimit'] = ApiBase::LIMIT_SML2; |
||
374 | } |
||
375 | |||
376 | if ( !empty( $settings[ApiBase::PARAM_ALLOW_DUPLICATES] ) ) { |
||
377 | $item['allowsduplicates'] = true; |
||
378 | } |
||
379 | |||
380 | if ( isset( $settings[ApiBase::PARAM_TYPE] ) ) { |
||
381 | if ( $settings[ApiBase::PARAM_TYPE] === 'submodule' ) { |
||
382 | if ( isset( $settings[ApiBase::PARAM_SUBMODULE_MAP] ) ) { |
||
383 | ksort( $settings[ApiBase::PARAM_SUBMODULE_MAP] ); |
||
384 | $item['type'] = array_keys( $settings[ApiBase::PARAM_SUBMODULE_MAP] ); |
||
385 | $item['submodules'] = $settings[ApiBase::PARAM_SUBMODULE_MAP]; |
||
386 | } else { |
||
387 | $item['type'] = $module->getModuleManager()->getNames( $name ); |
||
388 | sort( $item['type'] ); |
||
389 | $prefix = $module->isMain() |
||
390 | ? '' : ( $module->getModulePath() . '+' ); |
||
391 | $item['submodules'] = []; |
||
392 | foreach ( $item['type'] as $v ) { |
||
393 | $item['submodules'][$v] = $prefix . $v; |
||
394 | } |
||
395 | } |
||
396 | if ( isset( $settings[ApiBase::PARAM_SUBMODULE_PARAM_PREFIX] ) ) { |
||
397 | $item['submoduleparamprefix'] = $settings[ApiBase::PARAM_SUBMODULE_PARAM_PREFIX]; |
||
398 | } |
||
399 | } elseif ( $settings[ApiBase::PARAM_TYPE] === 'tags' ) { |
||
400 | $item['type'] = ChangeTags::listExplicitlyDefinedTags(); |
||
401 | } else { |
||
402 | $item['type'] = $settings[ApiBase::PARAM_TYPE]; |
||
403 | } |
||
404 | if ( is_array( $item['type'] ) ) { |
||
405 | // To prevent sparse arrays from being serialized to JSON as objects |
||
406 | $item['type'] = array_values( $item['type'] ); |
||
407 | ApiResult::setIndexedTagName( $item['type'], 't' ); |
||
408 | } |
||
409 | } |
||
410 | if ( isset( $settings[ApiBase::PARAM_MAX] ) ) { |
||
411 | $item['max'] = $settings[ApiBase::PARAM_MAX]; |
||
412 | } |
||
413 | if ( isset( $settings[ApiBase::PARAM_MAX2] ) ) { |
||
414 | $item['highmax'] = $settings[ApiBase::PARAM_MAX2]; |
||
415 | } |
||
416 | if ( isset( $settings[ApiBase::PARAM_MIN] ) ) { |
||
417 | $item['min'] = $settings[ApiBase::PARAM_MIN]; |
||
418 | } |
||
419 | if ( !empty( $settings[ApiBase::PARAM_RANGE_ENFORCE] ) ) { |
||
420 | $item['enforcerange'] = true; |
||
421 | } |
||
422 | |||
423 | if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) { |
||
424 | $item['info'] = []; |
||
425 | foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) { |
||
426 | $tag = array_shift( $i ); |
||
427 | $info = [ |
||
428 | 'name' => $tag, |
||
429 | ]; |
||
430 | if ( count( $i ) ) { |
||
431 | $info['values'] = $i; |
||
432 | ApiResult::setIndexedTagName( $info['values'], 'v' ); |
||
433 | } |
||
434 | $this->formatHelpMessages( $info, 'text', [ |
||
435 | $this->context->msg( "apihelp-{$path}-paraminfo-{$tag}" ) |
||
436 | ->numParams( count( $i ) ) |
||
437 | ->params( $this->context->getLanguage()->commaList( $i ) ) |
||
438 | ->params( $module->getModulePrefix() ) |
||
439 | ] ); |
||
440 | ApiResult::setSubelementsList( $info, 'text' ); |
||
441 | $item['info'][] = $info; |
||
442 | } |
||
443 | ApiResult::setIndexedTagName( $item['info'], 'i' ); |
||
444 | } |
||
445 | |||
446 | $ret['parameters'][] = $item; |
||
447 | } |
||
448 | ApiResult::setIndexedTagName( $ret['parameters'], 'param' ); |
||
449 | |||
450 | $dynamicParams = $module->dynamicParameterDocumentation(); |
||
451 | if ( $dynamicParams !== null ) { |
||
452 | if ( $this->helpFormat === 'none' ) { |
||
453 | $ret['dynamicparameters'] = true; |
||
454 | } else { |
||
455 | $dynamicParams = ApiBase::makeMessage( $dynamicParams, $this->context, [ |
||
456 | $module->getModulePrefix(), |
||
457 | $module->getModuleName(), |
||
458 | $module->getModulePath() |
||
459 | ] ); |
||
460 | $this->formatHelpMessages( $ret, 'dynamicparameters', [ $dynamicParams ] ); |
||
461 | } |
||
462 | } |
||
463 | |||
464 | return $ret; |
||
465 | } |
||
466 | |||
467 | public function isReadMode() { |
||
468 | return false; |
||
469 | } |
||
470 | |||
471 | public function getAllowedParams() { |
||
472 | // back compat |
||
473 | $querymodules = $this->getMain()->getModuleManager() |
||
474 | ->getModule( 'query' )->getModuleManager()->getNames(); |
||
475 | sort( $querymodules ); |
||
476 | $formatmodules = $this->getMain()->getModuleManager()->getNames( 'format' ); |
||
477 | sort( $formatmodules ); |
||
478 | |||
479 | return [ |
||
480 | 'modules' => [ |
||
481 | ApiBase::PARAM_ISMULTI => true, |
||
482 | ], |
||
483 | 'helpformat' => [ |
||
484 | ApiBase::PARAM_DFLT => 'none', |
||
485 | ApiBase::PARAM_TYPE => [ 'html', 'wikitext', 'raw', 'none' ], |
||
486 | ], |
||
487 | |||
488 | 'querymodules' => [ |
||
489 | ApiBase::PARAM_DEPRECATED => true, |
||
490 | ApiBase::PARAM_ISMULTI => true, |
||
491 | ApiBase::PARAM_TYPE => $querymodules, |
||
492 | ], |
||
493 | 'mainmodule' => [ |
||
494 | ApiBase::PARAM_DEPRECATED => true, |
||
495 | ], |
||
496 | 'pagesetmodule' => [ |
||
497 | ApiBase::PARAM_DEPRECATED => true, |
||
498 | ], |
||
499 | 'formatmodules' => [ |
||
500 | ApiBase::PARAM_DEPRECATED => true, |
||
501 | ApiBase::PARAM_ISMULTI => true, |
||
502 | ApiBase::PARAM_TYPE => $formatmodules, |
||
503 | ] |
||
504 | ]; |
||
505 | } |
||
506 | |||
507 | protected function getExamplesMessages() { |
||
508 | return [ |
||
509 | 'action=paraminfo&modules=parse|phpfm|query%2Ballpages|query%2Bsiteinfo' |
||
510 | => 'apihelp-paraminfo-example-1', |
||
511 | 'action=paraminfo&modules=query%2B*' |
||
512 | => 'apihelp-paraminfo-example-2', |
||
513 | ]; |
||
514 | } |
||
515 | |||
516 | public function getHelpUrls() { |
||
517 | return 'https://www.mediawiki.org/wiki/API:Parameter_information'; |
||
518 | } |
||
519 | } |
||
520 |