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 $tocnumber[$level]++;
257 $path = $module->getModulePath();
269 if ( empty( $options[
'noheader'] ) || !empty( $options[
'toc'] ) ) {
272 while ( isset( $haveModules[$anchor] ) ) {
273 $anchor =
$path .
'|' . ++$i;
276 if ( $module->isMain() ) {
277 $headerContent =
$context->
msg(
'api-help-main-header' )->parse();
279 'class' =>
'apihelp-header',
282 $name = $module->getModuleName();
283 $headerContent = $module->getParent()->getModuleManager()->getModuleGroup( $name ) .
285 if ( $module->getModulePrefix() !==
'' ) {
286 $headerContent .=
' ' .
287 $context->
msg(
'parentheses', $module->getModulePrefix() )->parse();
293 'class' =>
'apihelp-header apihelp-module-name',
299 $headerAttr[
'id'] = $anchor;
301 $haveModules[$anchor] = [
302 'toclevel' => count( $tocnumber ),
305 'line' => $headerContent,
306 'number' => implode(
'.', $tocnumber ),
309 if ( empty( $options[
'noheader'] ) ) {
310 $help[
'header'] .= Html::element(
311 'h' . min( 6, $level ),
317 $haveModules[
$path] =
true;
322 for ( $m = $module; $m !==
null; $m = $m->getParent() ) {
323 $name = $m->getModuleName();
324 if ( $name ===
'main_int' ) {
329 !( !empty( $options[
'submodules'] ) && $m->getModuleManager() )
331 $link = Html::element(
'b', [
'dir' =>
'ltr',
'lang' =>
'en' ], $name );
333 $link = SpecialPage::getTitleFor(
'ApiHelp', $m->getModulePath() )->getLocalURL();
334 $link = Html::element(
'a',
335 [
'href' => $link,
'class' =>
'apihelp-linktrail',
'dir' =>
'ltr',
'lang' =>
'en' ],
340 array_unshift( $links, $link );
346 'apihelp-linktrail',
'div'
350 $flags = $module->getHelpFlags();
351 $help[
'flags'] .= Html::openElement(
'div',
352 [
'class' =>
'apihelp-block apihelp-flags' ] );
354 if ( !$msg->isDisabled() ) {
356 $msg->numParams( count( $flags ) ),
'apihelp-block-head',
'div'
359 $help[
'flags'] .= Html::openElement(
'ul' );
360 foreach ( $flags as $flag ) {
361 $help[
'flags'] .= Html::rawElement(
'li',
null,
362 self::wrap(
$context->
msg(
"api-help-flag-$flag" ),
"apihelp-flag-$flag" )
365 $sourceInfo = $module->getModuleSourceInfo();
367 if ( isset( $sourceInfo[
'namemsg'] ) ) {
368 $extname =
$context->
msg( $sourceInfo[
'namemsg'] )->text();
371 $extname = Html::element(
'span', [
'dir' =>
'ltr',
'lang' =>
'en' ], $sourceInfo[
'name'] );
373 $help[
'flags'] .= Html::rawElement(
'li',
null,
375 $context->
msg(
'api-help-source', $extname, $sourceInfo[
'name'] ),
380 $link = SpecialPage::getTitleFor(
'Version',
'License/' . $sourceInfo[
'name'] );
381 if ( isset( $sourceInfo[
'license-name'] ) ) {
383 Html::element(
'span', [
'dir' =>
'ltr',
'lang' =>
'en' ], $sourceInfo[
'license-name'] )
386 $msg =
$context->
msg(
'api-help-license-noname', $link );
388 $msg =
$context->
msg(
'api-help-license-unknown' );
390 $help[
'flags'] .= Html::rawElement(
'li',
null,
391 self::wrap( $msg,
'apihelp-license' )
394 $help[
'flags'] .= Html::rawElement(
'li',
null,
395 self::wrap(
$context->
msg(
'api-help-source-unknown' ),
'apihelp-source' )
397 $help[
'flags'] .= Html::rawElement(
'li',
null,
398 self::wrap(
$context->
msg(
'api-help-license-unknown' ),
'apihelp-license' )
401 $help[
'flags'] .= Html::closeElement(
'ul' );
402 $help[
'flags'] .= Html::closeElement(
'div' );
404 foreach ( $module->getFinalDescription() as $msg ) {
406 $help[
'description'] .= $msg->parseAsBlock();
409 $urls = $module->getHelpUrls();
411 $help[
'help-urls'] .= Html::openElement(
'div',
412 [
'class' =>
'apihelp-block apihelp-help-urls' ]
415 if ( !$msg->isDisabled() ) {
417 $msg->numParams( count(
$urls ) ),
'apihelp-block-head',
'div'
420 if ( !is_array(
$urls ) ) {
423 $help[
'help-urls'] .= Html::openElement(
'ul' );
424 foreach (
$urls as $url ) {
425 $help[
'help-urls'] .= Html::rawElement(
'li',
null,
426 Html::element(
'a', [
'href' => $url,
'dir' =>
'ltr' ], $url )
429 $help[
'help-urls'] .= Html::closeElement(
'ul' );
430 $help[
'help-urls'] .= Html::closeElement(
'div' );
434 $dynamicParams = $module->dynamicParameterDocumentation();
436 if ( $params || $dynamicParams !==
null ) {
437 $help[
'parameters'] .= Html::openElement(
'div',
438 [
'class' =>
'apihelp-block apihelp-parameters' ]
441 if ( !$msg->isDisabled() ) {
443 $msg->numParams( count( $params ) ),
'apihelp-block-head',
'div'
446 $help[
'parameters'] .= Html::openElement(
'dl' );
448 $descriptions = $module->getFinalParamDescription();
450 foreach ( $params as $name => $settings ) {
451 if ( !is_array( $settings ) ) {
455 $help[
'parameters'] .= Html::rawElement(
'dt',
null,
456 Html::element(
'span', [
'dir' =>
'ltr',
'lang' =>
'en' ], $module->encodeParamName( $name ) )
461 if ( isset( $descriptions[$name] ) ) {
462 foreach ( $descriptions[$name] as $msg ) {
464 $description[] = $msg->parseAsBlock();
473 $info[] =
$context->
msg(
'api-help-param-required' )->parse();
479 $tag = array_shift( $i );
480 $info[] =
$context->
msg(
"apihelp-{$path}-paraminfo-{$tag}" )
481 ->numParams( count( $i ) )
483 ->params( $module->getModulePrefix() )
491 $msg =
'api-help-param-templated-var-first';
493 $vars[] =
$context->
msg( $msg, $k, $module->encodeParamName( $v ) );
494 $msg =
'api-help-param-templated-var';
496 $info[] =
$context->
msg(
'api-help-param-templated' )
497 ->numParams( count( $vars ) )
505 if ( is_bool( $dflt ) ) {
507 } elseif ( is_string( $dflt ) || is_null( $dflt ) ) {
509 } elseif ( is_int( $dflt ) ) {
516 $hintPipeSeparated =
true;
521 if ( is_array(
$type ) ) {
522 $count = count(
$type );
525 $values = array_map(
function ( $v ) use ( $links, $deprecatedValues ) {
529 $attr[
'dir'] =
'auto';
531 if ( isset( $deprecatedValues[$v] ) ) {
532 $attr[
'class'] =
'apihelp-deprecated-value';
534 $ret = $attr ? Html::element(
'span', $attr, $v ) : $v;
535 if ( isset( $links[$v] ) ) {
536 $ret =
"[[{$links[$v]}|$ret]]";
540 $i = array_search(
'',
$type,
true );
541 if ( $i ===
false ) {
544 unset( $values[$i] );
545 $values =
$context->
msg(
'api-help-param-list-can-be-empty' )
546 ->numParams( count( $values ) )
551 ->params( $multi ? 2 : 1 )
554 $hintPipeSeparated =
false;
564 $prefix = $module->isMain() ?
'' : ( $module->getModulePath() .
'+' );
566 foreach ( $module->getModuleManager()->getNames( $name ) as $submoduleName ) {
567 $map[$submoduleName] = $prefix . $submoduleName;
569 $defaultAttrs = [
'dir' =>
'ltr',
'lang' =>
'en' ];
574 $deprecatedSubmodules = [];
575 foreach ( $map as $v => $m ) {
576 $attrs = $defaultAttrs;
579 $submod = $module->getModuleFromPath( $m );
580 if ( $submod && $submod->isDeprecated() ) {
581 $arr = &$deprecatedSubmodules;
582 $attrs[
'class'] =
'apihelp-deprecated-value';
588 $v = Html::element(
'span', $attrs, $v );
590 $arr[] =
"[[Special:ApiHelp/{$m}|{$v}]]";
592 $submodules = array_merge( $submodules, $deprecatedSubmodules );
593 $count = count( $submodules );
595 ->params( $multi ? 2 : 1 )
598 $hintPipeSeparated =
false;
604 $namespaces = MediaWikiServices::getInstance()->
605 getNamespaceInfo()->getValidNamespaces();
612 $count = count( $namespaces );
614 ->params( $multi ? 2 : 1 )
617 $hintPipeSeparated =
false;
624 $count = count( $tags );
626 ->params( $multi ? 2 : 1 )
629 $hintPipeSeparated =
false;
661 if ( $suffix !==
'' ) {
664 ->params( $multi ? 2 : 1 )
665 ->numParams( $min, $max )
689 if ( is_string(
$type ) ) {
690 $msg =
$context->
msg(
"api-help-param-type-$type" );
691 if ( !$msg->isDisabled() ) {
692 $info[] = $msg->params( $multi ? 2 : 1 )->parse();
705 if ( $hintPipeSeparated ) {
706 $extra[] =
$context->
msg(
'api-help-param-multi-separate' )->parse();
708 if ( $count > $lowcount ) {
709 if ( $lowcount === $highcount ) {
710 $msg =
$context->
msg(
'api-help-param-multi-max-simple' )
711 ->numParams( $lowcount );
714 ->numParams( $lowcount, $highcount );
716 $extra[] = $msg->parse();
719 $info[] = implode(
' ', $extra );
729 $info[] =
$context->
msg(
'api-help-param-multi-all' )
730 ->params( $allSpecifier )
736 if ( isset( $settings[self::PARAM_MAX_BYTES] ) ) {
737 $info[] =
$context->
msg(
'api-help-param-maxbytes' )
738 ->numParams( $settings[self::PARAM_MAX_BYTES] );
740 if ( isset( $settings[self::PARAM_MAX_CHARS] ) ) {
741 $info[] =
$context->
msg(
'api-help-param-maxchars' )
742 ->numParams( $settings[self::PARAM_MAX_CHARS] );
747 if ( $default ===
'' ) {
748 $info[] =
$context->
msg(
'api-help-param-default-empty' )
750 } elseif ( $default !==
null && $default !==
false ) {
752 $info[] =
$context->
msg(
'api-help-param-default' )
753 ->params( Html::element(
'span', [
'dir' =>
'auto' ], $default ) )
757 if ( !array_filter( $description ) ) {
766 $help[
'parameters'] .= Html::openElement(
'dd',
767 [
'class' =>
'info' ] );
770 'apihelp-deprecated',
'strong'
772 $help[
'parameters'] .= Html::closeElement(
'dd' );
775 if ( $description ) {
776 $description = implode(
'', $description );
777 $description = preg_replace(
'!\s*</([oud]l)>\s*<\1>\s*!',
"\n", $description );
778 $help[
'parameters'] .= Html::rawElement(
'dd',
779 [
'class' =>
'description' ], $description );
782 foreach ( $info as $i ) {
783 $help[
'parameters'] .= Html::rawElement(
'dd', [
'class' =>
'info' ], $i );
787 if ( $dynamicParams !==
null ) {
789 $module->getModulePrefix(),
790 $module->getModuleName(),
791 $module->getModulePath()
793 $help[
'parameters'] .= Html::element(
'dt',
null,
'*' );
794 $help[
'parameters'] .= Html::rawElement(
'dd',
795 [
'class' =>
'description' ], $dynamicParams->parse() );
798 $help[
'parameters'] .= Html::closeElement(
'dl' );
799 $help[
'parameters'] .= Html::closeElement(
'div' );
802 $examples = $module->getExamplesMessages();
804 $help[
'examples'] .= Html::openElement(
'div',
805 [
'class' =>
'apihelp-block apihelp-examples' ] );
807 if ( !$msg->isDisabled() ) {
809 $msg->numParams( count( $examples ) ),
'apihelp-block-head',
'div'
813 $help[
'examples'] .= Html::openElement(
'dl' );
814 foreach ( $examples as $qs => $msg ) {
816 $module->getModulePrefix(),
817 $module->getModuleName(),
818 $module->getModulePath()
822 $sandbox = SpecialPage::getTitleFor(
'ApiSandbox' )->getLocalURL() .
'#' . $qs;
823 $help[
'examples'] .= Html::rawElement(
'dt',
null, $msg->parse() );
824 $help[
'examples'] .= Html::rawElement(
'dd',
null,
825 Html::element(
'a', [
'href' => $link,
'dir' =>
'ltr' ],
"api.php?$qs" ) .
' ' .
826 Html::rawElement(
'a', [
'href' => $sandbox ],
827 $context->
msg(
'api-help-open-in-apisandbox' )->parse() )
830 $help[
'examples'] .= Html::closeElement(
'dl' );
831 $help[
'examples'] .= Html::closeElement(
'div' );
834 $subtocnumber = $tocnumber;
835 $subtocnumber[$level + 1] = 0;
837 'submodules' => $options[
'recursivesubmodules'],
838 'headerlevel' => $level + 1,
839 'tocnumber' => &$subtocnumber,
843 if ( $options[
'submodules'] && $module->getModuleManager() ) {
844 $manager = $module->getModuleManager();
846 foreach ( $groups as $group ) {
847 $names = $manager->getNames( $group );
849 foreach ( $names as $name ) {
850 $submodules[] = $manager->getModule( $name );
861 $module->modifyHelp(
$help, $suboptions, $haveModules );
863 Hooks::run(
'APIHelpModifyOutput', [ $module, &
$help, $suboptions, &$haveModules ] );
865 $out .= implode(
"\n",
$help );