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