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