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