MediaWiki REL1_37
ApiParamInfo.php
Go to the documentation of this file.
1<?php
25
29class ApiParamInfo extends ApiBase {
30
31 private $helpFormat;
32
34 private $context;
35
37 private $userFactory;
38
44 public function __construct(
45 ApiMain $main,
46 $action,
48 ) {
49 parent::__construct( $main, $action );
50 $this->userFactory = $userFactory;
51 }
52
53 public function execute() {
54 // Get parameters
55 $params = $this->extractRequestParams();
56
57 $this->helpFormat = $params['helpformat'];
58 $this->context = new RequestContext;
59 $this->context->setUser( $this->userFactory->newAnonymous() ); // anon to avoid caching issues
60 $this->context->setLanguage( $this->getMain()->getLanguage() );
61
62 if ( is_array( $params['modules'] ) ) {
63 $modules = [];
64 foreach ( $params['modules'] as $path ) {
65 if ( $path === '*' || $path === '**' ) {
66 $path = "main+$path";
67 }
68 if ( substr( $path, -2 ) === '+*' || substr( $path, -2 ) === ' *' ) {
69 $submodules = true;
70 $path = substr( $path, 0, -2 );
71 $recursive = false;
72 } elseif ( substr( $path, -3 ) === '+**' || substr( $path, -3 ) === ' **' ) {
73 $submodules = true;
74 $path = substr( $path, 0, -3 );
75 $recursive = true;
76 } else {
77 $submodules = false;
78 }
79
80 if ( $submodules ) {
81 try {
82 $module = $this->getModuleFromPath( $path );
83 } catch ( ApiUsageException $ex ) {
84 foreach ( $ex->getStatusValue()->getErrors() as $error ) {
85 $this->addWarning( $error );
86 }
87 continue;
88 }
89 $submodules = $this->listAllSubmodules( $module, $recursive );
90 if ( $submodules ) {
91 $modules = array_merge( $modules, $submodules );
92 } else {
93 $this->addWarning( [ 'apierror-badmodule-nosubmodules', $path ], 'badmodule' );
94 }
95 } else {
96 $modules[] = $path;
97 }
98 }
99 } else {
100 $modules = [];
101 }
102
103 if ( is_array( $params['querymodules'] ) ) {
104 $queryModules = $params['querymodules'];
105 foreach ( $queryModules as $m ) {
106 $modules[] = 'query+' . $m;
107 }
108 } else {
109 $queryModules = [];
110 }
111
112 if ( is_array( $params['formatmodules'] ) ) {
113 $formatModules = $params['formatmodules'];
114 foreach ( $formatModules as $m ) {
115 $modules[] = $m;
116 }
117 } else {
118 $formatModules = [];
119 }
120
121 $modules = array_unique( $modules );
122
123 $res = [];
124
125 foreach ( $modules as $m ) {
126 try {
127 $module = $this->getModuleFromPath( $m );
128 } catch ( ApiUsageException $ex ) {
129 foreach ( $ex->getStatusValue()->getErrors() as $error ) {
130 $this->addWarning( $error );
131 }
132 continue;
133 }
134 $key = 'modules';
135
136 // Back compat
137 $isBCQuery = false;
138 if ( $module->getParent() && $module->getParent()->getModuleName() == 'query' &&
139 in_array( $module->getModuleName(), $queryModules )
140 ) {
141 $isBCQuery = true;
142 $key = 'querymodules';
143 }
144 if ( in_array( $module->getModuleName(), $formatModules ) ) {
145 $key = 'formatmodules';
146 }
147
148 $item = $this->getModuleInfo( $module );
149 if ( $isBCQuery ) {
150 $item['querytype'] = $item['group'];
151 }
152 $res[$key][] = $item;
153 }
154
155 $result = $this->getResult();
156 $result->addValue( [ $this->getModuleName() ], 'helpformat', $this->helpFormat );
157
158 foreach ( $res as $key => $stuff ) {
159 ApiResult::setIndexedTagName( $res[$key], 'module' );
160 }
161
162 if ( $params['mainmodule'] ) {
163 $res['mainmodule'] = $this->getModuleInfo( $this->getMain() );
164 }
165
166 if ( $params['pagesetmodule'] ) {
167 $pageSet = new ApiPageSet( $this->getMain()->getModuleManager()->getModule( 'query' ) );
168 $res['pagesetmodule'] = $this->getModuleInfo( $pageSet );
169 unset( $res['pagesetmodule']['name'] );
170 unset( $res['pagesetmodule']['path'] );
171 unset( $res['pagesetmodule']['group'] );
172 }
173
174 $result->addValue( null, $this->getModuleName(), $res );
175 }
176
183 private function listAllSubmodules( ApiBase $module, $recursive ) {
184 $paths = [];
185 $manager = $module->getModuleManager();
186 if ( $manager ) {
187 $names = $manager->getNames();
188 sort( $names );
189 foreach ( $names as $name ) {
190 $submodule = $manager->getModule( $name );
191 $paths[] = $submodule->getModulePath();
192 if ( $recursive && $submodule->getModuleManager() ) {
193 $paths = array_merge( $paths, $this->listAllSubmodules( $submodule, $recursive ) );
194 }
195 }
196 }
197 return $paths;
198 }
199
206 protected function formatHelpMessages( array &$res, $key, array $msgs, $joinLists = false ) {
207 switch ( $this->helpFormat ) {
208 case 'none':
209 break;
210
211 case 'wikitext':
212 $ret = [];
213 foreach ( $msgs as $m ) {
214 $ret[] = $m->setContext( $this->context )->text();
215 }
216 $res[$key] = implode( "\n\n", $ret );
217 if ( $joinLists ) {
218 $res[$key] = preg_replace( '!^(([*#:;])[^\n]*)\n\n(?=\2)!m', "$1\n", $res[$key] );
219 }
220 break;
221
222 case 'html':
223 $ret = [];
224 foreach ( $msgs as $m ) {
225 $ret[] = $m->setContext( $this->context )->parseAsBlock();
226 }
227 $ret = implode( "\n", $ret );
228 if ( $joinLists ) {
229 $ret = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $ret );
230 }
231 $res[$key] = Parser::stripOuterParagraph( $ret );
232 break;
233
234 case 'raw':
235 $res[$key] = [];
236 foreach ( $msgs as $m ) {
237 $a = [
238 'key' => $m->getKey(),
239 'params' => $m->getParams(),
240 ];
241 ApiResult::setIndexedTagName( $a['params'], 'param' );
242 if ( $m instanceof ApiHelpParamValueMessage ) {
243 $a['forvalue'] = $m->getParamValue();
244 }
245 $res[$key][] = $a;
246 }
247 ApiResult::setIndexedTagName( $res[$key], 'msg' );
248 break;
249 }
250 }
251
256 private function getModuleInfo( $module ) {
257 $ret = [];
258 $path = $module->getModulePath();
259 $paramValidator = $module->getMain()->getParamValidator();
260
261 $ret['name'] = $module->getModuleName();
262 $ret['classname'] = get_class( $module );
263 $ret['path'] = $path;
264 if ( !$module->isMain() ) {
265 $ret['group'] = $module->getParent()->getModuleManager()->getModuleGroup(
266 $module->getModuleName()
267 );
268 }
269 $ret['prefix'] = $module->getModulePrefix();
270
271 $sourceInfo = $module->getModuleSourceInfo();
272 if ( $sourceInfo ) {
273 $ret['source'] = $sourceInfo['name'];
274 if ( isset( $sourceInfo['namemsg'] ) ) {
275 $ret['sourcename'] = $this->context->msg( $sourceInfo['namemsg'] )->text();
276 } else {
277 $ret['sourcename'] = $ret['source'];
278 }
279
280 $link = SpecialPage::getTitleFor( 'Version', 'License/' . $sourceInfo['name'] )->getFullURL();
281 if ( isset( $sourceInfo['license-name'] ) ) {
282 $ret['licensetag'] = $sourceInfo['license-name'];
283 $ret['licenselink'] = (string)$link;
284 } elseif ( ExtensionInfo::getLicenseFileNames( dirname( $sourceInfo['path'] ) ) ) {
285 $ret['licenselink'] = (string)$link;
286 }
287 }
288
289 $this->formatHelpMessages( $ret, 'description', $module->getFinalDescription() );
290
291 foreach ( $module->getHelpFlags() as $flag ) {
292 $ret[$flag] = true;
293 }
294
295 $ret['helpurls'] = (array)$module->getHelpUrls();
296 if ( isset( $ret['helpurls'][0] ) && $ret['helpurls'][0] === false ) {
297 $ret['helpurls'] = [];
298 }
299 ApiResult::setIndexedTagName( $ret['helpurls'], 'helpurl' );
300
301 if ( $this->helpFormat !== 'none' ) {
302 $ret['examples'] = [];
303 $examples = $module->getExamplesMessages();
304 foreach ( $examples as $qs => $msg ) {
305 $item = [
306 'query' => $qs
307 ];
308 $msg = ApiBase::makeMessage( $msg, $this->context, [
309 $module->getModulePrefix(),
310 $module->getModuleName(),
311 $module->getModulePath()
312 ] );
313 $this->formatHelpMessages( $item, 'description', [ $msg ] );
314 if ( isset( $item['description'] ) ) {
315 if ( is_array( $item['description'] ) ) {
316 $item['description'] = $item['description'][0];
317 } else {
318 ApiResult::setSubelementsList( $item, 'description' );
319 }
320 }
321 $ret['examples'][] = $item;
322 }
323 ApiResult::setIndexedTagName( $ret['examples'], 'example' );
324 }
325
326 $ret['parameters'] = [];
327 $ret['templatedparameters'] = [];
328 $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
329 $paramDesc = $module->getFinalParamDescription();
330 $index = 0;
331 foreach ( $params as $name => $settings ) {
332 $settings = $paramValidator->normalizeSettings( $settings );
333
334 $item = [
335 'index' => ++$index,
336 'name' => $name,
337 ];
338
339 if ( !empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
340 $item['templatevars'] = $settings[ApiBase::PARAM_TEMPLATE_VARS];
341 ApiResult::setIndexedTagName( $item['templatevars'], 'var' );
342 }
343
344 if ( isset( $paramDesc[$name] ) ) {
345 $this->formatHelpMessages( $item, 'description', $paramDesc[$name], true );
346 }
347
348 foreach ( $paramValidator->getParamInfo( $module, $name, $settings, [] ) as $k => $v ) {
349 $item[$k] = $v;
350 }
351
352 if ( $name === 'token' && $module->needsToken() ) {
353 $item['tokentype'] = $module->needsToken();
354 }
355
356 if ( $item['type'] === 'NULL' ) {
357 // Munge "NULL" to "string" for historical reasons
358 $item['type'] = 'string';
359 } elseif ( is_array( $item['type'] ) ) {
360 // Set indexed tag name, for historical reasons
361 ApiResult::setIndexedTagName( $item['type'], 't' );
362 }
363
364 if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) {
365 $item['info'] = [];
366 foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) {
367 $tag = array_shift( $i );
368 $info = [
369 'name' => $tag,
370 ];
371 if ( count( $i ) ) {
372 $info['values'] = $i;
373 ApiResult::setIndexedTagName( $info['values'], 'v' );
374 }
375 $this->formatHelpMessages( $info, 'text', [
376 $this->context->msg( "apihelp-{$path}-paraminfo-{$tag}" )
377 ->numParams( count( $i ) )
378 ->params( $this->context->getLanguage()->commaList( $i ) )
379 ->params( $module->getModulePrefix() )
380 ] );
381 ApiResult::setSubelementsList( $info, 'text' );
382 $item['info'][] = $info;
383 }
384 ApiResult::setIndexedTagName( $item['info'], 'i' );
385 }
386
387 $key = empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ? 'parameters' : 'templatedparameters';
388 $ret[$key][] = $item;
389 }
390 ApiResult::setIndexedTagName( $ret['parameters'], 'param' );
391 ApiResult::setIndexedTagName( $ret['templatedparameters'], 'param' );
392
393 $dynamicParams = $module->dynamicParameterDocumentation();
394 if ( $dynamicParams !== null ) {
395 if ( $this->helpFormat === 'none' ) {
396 $ret['dynamicparameters'] = true;
397 } else {
398 $dynamicParams = ApiBase::makeMessage( $dynamicParams, $this->context, [
399 $module->getModulePrefix(),
400 $module->getModuleName(),
401 $module->getModulePath()
402 ] );
403 $this->formatHelpMessages( $ret, 'dynamicparameters', [ $dynamicParams ] );
404 }
405 }
406
407 return $ret;
408 }
409
410 public function isReadMode() {
411 return false;
412 }
413
414 public function getAllowedParams() {
415 // back compat
416 $querymodules = $this->getMain()->getModuleManager()
417 ->getModule( 'query' )->getModuleManager()->getNames();
418 sort( $querymodules );
419 $formatmodules = $this->getMain()->getModuleManager()->getNames( 'format' );
420 sort( $formatmodules );
421
422 return [
423 'modules' => [
425 ],
426 'helpformat' => [
427 ApiBase::PARAM_DFLT => 'none',
428 ApiBase::PARAM_TYPE => [ 'html', 'wikitext', 'raw', 'none' ],
429 ],
430
431 'querymodules' => [
434 ApiBase::PARAM_TYPE => $querymodules,
435 ],
436 'mainmodule' => [
438 ],
439 'pagesetmodule' => [
441 ],
442 'formatmodules' => [
445 ApiBase::PARAM_TYPE => $formatmodules,
446 ]
447 ];
448 }
449
450 protected function getExamplesMessages() {
451 return [
452 'action=paraminfo&modules=parse|phpfm|query%2Ballpages|query%2Bsiteinfo'
453 => 'apihelp-paraminfo-example-1',
454 'action=paraminfo&modules=query%2B*'
455 => 'apihelp-paraminfo-example-2',
456 ];
457 }
458
459 public function getHelpUrls() {
460 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parameter_information';
461 }
462}
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:55
const PARAM_DEPRECATED
Definition ApiBase.php:101
getModuleFromPath( $path)
Get a module from its module path.
Definition ApiBase.php:590
static makeMessage( $msg, IContextSource $context, array $params=null)
Create a Message from a string or array.
Definition ApiBase.php:1216
getModuleManager()
Get the module manager, or null if this module has no sub-modules.
Definition ApiBase.php:306
getMain()
Get the main module.
Definition ApiBase.php:513
const PARAM_TYPE
Definition ApiBase.php:81
const PARAM_HELP_MSG_INFO
(array) Specify additional information tags for the parameter.
Definition ApiBase.php:179
const PARAM_DFLT
Definition ApiBase.php:73
const PARAM_TEMPLATE_VARS
(array) Indicate that this is a templated parameter, and specify replacements.
Definition ApiBase.php:213
getResult()
Get the result object.
Definition ApiBase.php:628
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:764
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1354
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
Definition ApiBase.php:233
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:497
const PARAM_ISMULTI
Definition ApiBase.php:77
Message subclass that prepends wikitext for API help.
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:49
This class contains a list of pages that the client has requested.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
UserFactory $userFactory
RequestContext $context
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
isReadMode()
Indicates whether this module requires read rights.
getHelpUrls()
Return links to more detailed help pages about the module.
__construct(ApiMain $main, $action, UserFactory $userFactory)
formatHelpMessages(array &$res, $key, array $msgs, $joinLists=false)
listAllSubmodules(ApiBase $module, $recursive)
List all submodules of a module.
getExamplesMessages()
Returns usage examples for this module.
getModuleInfo( $module)
Exception used to abort API execution with an error.
getStatusValue()
Fetch the error status.
Creates User objects.
static stripOuterParagraph( $html)
Strip outer.
Definition Parser.php:6336
Group all the pieces relevant to the context of a request into one instance @newable.
setUser(User $user)
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...