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