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