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