MediaWiki master
ApiHelp.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
27use Wikimedia\Parsoid\Core\SectionMetadata;
28use Wikimedia\Parsoid\Core\TOCData;
29use Wikimedia\RemexHtml\Serializer\SerializerNode;
30
37class ApiHelp extends ApiBase {
38
39 public function __construct(
40 ApiMain $main,
41 string $action,
42 private readonly SkinFactory $skinFactory,
43 ) {
44 parent::__construct( $main, $action );
45 }
46
47 public function execute() {
48 $params = $this->extractRequestParams();
49 $modules = [];
50
51 foreach ( $params['modules'] as $path ) {
52 $modules[] = $this->getModuleFromPath( $path );
53 }
54
55 // Get the help
56 $context = new DerivativeContext( $this->getMain()->getContext() );
57 $context->setSkin( $this->skinFactory->makeSkin( 'apioutput' ) );
58 $context->setLanguage( $this->getMain()->getLanguage() );
59 $context->setTitle( SpecialPage::getTitleFor( 'ApiHelp' ) );
60 $out = new OutputPage( $context );
61 $out->setRobotPolicy( 'noindex,nofollow' );
62 $out->setCopyrightUrl( 'https://www.mediawiki.org/wiki/Special:MyLanguage/Copyright' );
63 $out->disallowUserJs();
64 $context->setOutput( $out );
65
66 self::getHelp( $context, $modules, $params );
67
68 // Grab the output from the skin
69 ob_start();
70 $context->getOutput()->output();
71 $html = ob_get_clean();
72
73 $result = $this->getResult();
74 if ( $params['wrap'] ) {
75 $data = [
76 'mime' => 'text/html',
77 'filename' => 'api-help.html',
78 'help' => $html,
79 ];
80 ApiResult::setSubelementsList( $data, 'help' );
81 $result->addValue( null, $this->getModuleName(), $data );
82 } else {
83 // Show any errors at the top of the HTML
84 $transform = [
85 'Types' => [ 'AssocAsObject' => true ],
86 'Strip' => 'all',
87 ];
88 $errors = array_filter( [
89 'errors' => $this->getResult()->getResultData( [ 'errors' ], $transform ),
90 'warnings' => $this->getResult()->getResultData( [ 'warnings' ], $transform ),
91 ] );
92 if ( $errors ) {
93 $json = FormatJson::encode( $errors, true, FormatJson::UTF8_OK );
94 // Escape any "--", some parsers might interpret that as end-of-comment.
95 // The above already escaped any "<" and ">".
96 $json = str_replace( '--', '-\u002D', $json );
97 $html = "<!-- API warnings and errors:\n$json\n-->\n$html";
98 }
99
100 $result->reset();
101 $result->addValue( null, 'text', $html, ApiResult::NO_SIZE_CHECK );
102 $result->addValue( null, 'mime', 'text/html', ApiResult::NO_SIZE_CHECK );
103 $result->addValue( null, 'filename', 'api-help.html', ApiResult::NO_SIZE_CHECK );
104 }
105 }
106
126 public static function getHelp( IContextSource $context, $modules, array $options ) {
127 if ( !is_array( $modules ) ) {
128 $modules = [ $modules ];
129 }
130
131 $out = $context->getOutput();
132 $out->addModuleStyles( [
133 'mediawiki.hlist',
134 'mediawiki.apipretty',
135 ] );
136 $out->setPageTitleMsg( $context->msg( 'api-help-title' ) );
137
138 $services = MediaWikiServices::getInstance();
139 $cache = $services->getMainWANObjectCache();
140 $cacheKey = null;
141 if ( count( $modules ) == 1 && $modules[0] instanceof ApiMain &&
142 $options['recursivesubmodules'] &&
143 $context->getLanguage()->equals( $services->getContentLanguage() )
144 ) {
145 $cacheHelpTimeout = $context->getConfig()->get( MainConfigNames::APICacheHelpTimeout );
146 if ( $cacheHelpTimeout > 0 ) {
147 // Get help text from cache if present
148 $cacheKey = $cache->makeKey( 'apihelp', $modules[0]->getModulePath(),
149 (int)!empty( $options['toc'] ),
150 str_replace( ' ', '_', SpecialVersion::getVersion( 'nodb' ) ) );
151 $cached = $cache->get( $cacheKey );
152 if ( $cached ) {
153 $out->addHTML( $cached );
154 return;
155 }
156 }
157 }
158 if ( $out->getHTML() !== '' ) {
159 // Don't save to cache, there's someone else's content in the page
160 // already
161 $cacheKey = null;
162 }
163
164 // If no parameters were passed (not even action=help), display the TOC.
165 // It's a special case for the landing page because it's much nicer with a TOC.
166 if ( !$context->getRequest()->getValues() ) {
167 $options['toc'] = true;
168 }
169 $options['recursivesubmodules'] = !empty( $options['recursivesubmodules'] );
170 $options['submodules'] = $options['recursivesubmodules'] || !empty( $options['submodules'] );
171 $haveModules = [];
172 $html = self::getHelpInternal( $context, $modules, $options, $haveModules );
173
174 if ( !empty( $options['toc'] ) && $haveModules ) {
175 $out->addTOCPlaceholder( new TOCData( ...array_values( $haveModules ) ) );
176 }
177
178 // Prepend lead
179 if ( empty( $options['nolead'] ) ) {
180 $msg = $context->msg( 'api-help-lead' );
181 if ( !$msg->isDisabled() ) {
182 $out->addHTML( $msg->parseAsBlock() );
183 }
184 }
185
186 $out->addHTML( $html );
187
188 $helptitle = $options['helptitle'] ?? null;
189 $html = self::fixHelpLinks( $out->getHTML(), $helptitle, $haveModules );
190 $out->clearHTML();
191 $out->addHTML( $html );
192
193 if ( $cacheKey !== null ) {
194 // @phan-suppress-next-line PhanPossiblyUndeclaredVariable $cacheHelpTimeout declared when $cacheKey is set
195 $cache->set( $cacheKey, $out->getHTML(), $cacheHelpTimeout );
196 }
197 }
198
207 public static function fixHelpLinks( $html, $helptitle = null, $localModules = [] ) {
209 $html,
210 static function ( SerializerNode $node ): bool {
211 return $node->name === 'a'
212 && isset( $node->attrs['href'] )
213 && !str_contains( $node->attrs['class'] ?? '', 'apihelp-linktrail' );
214 },
215 static function ( SerializerNode $node ) use ( $helptitle, $localModules ): SerializerNode {
216 $href = $node->attrs['href'];
217 // FIXME This can't be right to do this in a loop
218 do {
219 $old = $href;
220 $href = rawurldecode( $href );
221 } while ( $old !== $href );
222 if ( preg_match( '!Special:ApiHelp/([^&/|#]+)((?:#.*)?)!', $href, $m ) ) {
223 if ( isset( $localModules[$m[1]] ) ) {
224 $href = $m[2] === '' ? '#' . $m[1] : $m[2];
225 } elseif ( $helptitle !== null ) {
226 $href = Title::newFromText( str_replace( '$1', $m[1], $helptitle ) . $m[2] )
227 ->getFullURL();
228 } else {
229 $href = wfAppendQuery( wfScript( 'api' ), [
230 'action' => 'help',
231 'modules' => $m[1],
232 ] ) . $m[2];
233 }
234 $node->attrs['href'] = $href;
235 unset( $node->attrs['title'] );
236 }
237
238 return $node;
239 }
240 );
241 }
242
251 private static function wrap( Message $msg, $class, $tag = 'span' ) {
252 return Html::rawElement( $tag, [ 'class' => $class ],
253 $msg->parse()
254 );
255 }
256
266 private static function getHelpInternal( IContextSource $context, array $modules,
267 array $options, &$haveModules
268 ) {
269 $out = '';
270
271 $level = empty( $options['headerlevel'] ) ? 2 : $options['headerlevel'];
272 if ( empty( $options['tocnumber'] ) ) {
273 $tocnumber = [ 2 => 0 ];
274 } else {
275 $tocnumber = &$options['tocnumber'];
276 }
277
278 foreach ( $modules as $module ) {
279 $paramValidator = $module->getMain()->getParamValidator();
280 $tocnumber[$level]++;
281 $path = $module->getModulePath();
282 $module->setContext( $context );
283 $help = [
284 'header' => '',
285 'flags' => '',
286 'description' => '',
287 'help-urls' => '',
288 'parameters' => '',
289 'examples' => '',
290 'submodules' => '',
291 ];
292
293 if ( empty( $options['noheader'] ) || !empty( $options['toc'] ) ) {
294 $anchor = $path;
295 $i = 1;
296 while ( isset( $haveModules[$anchor] ) ) {
297 $anchor = $path . '|' . ++$i;
298 }
299
300 if ( $module->isMain() ) {
301 $headerContent = $context->msg( 'api-help-main-header' )->parse();
302 $headerAttr = [
303 'class' => 'apihelp-header',
304 ];
305 } else {
306 $name = $module->getModuleName();
307 $headerContent = htmlspecialchars(
308 $module->getParent()->getModuleManager()->getModuleGroup( $name ) . "=$name"
309 );
310 if ( $module->getModulePrefix() !== '' ) {
311 $headerContent .= ' ' .
312 $context->msg( 'parentheses', $module->getModulePrefix() )->parse();
313 }
314 // Module names are always in English and not localized,
315 // so English language and direction must be set explicitly,
316 // otherwise parentheses will get broken in RTL wikis
317 $headerAttr = [
318 'class' => [ 'apihelp-header', 'apihelp-module-name' ],
319 'dir' => 'ltr',
320 'lang' => 'en',
321 ];
322 }
323
324 $headerAttr['id'] = $anchor;
325
326 $haveModules[$anchor] = new SectionMetadata(
327 tocLevel: count( $tocnumber ),
328 hLevel: $level,
329 line: $headerContent,
330 number: implode( '.', $tocnumber ),
331 index: (string)( 1 + count( $haveModules ) ),
332 anchor: $anchor,
333 linkAnchor: Sanitizer::escapeIdForLink( $anchor ),
334 );
335 if ( empty( $options['noheader'] ) ) {
336 $help['header'] .= Html::rawElement(
337 'h' . min( 6, $level ),
338 $headerAttr,
339 $headerContent
340 );
341 }
342 } else {
343 $haveModules[$path] = true;
344 }
345
346 $links = [];
347 $any = false;
348 for ( $m = $module; $m !== null; $m = $m->getParent() ) {
349 $name = $m->getModuleName();
350 if ( $name === 'main_int' ) {
351 $name = 'main';
352 }
353
354 if ( count( $modules ) === 1 && $m === $modules[0] &&
355 !( !empty( $options['submodules'] ) && $m->getModuleManager() )
356 ) {
357 $link = Html::element( 'b', [ 'dir' => 'ltr', 'lang' => 'en' ], $name );
358 } else {
359 $link = SpecialPage::getTitleFor( 'ApiHelp', $m->getModulePath() )->getLocalURL();
360 $link = Html::element( 'a',
361 [ 'href' => $link, 'class' => 'apihelp-linktrail', 'dir' => 'ltr', 'lang' => 'en' ],
362 $name
363 );
364 $any = true;
365 }
366 array_unshift( $links, $link );
367 }
368 if ( $any ) {
369 $help['header'] .= self::wrap(
370 $context->msg( 'parentheses' )
371 ->rawParams( $context->getLanguage()->pipeList( $links ) ),
372 'apihelp-linktrail', 'div'
373 );
374 }
375
376 $flags = $module->getHelpFlags();
377 $help['flags'] .= Html::openElement( 'div',
378 [ 'class' => [ 'apihelp-block', 'apihelp-flags' ] ] );
379 $msg = $context->msg( 'api-help-flags' );
380 if ( !$msg->isDisabled() ) {
381 $help['flags'] .= self::wrap(
382 $msg->numParams( count( $flags ) ), 'apihelp-block-head', 'div'
383 );
384 }
385 $help['flags'] .= Html::openElement( 'ul' );
386 foreach ( $flags as $flag ) {
387 $help['flags'] .= Html::rawElement( 'li', [],
388 // The follow classes are used here:
389 // * apihelp-flag-generator
390 // * apihelp-flag-internal
391 // * apihelp-flag-mustbeposted
392 // * apihelp-flag-readrights
393 // * apihelp-flag-writerights
394 self::wrap( $context->msg( "api-help-flag-$flag" ), "apihelp-flag-$flag" )
395 );
396 }
397 $sourceInfo = $module->getModuleSourceInfo();
398 if ( $sourceInfo ) {
399 if ( isset( $sourceInfo['namemsg'] ) ) {
400 $extname = $context->msg( $sourceInfo['namemsg'] )->text();
401 } else {
402 // Probably English, so wrap it.
403 $extname = Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $sourceInfo['name'] );
404 }
405 $help['flags'] .= Html::rawElement( 'li', [],
406 self::wrap(
407 $context->msg( 'api-help-source', $extname, $sourceInfo['name'] ),
408 'apihelp-source'
409 )
410 );
411
412 $linkText = SpecialPage::getTitleFor( 'Version', 'License/' . $sourceInfo['name'] )
413 ->getPrefixedText();
414 if ( isset( $sourceInfo['license-name'] ) ) {
415 $msg = $context->msg( 'api-help-license', $linkText,
416 Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $sourceInfo['license-name'] )
417 );
418 } elseif ( ExtensionInfo::getLicenseFileNames( dirname( $sourceInfo['path'] ) ) ) {
419 $msg = $context->msg( 'api-help-license-noname', $linkText );
420 } else {
421 $msg = $context->msg( 'api-help-license-unknown' );
422 }
423 $help['flags'] .= Html::rawElement( 'li', [],
424 self::wrap( $msg, 'apihelp-license' )
425 );
426 } else {
427 $help['flags'] .= Html::rawElement( 'li', [],
428 self::wrap( $context->msg( 'api-help-source-unknown' ), 'apihelp-source' )
429 );
430 $help['flags'] .= Html::rawElement( 'li', [],
431 self::wrap( $context->msg( 'api-help-license-unknown' ), 'apihelp-license' )
432 );
433 }
434 $help['flags'] .= Html::closeElement( 'ul' );
435 $help['flags'] .= Html::closeElement( 'div' );
436
437 foreach ( $module->getFinalDescription() as $msg ) {
438 $msg->setContext( $context );
439 $help['description'] .= $msg->parseAsBlock();
440 }
441
442 $urls = $module->getHelpUrls();
443 if ( $urls ) {
444 if ( !is_array( $urls ) ) {
445 $urls = [ $urls ];
446 }
447 $help['help-urls'] .= Html::openElement( 'div',
448 [ 'class' => [ 'apihelp-block', 'apihelp-help-urls' ] ]
449 );
450 $msg = $context->msg( 'api-help-help-urls' );
451 if ( !$msg->isDisabled() ) {
452 $help['help-urls'] .= self::wrap(
453 $msg->numParams( count( $urls ) ), 'apihelp-block-head', 'div'
454 );
455 }
456 $help['help-urls'] .= Html::openElement( 'ul' );
457 foreach ( $urls as $url ) {
458 $help['help-urls'] .= Html::rawElement( 'li', [],
459 Html::element( 'a', [ 'href' => $url, 'dir' => 'ltr' ], $url )
460 );
461 }
462 $help['help-urls'] .= Html::closeElement( 'ul' );
463 $help['help-urls'] .= Html::closeElement( 'div' );
464 }
465
466 $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
467 $dynamicParams = $module->dynamicParameterDocumentation();
468 $groups = [];
469 if ( $params || $dynamicParams !== null ) {
470 $help['parameters'] .= Html::openElement( 'div',
471 [ 'class' => [ 'apihelp-block', 'apihelp-parameters' ] ]
472 );
473 $msg = $context->msg( 'api-help-parameters' );
474 if ( !$msg->isDisabled() ) {
475 $help['parameters'] .= self::wrap(
476 $msg->numParams( count( $params ) ), 'apihelp-block-head', 'div'
477 );
478 if ( !$module->isMain() ) {
479 // Add a note explaining that other parameters may exist.
480 $help['parameters'] .= self::wrap(
481 $context->msg( 'api-help-parameters-note' ), 'apihelp-block-header', 'div'
482 );
483 }
484 }
485 $help['parameters'] .= Html::openElement( 'dl' );
486
487 $descriptions = $module->getFinalParamDescription();
488
489 foreach ( $params as $name => $settings ) {
490 $settings = $paramValidator->normalizeSettings( $settings );
491
492 if ( $settings[ParamValidator::PARAM_TYPE] === 'submodule' ) {
493 $groups[] = $name;
494 }
495
496 $encodedParamName = $module->encodeParamName( $name );
497 $paramNameAttribs = [ 'dir' => 'ltr', 'lang' => 'en' ];
498 if ( isset( $anchor ) ) {
499 $paramNameAttribs['id'] = "$anchor:$encodedParamName";
500 }
501 $help['parameters'] .= Html::rawElement( 'dt', [],
502 Html::element( 'span', $paramNameAttribs, $encodedParamName )
503 );
504
505 // Add description
506 $description = [];
507 if ( isset( $descriptions[$name] ) ) {
508 foreach ( $descriptions[$name] as $msg ) {
509 $msg->setContext( $context );
510 $description[] = $msg->parseAsBlock();
511 }
512 }
513 if ( !array_filter( $description ) ) {
514 $description = [ self::wrap(
515 $context->msg( 'api-help-param-no-description' ),
516 'apihelp-empty'
517 ) ];
518 }
519
520 // Add "deprecated" flag
521 if ( !empty( $settings[ParamValidator::PARAM_DEPRECATED] ) ) {
522 $help['parameters'] .= Html::openElement( 'dd',
523 [ 'class' => 'info' ] );
524 $help['parameters'] .= self::wrap(
525 $context->msg( 'api-help-param-deprecated' ),
526 'apihelp-deprecated', 'strong'
527 );
528 $help['parameters'] .= Html::closeElement( 'dd' );
529 }
530
531 if ( $description ) {
532 $description = implode( '', $description );
533 $description = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $description );
534 $help['parameters'] .= Html::rawElement( 'dd',
535 [ 'class' => 'description' ], $description );
536 }
537
538 // Add usage info
539 $info = [];
540 $paramHelp = $paramValidator->getHelpInfo( $module, $name, $settings, [] );
541
542 unset( $paramHelp[ParamValidator::PARAM_DEPRECATED] );
543
544 if ( isset( $paramHelp[ParamValidator::PARAM_REQUIRED] ) ) {
545 $paramHelp[ParamValidator::PARAM_REQUIRED]->setContext( $context );
546 $info[] = $paramHelp[ParamValidator::PARAM_REQUIRED];
547 unset( $paramHelp[ParamValidator::PARAM_REQUIRED] );
548 }
549
550 // Custom info?
551 if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) {
552 foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) {
553 $tag = array_shift( $i );
554 $info[] = $context->msg( "apihelp-{$path}-paraminfo-{$tag}" )
555 ->numParams( count( $i ) )
556 ->params( $context->getLanguage()->commaList( $i ) )
557 ->params( $module->getModulePrefix() )
558 ->parse();
559 }
560 }
561
562 // Templated?
563 if ( !empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
564 $vars = [];
565 $msg = 'api-help-param-templated-var-first';
566 foreach ( $settings[ApiBase::PARAM_TEMPLATE_VARS] as $k => $v ) {
567 $vars[] = $context->msg( $msg, $k, $module->encodeParamName( $v ) );
568 $msg = 'api-help-param-templated-var';
569 }
570 $info[] = $context->msg( 'api-help-param-templated' )
571 ->numParams( count( $vars ) )
572 ->params( Message::listParam( $vars ) )
573 ->parse();
574 }
575
576 // Type documentation
577 foreach ( $paramHelp as $m ) {
578 $m->setContext( $context );
579 $info[] = $m->parse();
580 }
581
582 foreach ( $info as $i ) {
583 $help['parameters'] .= Html::rawElement( 'dd', [ 'class' => 'info' ], $i );
584 }
585 }
586
587 if ( $dynamicParams !== null ) {
588 $dynamicParams = $context->msg(
589 Message::newFromSpecifier( $dynamicParams ),
590 $module->getModulePrefix(),
591 $module->getModuleName(),
592 $module->getModulePath()
593 );
594 $help['parameters'] .= Html::element( 'dt', [], '*' );
595 $help['parameters'] .= Html::rawElement( 'dd',
596 [ 'class' => 'description' ], $dynamicParams->parse() );
597 }
598
599 $help['parameters'] .= Html::closeElement( 'dl' );
600 $help['parameters'] .= Html::closeElement( 'div' );
601 }
602
603 $examples = $module->getExamplesMessages();
604 if ( $examples ) {
605 $help['examples'] .= Html::openElement( 'div',
606 [ 'class' => [ 'apihelp-block', 'apihelp-examples' ] ] );
607 $msg = $context->msg( 'api-help-examples' );
608 if ( !$msg->isDisabled() ) {
609 $help['examples'] .= self::wrap(
610 $msg->numParams( count( $examples ) ), 'apihelp-block-head', 'div'
611 );
612 }
613
614 $help['examples'] .= Html::openElement( 'dl' );
615 foreach ( $examples as $qs => $msg ) {
616 $msg = $context->msg(
618 $module->getModulePrefix(),
619 $module->getModuleName(),
620 $module->getModulePath()
621 );
622
623 $link = wfAppendQuery( wfScript( 'api' ), $qs );
624 $sandbox = SpecialPage::getTitleFor( 'ApiSandbox' )->getLocalURL() . '#' . $qs;
625 $help['examples'] .= Html::rawElement( 'dt', [], $msg->parse() );
626 $help['examples'] .= Html::rawElement( 'dd', [],
627 Html::element( 'a', [
628 'href' => $link,
629 'dir' => 'ltr',
630 'rel' => 'nofollow',
631 ], "api.php?$qs" ) . ' ' .
632 Html::rawElement( 'a', [ 'href' => $sandbox ],
633 $context->msg( 'api-help-open-in-apisandbox' )->parse() )
634 );
635 }
636 $help['examples'] .= Html::closeElement( 'dl' );
637 $help['examples'] .= Html::closeElement( 'div' );
638 }
639
640 $subtocnumber = $tocnumber;
641 $subtocnumber[$level + 1] = 0;
642 $suboptions = [
643 'submodules' => $options['recursivesubmodules'],
644 'headerlevel' => $level + 1,
645 'tocnumber' => &$subtocnumber,
646 'noheader' => false,
647 ] + $options;
648
649 if ( $options['submodules'] && $module->getModuleManager() ) {
650 $manager = $module->getModuleManager();
651 $submodules = [];
652 foreach ( $groups as $group ) {
653 $names = $manager->getNames( $group );
654 sort( $names );
655 foreach ( $names as $name ) {
656 $submodules[] = $manager->getModule( $name );
657 }
658 }
659 $help['submodules'] .= self::getHelpInternal(
660 $context,
661 $submodules,
662 $suboptions,
663 $haveModules
664 );
665 }
666
667 $module->modifyHelp( $help, $suboptions, $haveModules );
668
669 if ( $module->getHookContainer()->isRegistered( 'APIHelpModifyOutput' ) ) {
670 // XXX: we should probably deprecate this hook so that we can
671 // migrate the $haveModules format.
672 if ( !empty( $suboptions['toc'] ) ) {
673 $haveModules = array_map(
674 static fn ( $s )=>$s->toLegacy(), $haveModules
675 );
676 }
677 $module->getHookRunner()->onAPIHelpModifyOutput(
678 $module, $help, $suboptions, $haveModules
679 );
680 if ( !empty( $suboptions['toc'] ) ) {
681 $haveModules = array_map(
682 static fn ( $s )=>SectionMetadata::fromLegacy( $s ), $haveModules
683 );
684 }
685 }
686
687 $out .= implode( "\n", $help );
688 }
689
690 return $out;
691 }
692
694 public function shouldCheckMaxlag() {
695 return false;
696 }
697
699 public function isReadMode() {
700 return false;
701 }
702
704 public function getCustomPrinter() {
705 $params = $this->extractRequestParams();
706 if ( $params['wrap'] ) {
707 return null;
708 }
709
710 $main = $this->getMain();
711 $errorPrinter = $main->createPrinterByName( $main->getParameter( 'format' ) );
712 return new ApiFormatRaw( $main, $errorPrinter );
713 }
714
716 public function getAllowedParams() {
717 return [
718 'modules' => [
719 ParamValidator::PARAM_DEFAULT => 'main',
720 ParamValidator::PARAM_ISMULTI => true,
721 ],
722 'submodules' => false,
723 'recursivesubmodules' => false,
724 'wrap' => false,
725 'toc' => false,
726 ];
727 }
728
730 protected function getExamplesMessages() {
731 return [
732 'action=help'
733 => 'apihelp-help-example-main',
734 'action=help&modules=query&submodules=1'
735 => 'apihelp-help-example-submodules',
736 'action=help&recursivesubmodules=1&toc'
737 => 'apihelp-help-example-recursive',
738 'action=help&modules=help'
739 => 'apihelp-help-example-help',
740 'action=help&modules=query+info|query+categorymembers'
741 => 'apihelp-help-example-query',
742 ];
743 }
744
746 public function getHelpUrls() {
747 return [
748 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Main_page',
749 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:FAQ',
750 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Quick_start_guide',
751 ];
752 }
753}
754
756class_alias( ApiHelp::class, 'ApiHelp' );
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
wfScript( $script='index')
Get the URL path to a MediaWiki entry point.
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:60
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:557
const PARAM_HELP_MSG_INFO
(array) Specify additional information tags for the parameter.
Definition ApiBase.php:184
getMain()
Get the main module.
Definition ApiBase.php:575
getModulePath()
Get the path to this module.
Definition ApiBase.php:636
getResult()
Get the result object.
Definition ApiBase.php:696
const PARAM_TEMPLATE_VARS
(array) Indicate that this is a templated parameter, and specify replacements.
Definition ApiBase.php:224
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:837
getModuleFromPath( $path)
Get a module from its module path.
Definition ApiBase.php:656
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When this is set, the result could take longer to generate,...
Definition ApiBase.php:244
Formatter that spits out anything you like with any desired MIME type.
Class to output help for an API module.
Definition ApiHelp.php:37
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition ApiHelp.php:716
shouldCheckMaxlag()
Indicates if this module needs maxlag to be checked.to override bool
Definition ApiHelp.php:694
__construct(ApiMain $main, string $action, private readonly SkinFactory $skinFactory,)
Definition ApiHelp.php:39
static getHelp(IContextSource $context, $modules, array $options)
Generate help for the specified modules.
Definition ApiHelp.php:126
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
Definition ApiHelp.php:47
isReadMode()
Indicates whether this module requires read rights.to override bool
Definition ApiHelp.php:699
getHelpUrls()
Return links to more detailed help pages about the module.1.25, returning boolean false is deprecated...
Definition ApiHelp.php:746
static fixHelpLinks( $html, $helptitle=null, $localModules=[])
Replace Special:ApiHelp links with links to api.php.
Definition ApiHelp.php:207
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
Definition ApiHelp.php:730
getCustomPrinter()
If the module may only be used with a certain format module, it should override this method to return...
Definition ApiHelp.php:704
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:66
const NO_SIZE_CHECK
For addValue() and similar functions, do not check size while adding a value Don't use this unless yo...
Definition ApiResult.php:57
static setSubelementsList(array &$arr, $names)
Causes the elements with the specified names to be output as subelements rather than attributes.
An IContextSource implementation which will inherit context from another source but allow individual ...
Static utilities for manipulating HTML strings.
static modifyElements(string $htmlFragment, callable $shouldModifyCallback, callable $modifyCallback, bool $html5format=true)
Modify elements of an HTML fragment via a user-provided callback.
This class is a collection of static functions that serve two purposes:
Definition Html.php:44
JSON formatter wrapper class.
A class containing constants representing the names of configuration variables.
const APICacheHelpTimeout
Name constant for the APICacheHelpTimeout setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:144
static newFromSpecifier( $value)
Transform a MessageSpecifier or a primitive value used interchangeably with specifiers (a message key...
Definition Message.php:492
parse()
Fully parse the text from wikitext to HTML.
Definition Message.php:1125
static listParam(array $list, $type=ListType::AND)
Definition Message.php:1355
This is one of the Core classes and should be read at least once by any new developers.
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:34
Factory class to create Skin objects.
Parent class for all special pages.
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,...
Version information about MediaWiki (core, extensions, libs), PHP, and the database.
Represents a title within MediaWiki.
Definition Title.php:69
Service for formatting and validating API parameters.
Interface for objects which can provide a MediaWiki context on request.
getConfig()
Get the site configuration.
msg( $key,... $params)
This is the method for getting translated interface messages.
element(SerializerNode $parent, SerializerNode $node, $contents)
array $params
The job parameters.