MediaWiki master
ApiHelp.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
26use Wikimedia\Parsoid\Core\TOCData;
27use Wikimedia\RemexHtml\Serializer\SerializerNode;
28
35class ApiHelp extends ApiBase {
36 private SkinFactory $skinFactory;
37
38 public function __construct(
39 ApiMain $main,
40 string $action,
41 SkinFactory $skinFactory
42 ) {
43 parent::__construct( $main, $action );
44 $this->skinFactory = $skinFactory;
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 $options['recursivesubmodules'] = !empty( $options['recursivesubmodules'] );
165 $options['submodules'] = $options['recursivesubmodules'] || !empty( $options['submodules'] );
166
167 // Prepend lead
168 if ( empty( $options['nolead'] ) ) {
169 $msg = $context->msg( 'api-help-lead' );
170 if ( !$msg->isDisabled() ) {
171 $out->addHTML( $msg->parseAsBlock() );
172 }
173 }
174
175 $haveModules = [];
176 $html = self::getHelpInternal( $context, $modules, $options, $haveModules );
177 if ( !empty( $options['toc'] ) && $haveModules ) {
178 $out->addTOCPlaceholder( TOCData::fromLegacy( array_values( $haveModules ) ) );
179 }
180 $out->addHTML( $html );
181
182 $helptitle = $options['helptitle'] ?? null;
183 $html = self::fixHelpLinks( $out->getHTML(), $helptitle, $haveModules );
184 $out->clearHTML();
185 $out->addHTML( $html );
186
187 if ( $cacheKey !== null ) {
188 // @phan-suppress-next-line PhanPossiblyUndeclaredVariable $cacheHelpTimeout declared when $cacheKey is set
189 $cache->set( $cacheKey, $out->getHTML(), $cacheHelpTimeout );
190 }
191 }
192
201 public static function fixHelpLinks( $html, $helptitle = null, $localModules = [] ) {
203 $html,
204 static function ( SerializerNode $node ): bool {
205 return $node->name === 'a'
206 && isset( $node->attrs['href'] )
207 && !str_contains( $node->attrs['class'] ?? '', 'apihelp-linktrail' );
208 },
209 static function ( SerializerNode $node ) use ( $helptitle, $localModules ): SerializerNode {
210 $href = $node->attrs['href'];
211 // FIXME This can't be right to do this in a loop
212 do {
213 $old = $href;
214 $href = rawurldecode( $href );
215 } while ( $old !== $href );
216 if ( preg_match( '!Special:ApiHelp/([^&/|#]+)((?:#.*)?)!', $href, $m ) ) {
217 if ( isset( $localModules[$m[1]] ) ) {
218 $href = $m[2] === '' ? '#' . $m[1] : $m[2];
219 } elseif ( $helptitle !== null ) {
220 $href = Title::newFromText( str_replace( '$1', $m[1], $helptitle ) . $m[2] )
221 ->getFullURL();
222 } else {
223 $href = wfAppendQuery( wfScript( 'api' ), [
224 'action' => 'help',
225 'modules' => $m[1],
226 ] ) . $m[2];
227 }
228 $node->attrs['href'] = $href;
229 unset( $node->attrs['title'] );
230 }
231
232 return $node;
233 }
234 );
235 }
236
245 private static function wrap( Message $msg, $class, $tag = 'span' ) {
246 return Html::rawElement( $tag, [ 'class' => $class ],
247 $msg->parse()
248 );
249 }
250
260 private static function getHelpInternal( IContextSource $context, array $modules,
261 array $options, &$haveModules
262 ) {
263 $out = '';
264
265 $level = empty( $options['headerlevel'] ) ? 2 : $options['headerlevel'];
266 if ( empty( $options['tocnumber'] ) ) {
267 $tocnumber = [ 2 => 0 ];
268 } else {
269 $tocnumber = &$options['tocnumber'];
270 }
271
272 foreach ( $modules as $module ) {
273 $paramValidator = $module->getMain()->getParamValidator();
274 $tocnumber[$level]++;
275 $path = $module->getModulePath();
276 $module->setContext( $context );
277 $help = [
278 'header' => '',
279 'flags' => '',
280 'description' => '',
281 'help-urls' => '',
282 'parameters' => '',
283 'examples' => '',
284 'submodules' => '',
285 ];
286
287 if ( empty( $options['noheader'] ) || !empty( $options['toc'] ) ) {
288 $anchor = $path;
289 $i = 1;
290 while ( isset( $haveModules[$anchor] ) ) {
291 $anchor = $path . '|' . ++$i;
292 }
293
294 if ( $module->isMain() ) {
295 $headerContent = $context->msg( 'api-help-main-header' )->parse();
296 $headerAttr = [
297 'class' => 'apihelp-header',
298 ];
299 } else {
300 $name = $module->getModuleName();
301 $headerContent = htmlspecialchars(
302 $module->getParent()->getModuleManager()->getModuleGroup( $name ) . "=$name"
303 );
304 if ( $module->getModulePrefix() !== '' ) {
305 $headerContent .= ' ' .
306 $context->msg( 'parentheses', $module->getModulePrefix() )->parse();
307 }
308 // Module names are always in English and not localized,
309 // so English language and direction must be set explicitly,
310 // otherwise parentheses will get broken in RTL wikis
311 $headerAttr = [
312 'class' => [ 'apihelp-header', 'apihelp-module-name' ],
313 'dir' => 'ltr',
314 'lang' => 'en',
315 ];
316 }
317
318 $headerAttr['id'] = $anchor;
319
320 // T326687: Maybe transition to using a SectionMetadata object?
321 $haveModules[$anchor] = [
322 'toclevel' => count( $tocnumber ),
323 'level' => $level,
324 'anchor' => $anchor,
325 'line' => $headerContent,
326 'number' => implode( '.', $tocnumber ),
327 'index' => '',
328 ];
329 if ( empty( $options['noheader'] ) ) {
330 $help['header'] .= Html::rawElement(
331 'h' . min( 6, $level ),
332 $headerAttr,
333 $headerContent
334 );
335 }
336 } else {
337 $haveModules[$path] = true;
338 }
339
340 $links = [];
341 $any = false;
342 for ( $m = $module; $m !== null; $m = $m->getParent() ) {
343 $name = $m->getModuleName();
344 if ( $name === 'main_int' ) {
345 $name = 'main';
346 }
347
348 if ( count( $modules ) === 1 && $m === $modules[0] &&
349 !( !empty( $options['submodules'] ) && $m->getModuleManager() )
350 ) {
351 $link = Html::element( 'b', [ 'dir' => 'ltr', 'lang' => 'en' ], $name );
352 } else {
353 $link = SpecialPage::getTitleFor( 'ApiHelp', $m->getModulePath() )->getLocalURL();
354 $link = Html::element( 'a',
355 [ 'href' => $link, 'class' => 'apihelp-linktrail', 'dir' => 'ltr', 'lang' => 'en' ],
356 $name
357 );
358 $any = true;
359 }
360 array_unshift( $links, $link );
361 }
362 if ( $any ) {
363 $help['header'] .= self::wrap(
364 $context->msg( 'parentheses' )
365 ->rawParams( $context->getLanguage()->pipeList( $links ) ),
366 'apihelp-linktrail', 'div'
367 );
368 }
369
370 $flags = $module->getHelpFlags();
371 $help['flags'] .= Html::openElement( 'div',
372 [ 'class' => [ 'apihelp-block', 'apihelp-flags' ] ] );
373 $msg = $context->msg( 'api-help-flags' );
374 if ( !$msg->isDisabled() ) {
375 $help['flags'] .= self::wrap(
376 $msg->numParams( count( $flags ) ), 'apihelp-block-head', 'div'
377 );
378 }
379 $help['flags'] .= Html::openElement( 'ul' );
380 foreach ( $flags as $flag ) {
381 $help['flags'] .= Html::rawElement( 'li', [],
382 // The follow classes are used here:
383 // * apihelp-flag-generator
384 // * apihelp-flag-internal
385 // * apihelp-flag-mustbeposted
386 // * apihelp-flag-readrights
387 // * apihelp-flag-writerights
388 self::wrap( $context->msg( "api-help-flag-$flag" ), "apihelp-flag-$flag" )
389 );
390 }
391 $sourceInfo = $module->getModuleSourceInfo();
392 if ( $sourceInfo ) {
393 if ( isset( $sourceInfo['namemsg'] ) ) {
394 $extname = $context->msg( $sourceInfo['namemsg'] )->text();
395 } else {
396 // Probably English, so wrap it.
397 $extname = Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $sourceInfo['name'] );
398 }
399 $help['flags'] .= Html::rawElement( 'li', [],
400 self::wrap(
401 $context->msg( 'api-help-source', $extname, $sourceInfo['name'] ),
402 'apihelp-source'
403 )
404 );
405
406 $linkText = SpecialPage::getTitleFor( 'Version', 'License/' . $sourceInfo['name'] )
407 ->getPrefixedText();
408 if ( isset( $sourceInfo['license-name'] ) ) {
409 $msg = $context->msg( 'api-help-license', $linkText,
410 Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $sourceInfo['license-name'] )
411 );
412 } elseif ( ExtensionInfo::getLicenseFileNames( dirname( $sourceInfo['path'] ) ) ) {
413 $msg = $context->msg( 'api-help-license-noname', $linkText );
414 } else {
415 $msg = $context->msg( 'api-help-license-unknown' );
416 }
417 $help['flags'] .= Html::rawElement( 'li', [],
418 self::wrap( $msg, 'apihelp-license' )
419 );
420 } else {
421 $help['flags'] .= Html::rawElement( 'li', [],
422 self::wrap( $context->msg( 'api-help-source-unknown' ), 'apihelp-source' )
423 );
424 $help['flags'] .= Html::rawElement( 'li', [],
425 self::wrap( $context->msg( 'api-help-license-unknown' ), 'apihelp-license' )
426 );
427 }
428 $help['flags'] .= Html::closeElement( 'ul' );
429 $help['flags'] .= Html::closeElement( 'div' );
430
431 foreach ( $module->getFinalDescription() as $msg ) {
432 $msg->setContext( $context );
433 $help['description'] .= $msg->parseAsBlock();
434 }
435
436 $urls = $module->getHelpUrls();
437 if ( $urls ) {
438 if ( !is_array( $urls ) ) {
439 $urls = [ $urls ];
440 }
441 $help['help-urls'] .= Html::openElement( 'div',
442 [ 'class' => [ 'apihelp-block', 'apihelp-help-urls' ] ]
443 );
444 $msg = $context->msg( 'api-help-help-urls' );
445 if ( !$msg->isDisabled() ) {
446 $help['help-urls'] .= self::wrap(
447 $msg->numParams( count( $urls ) ), 'apihelp-block-head', 'div'
448 );
449 }
450 $help['help-urls'] .= Html::openElement( 'ul' );
451 foreach ( $urls as $url ) {
452 $help['help-urls'] .= Html::rawElement( 'li', [],
453 Html::element( 'a', [ 'href' => $url, 'dir' => 'ltr' ], $url )
454 );
455 }
456 $help['help-urls'] .= Html::closeElement( 'ul' );
457 $help['help-urls'] .= Html::closeElement( 'div' );
458 }
459
460 $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
461 $dynamicParams = $module->dynamicParameterDocumentation();
462 $groups = [];
463 if ( $params || $dynamicParams !== null ) {
464 $help['parameters'] .= Html::openElement( 'div',
465 [ 'class' => [ 'apihelp-block', 'apihelp-parameters' ] ]
466 );
467 $msg = $context->msg( 'api-help-parameters' );
468 if ( !$msg->isDisabled() ) {
469 $help['parameters'] .= self::wrap(
470 $msg->numParams( count( $params ) ), 'apihelp-block-head', 'div'
471 );
472 if ( !$module->isMain() ) {
473 // Add a note explaining that other parameters may exist.
474 $help['parameters'] .= self::wrap(
475 $context->msg( 'api-help-parameters-note' ), 'apihelp-block-header', 'div'
476 );
477 }
478 }
479 $help['parameters'] .= Html::openElement( 'dl' );
480
481 $descriptions = $module->getFinalParamDescription();
482
483 foreach ( $params as $name => $settings ) {
484 $settings = $paramValidator->normalizeSettings( $settings );
485
486 if ( $settings[ParamValidator::PARAM_TYPE] === 'submodule' ) {
487 $groups[] = $name;
488 }
489
490 $encodedParamName = $module->encodeParamName( $name );
491 $paramNameAttribs = [ 'dir' => 'ltr', 'lang' => 'en' ];
492 if ( isset( $anchor ) ) {
493 $paramNameAttribs['id'] = "$anchor:$encodedParamName";
494 }
495 $help['parameters'] .= Html::rawElement( 'dt', [],
496 Html::element( 'span', $paramNameAttribs, $encodedParamName )
497 );
498
499 // Add description
500 $description = [];
501 if ( isset( $descriptions[$name] ) ) {
502 foreach ( $descriptions[$name] as $msg ) {
503 $msg->setContext( $context );
504 $description[] = $msg->parseAsBlock();
505 }
506 }
507 if ( !array_filter( $description ) ) {
508 $description = [ self::wrap(
509 $context->msg( 'api-help-param-no-description' ),
510 'apihelp-empty'
511 ) ];
512 }
513
514 // Add "deprecated" flag
515 if ( !empty( $settings[ParamValidator::PARAM_DEPRECATED] ) ) {
516 $help['parameters'] .= Html::openElement( 'dd',
517 [ 'class' => 'info' ] );
518 $help['parameters'] .= self::wrap(
519 $context->msg( 'api-help-param-deprecated' ),
520 'apihelp-deprecated', 'strong'
521 );
522 $help['parameters'] .= Html::closeElement( 'dd' );
523 }
524
525 if ( $description ) {
526 $description = implode( '', $description );
527 $description = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $description );
528 $help['parameters'] .= Html::rawElement( 'dd',
529 [ 'class' => 'description' ], $description );
530 }
531
532 // Add usage info
533 $info = [];
534 $paramHelp = $paramValidator->getHelpInfo( $module, $name, $settings, [] );
535
536 unset( $paramHelp[ParamValidator::PARAM_DEPRECATED] );
537
538 if ( isset( $paramHelp[ParamValidator::PARAM_REQUIRED] ) ) {
539 $paramHelp[ParamValidator::PARAM_REQUIRED]->setContext( $context );
540 $info[] = $paramHelp[ParamValidator::PARAM_REQUIRED];
541 unset( $paramHelp[ParamValidator::PARAM_REQUIRED] );
542 }
543
544 // Custom info?
545 if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) {
546 foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) {
547 $tag = array_shift( $i );
548 $info[] = $context->msg( "apihelp-{$path}-paraminfo-{$tag}" )
549 ->numParams( count( $i ) )
550 ->params( $context->getLanguage()->commaList( $i ) )
551 ->params( $module->getModulePrefix() )
552 ->parse();
553 }
554 }
555
556 // Templated?
557 if ( !empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
558 $vars = [];
559 $msg = 'api-help-param-templated-var-first';
560 foreach ( $settings[ApiBase::PARAM_TEMPLATE_VARS] as $k => $v ) {
561 $vars[] = $context->msg( $msg, $k, $module->encodeParamName( $v ) );
562 $msg = 'api-help-param-templated-var';
563 }
564 $info[] = $context->msg( 'api-help-param-templated' )
565 ->numParams( count( $vars ) )
566 ->params( Message::listParam( $vars ) )
567 ->parse();
568 }
569
570 // Type documentation
571 foreach ( $paramHelp as $m ) {
572 $m->setContext( $context );
573 $info[] = $m->parse();
574 }
575
576 foreach ( $info as $i ) {
577 $help['parameters'] .= Html::rawElement( 'dd', [ 'class' => 'info' ], $i );
578 }
579 }
580
581 if ( $dynamicParams !== null ) {
582 $dynamicParams = $context->msg(
583 Message::newFromSpecifier( $dynamicParams ),
584 $module->getModulePrefix(),
585 $module->getModuleName(),
586 $module->getModulePath()
587 );
588 $help['parameters'] .= Html::element( 'dt', [], '*' );
589 $help['parameters'] .= Html::rawElement( 'dd',
590 [ 'class' => 'description' ], $dynamicParams->parse() );
591 }
592
593 $help['parameters'] .= Html::closeElement( 'dl' );
594 $help['parameters'] .= Html::closeElement( 'div' );
595 }
596
597 $examples = $module->getExamplesMessages();
598 if ( $examples ) {
599 $help['examples'] .= Html::openElement( 'div',
600 [ 'class' => [ 'apihelp-block', 'apihelp-examples' ] ] );
601 $msg = $context->msg( 'api-help-examples' );
602 if ( !$msg->isDisabled() ) {
603 $help['examples'] .= self::wrap(
604 $msg->numParams( count( $examples ) ), 'apihelp-block-head', 'div'
605 );
606 }
607
608 $help['examples'] .= Html::openElement( 'dl' );
609 foreach ( $examples as $qs => $msg ) {
610 $msg = $context->msg(
612 $module->getModulePrefix(),
613 $module->getModuleName(),
614 $module->getModulePath()
615 );
616
617 $link = wfAppendQuery( wfScript( 'api' ), $qs );
618 $sandbox = SpecialPage::getTitleFor( 'ApiSandbox' )->getLocalURL() . '#' . $qs;
619 $help['examples'] .= Html::rawElement( 'dt', [], $msg->parse() );
620 $help['examples'] .= Html::rawElement( 'dd', [],
621 Html::element( 'a', [
622 'href' => $link,
623 'dir' => 'ltr',
624 'rel' => 'nofollow',
625 ], "api.php?$qs" ) . ' ' .
626 Html::rawElement( 'a', [ 'href' => $sandbox ],
627 $context->msg( 'api-help-open-in-apisandbox' )->parse() )
628 );
629 }
630 $help['examples'] .= Html::closeElement( 'dl' );
631 $help['examples'] .= Html::closeElement( 'div' );
632 }
633
634 $subtocnumber = $tocnumber;
635 $subtocnumber[$level + 1] = 0;
636 $suboptions = [
637 'submodules' => $options['recursivesubmodules'],
638 'headerlevel' => $level + 1,
639 'tocnumber' => &$subtocnumber,
640 'noheader' => false,
641 ] + $options;
642
643 // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset False positive
644 if ( $options['submodules'] && $module->getModuleManager() ) {
645 $manager = $module->getModuleManager();
646 $submodules = [];
647 foreach ( $groups as $group ) {
648 $names = $manager->getNames( $group );
649 sort( $names );
650 foreach ( $names as $name ) {
651 $submodules[] = $manager->getModule( $name );
652 }
653 }
654 $help['submodules'] .= self::getHelpInternal(
655 $context,
656 $submodules,
657 $suboptions,
658 $haveModules
659 );
660 }
661
662 $module->modifyHelp( $help, $suboptions, $haveModules );
663
664 $module->getHookRunner()->onAPIHelpModifyOutput( $module, $help,
665 $suboptions, $haveModules );
666
667 $out .= implode( "\n", $help );
668 }
669
670 return $out;
671 }
672
674 public function shouldCheckMaxlag() {
675 return false;
676 }
677
679 public function isReadMode() {
680 return false;
681 }
682
684 public function getCustomPrinter() {
685 $params = $this->extractRequestParams();
686 if ( $params['wrap'] ) {
687 return null;
688 }
689
690 $main = $this->getMain();
691 $errorPrinter = $main->createPrinterByName( $main->getParameter( 'format' ) );
692 return new ApiFormatRaw( $main, $errorPrinter );
693 }
694
696 public function getAllowedParams() {
697 return [
698 'modules' => [
699 ParamValidator::PARAM_DEFAULT => 'main',
700 ParamValidator::PARAM_ISMULTI => true,
701 ],
702 'submodules' => false,
703 'recursivesubmodules' => false,
704 'wrap' => false,
705 'toc' => false,
706 ];
707 }
708
710 protected function getExamplesMessages() {
711 return [
712 'action=help'
713 => 'apihelp-help-example-main',
714 'action=help&modules=query&submodules=1'
715 => 'apihelp-help-example-submodules',
716 'action=help&recursivesubmodules=1'
717 => 'apihelp-help-example-recursive',
718 'action=help&modules=help'
719 => 'apihelp-help-example-help',
720 'action=help&modules=query+info|query+categorymembers'
721 => 'apihelp-help-example-query',
722 ];
723 }
724
726 public function getHelpUrls() {
727 return [
728 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Main_page',
729 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:FAQ',
730 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Quick_start_guide',
731 ];
732 }
733}
734
736class_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:61
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:543
const PARAM_HELP_MSG_INFO
(array) Specify additional information tags for the parameter.
Definition ApiBase.php:185
getMain()
Get the main module.
Definition ApiBase.php:561
getModulePath()
Get the path to this module.
Definition ApiBase.php:622
getResult()
Get the result object.
Definition ApiBase.php:682
const PARAM_TEMPLATE_VARS
(array) Indicate that this is a templated parameter, and specify replacements.
Definition ApiBase.php:225
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:823
getModuleFromPath( $path)
Get a module from its module path.
Definition ApiBase.php:642
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When this is set, the result could take longer to generate,...
Definition ApiBase.php:245
Formatter that spits out anything you like with any desired MIME type.
Class to output help for an API module.
Definition ApiHelp.php:35
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition ApiHelp.php:696
shouldCheckMaxlag()
Indicates if this module needs maxlag to be checked.to override bool
Definition ApiHelp.php:674
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:679
getHelpUrls()
Return links to more detailed help pages about the module.1.25, returning boolean false is deprecated...
Definition ApiHelp.php:726
static fixHelpLinks( $html, $helptitle=null, $localModules=[])
Replace Special:ApiHelp links with links to api.php.
Definition ApiHelp.php:201
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
Definition ApiHelp.php:710
getCustomPrinter()
If the module may only be used with a certain format module, it should override this method to return...
Definition ApiHelp.php:684
__construct(ApiMain $main, string $action, SkinFactory $skinFactory)
Definition ApiHelp.php:38
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:65
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:55
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:43
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:1122
static listParam(array $list, $type=ListType::AND)
Definition Message.php:1352
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: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.