244 array $options, &$haveModules
248 $level = empty( $options[
'headerlevel'] ) ? 2 : $options[
'headerlevel'];
249 if ( empty( $options[
'tocnumber'] ) ) {
250 $tocnumber = [ 2 => 0 ];
252 $tocnumber = &$options[
'tocnumber'];
256 $paramValidator = $module->getMain()->getParamValidator();
257 $tocnumber[$level]++;
258 $path = $module->getModulePath();
270 if ( empty( $options[
'noheader'] ) || !empty( $options[
'toc'] ) ) {
273 while ( isset( $haveModules[$anchor] ) ) {
274 $anchor =
$path .
'|' . ++$i;
277 if ( $module->isMain() ) {
278 $headerContent =
$context->
msg(
'api-help-main-header' )->parse();
280 'class' =>
'apihelp-header',
283 $name = $module->getModuleName();
284 $headerContent = htmlspecialchars(
285 $module->getParent()->getModuleManager()->getModuleGroup( $name ) .
"=$name"
287 if ( $module->getModulePrefix() !==
'' ) {
288 $headerContent .=
' ' .
289 $context->
msg(
'parentheses', $module->getModulePrefix() )->parse();
295 'class' =>
'apihelp-header apihelp-module-name',
301 $headerAttr[
'id'] = $anchor;
303 $haveModules[$anchor] = [
304 'toclevel' => count( $tocnumber ),
307 'line' => $headerContent,
308 'number' => implode(
'.', $tocnumber ),
311 if ( empty( $options[
'noheader'] ) ) {
312 $help[
'header'] .= Html::rawElement(
313 'h' . min( 6, $level ),
319 $haveModules[
$path] =
true;
324 for ( $m = $module; $m !==
null; $m = $m->getParent() ) {
325 $name = $m->getModuleName();
326 if ( $name ===
'main_int' ) {
331 !( !empty( $options[
'submodules'] ) && $m->getModuleManager() )
333 $link = Html::element(
'b', [
'dir' =>
'ltr',
'lang' =>
'en' ], $name );
336 $link = Html::element(
'a',
337 [
'href' => $link,
'class' =>
'apihelp-linktrail',
'dir' =>
'ltr',
'lang' =>
'en' ],
342 array_unshift( $links, $link );
348 'apihelp-linktrail',
'div'
352 $flags = $module->getHelpFlags();
353 $help[
'flags'] .= Html::openElement(
'div',
354 [
'class' =>
'apihelp-block apihelp-flags' ] );
356 if ( !$msg->isDisabled() ) {
358 $msg->numParams( count( $flags ) ),
'apihelp-block-head',
'div'
361 $help[
'flags'] .= Html::openElement(
'ul' );
362 foreach ( $flags as $flag ) {
363 $help[
'flags'] .= Html::rawElement(
'li',
null,
364 self::wrap(
$context->
msg(
"api-help-flag-$flag" ),
"apihelp-flag-$flag" )
367 $sourceInfo = $module->getModuleSourceInfo();
369 if ( isset( $sourceInfo[
'namemsg'] ) ) {
370 $extname =
$context->
msg( $sourceInfo[
'namemsg'] )->text();
373 $extname = Html::element(
'span', [
'dir' =>
'ltr',
'lang' =>
'en' ], $sourceInfo[
'name'] );
375 $help[
'flags'] .= Html::rawElement(
'li',
null,
377 $context->
msg(
'api-help-source', $extname, $sourceInfo[
'name'] ),
383 if ( isset( $sourceInfo[
'license-name'] ) ) {
385 Html::element(
'span', [
'dir' =>
'ltr',
'lang' =>
'en' ], $sourceInfo[
'license-name'] )
387 } elseif ( ExtensionInfo::getLicenseFileNames( dirname( $sourceInfo[
'path'] ) ) ) {
388 $msg =
$context->
msg(
'api-help-license-noname', $link );
390 $msg =
$context->
msg(
'api-help-license-unknown' );
392 $help[
'flags'] .= Html::rawElement(
'li',
null,
393 self::wrap( $msg,
'apihelp-license' )
396 $help[
'flags'] .= Html::rawElement(
'li',
null,
397 self::wrap(
$context->
msg(
'api-help-source-unknown' ),
'apihelp-source' )
399 $help[
'flags'] .= Html::rawElement(
'li',
null,
400 self::wrap(
$context->
msg(
'api-help-license-unknown' ),
'apihelp-license' )
403 $help[
'flags'] .= Html::closeElement(
'ul' );
404 $help[
'flags'] .= Html::closeElement(
'div' );
406 foreach ( $module->getFinalDescription() as $msg ) {
408 $help[
'description'] .= $msg->parseAsBlock();
411 $urls = $module->getHelpUrls();
413 if ( !is_array( $urls ) ) {
416 $help[
'help-urls'] .= Html::openElement(
'div',
417 [
'class' =>
'apihelp-block apihelp-help-urls' ]
420 if ( !$msg->isDisabled() ) {
422 $msg->numParams( count( $urls ) ),
'apihelp-block-head',
'div'
425 $help[
'help-urls'] .= Html::openElement(
'ul' );
426 foreach ( $urls as $url ) {
427 $help[
'help-urls'] .= Html::rawElement(
'li',
null,
428 Html::element(
'a', [
'href' => $url,
'dir' =>
'ltr' ], $url )
431 $help[
'help-urls'] .= Html::closeElement(
'ul' );
432 $help[
'help-urls'] .= Html::closeElement(
'div' );
436 $dynamicParams = $module->dynamicParameterDocumentation();
438 if ( $params || $dynamicParams !==
null ) {
439 $help[
'parameters'] .= Html::openElement(
'div',
440 [
'class' =>
'apihelp-block apihelp-parameters' ]
443 if ( !$msg->isDisabled() ) {
445 $msg->numParams( count( $params ) ),
'apihelp-block-head',
'div'
448 $help[
'parameters'] .= Html::openElement(
'dl' );
450 $descriptions = $module->getFinalParamDescription();
452 foreach ( $params as $name => $settings ) {
453 $settings = $paramValidator->normalizeSettings( $settings );
459 $help[
'parameters'] .= Html::rawElement(
'dt',
null,
460 Html::element(
'span', [
'dir' =>
'ltr',
'lang' =>
'en' ], $module->encodeParamName( $name ) )
465 if ( isset( $descriptions[$name] ) ) {
466 foreach ( $descriptions[$name] as $msg ) {
468 $description[] = $msg->parseAsBlock();
471 if ( !array_filter( $description ) ) {
480 $help[
'parameters'] .= Html::openElement(
'dd',
481 [
'class' =>
'info' ] );
484 'apihelp-deprecated',
'strong'
486 $help[
'parameters'] .= Html::closeElement(
'dd' );
489 if ( $description ) {
490 $description = implode(
'', $description );
491 $description = preg_replace(
'!\s*</([oud]l)>\s*<\1>\s*!',
"\n", $description );
492 $help[
'parameters'] .= Html::rawElement(
'dd',
493 [
'class' =>
'description' ], $description );
498 $paramHelp = $paramValidator->getHelpInfo( $module, $name, $settings, [] );
500 unset( $paramHelp[ParamValidator::PARAM_DEPRECATED] );
502 if ( isset( $paramHelp[ParamValidator::PARAM_REQUIRED] ) ) {
503 $paramHelp[ParamValidator::PARAM_REQUIRED]->setContext(
$context );
504 $info[] = $paramHelp[ParamValidator::PARAM_REQUIRED];
505 unset( $paramHelp[ParamValidator::PARAM_REQUIRED] );
511 $tag = array_shift( $i );
512 $info[] =
$context->
msg(
"apihelp-{$path}-paraminfo-{$tag}" )
513 ->numParams( count( $i ) )
515 ->params( $module->getModulePrefix() )
523 $msg =
'api-help-param-templated-var-first';
525 $vars[] =
$context->
msg( $msg, $k, $module->encodeParamName( $v ) );
526 $msg =
'api-help-param-templated-var';
528 $info[] =
$context->
msg(
'api-help-param-templated' )
529 ->numParams( count( $vars ) )
535 foreach ( $paramHelp as $m ) {
540 foreach ( $info as $i ) {
541 $help[
'parameters'] .= Html::rawElement(
'dd', [
'class' =>
'info' ], $i );
545 if ( $dynamicParams !==
null ) {
547 $module->getModulePrefix(),
548 $module->getModuleName(),
549 $module->getModulePath()
551 $help[
'parameters'] .= Html::element(
'dt',
null,
'*' );
552 $help[
'parameters'] .= Html::rawElement(
'dd',
553 [
'class' =>
'description' ], $dynamicParams->parse() );
556 $help[
'parameters'] .= Html::closeElement(
'dl' );
557 $help[
'parameters'] .= Html::closeElement(
'div' );
560 $examples = $module->getExamplesMessages();
562 $help[
'examples'] .= Html::openElement(
'div',
563 [
'class' =>
'apihelp-block apihelp-examples' ] );
565 if ( !$msg->isDisabled() ) {
567 $msg->numParams( count( $examples ) ),
'apihelp-block-head',
'div'
571 $help[
'examples'] .= Html::openElement(
'dl' );
572 foreach ( $examples as $qs => $msg ) {
574 $module->getModulePrefix(),
575 $module->getModuleName(),
576 $module->getModulePath()
581 $help[
'examples'] .= Html::rawElement(
'dt',
null, $msg->parse() );
582 $help[
'examples'] .= Html::rawElement(
'dd',
null,
583 Html::element(
'a', [
'href' => $link,
'dir' =>
'ltr' ],
"api.php?$qs" ) .
' ' .
584 Html::rawElement(
'a', [
'href' => $sandbox ],
585 $context->
msg(
'api-help-open-in-apisandbox' )->parse() )
588 $help[
'examples'] .= Html::closeElement(
'dl' );
589 $help[
'examples'] .= Html::closeElement(
'div' );
592 $subtocnumber = $tocnumber;
593 $subtocnumber[$level + 1] = 0;
595 'submodules' => $options[
'recursivesubmodules'],
596 'headerlevel' => $level + 1,
597 'tocnumber' => &$subtocnumber,
601 if ( $options[
'submodules'] && $module->getModuleManager() ) {
602 $manager = $module->getModuleManager();
604 foreach ( $groups as $group ) {
605 $names = $manager->getNames( $group );
607 foreach ( $names as $name ) {
608 $submodules[] = $manager->getModule( $name );
619 $module->modifyHelp(
$help, $suboptions, $haveModules );
621 $module->getHookRunner()->onAPIHelpModifyOutput( $module,
$help,
622 $suboptions, $haveModules );
624 $out .= implode(
"\n",
$help );