MediaWiki  master
ApiBase.php
Go to the documentation of this file.
1 <?php
35 
48 abstract class ApiBase extends ContextSource {
49 
51 
58  public const PARAM_DFLT = ParamValidator::PARAM_DEFAULT;
59  public const PARAM_ISMULTI = ParamValidator::PARAM_ISMULTI;
60  public const PARAM_TYPE = ParamValidator::PARAM_TYPE;
61  public const PARAM_MAX = IntegerDef::PARAM_MAX;
62  public const PARAM_MAX2 = IntegerDef::PARAM_MAX2;
63  public const PARAM_MIN = IntegerDef::PARAM_MIN;
64  public const PARAM_ALLOW_DUPLICATES = ParamValidator::PARAM_ALLOW_DUPLICATES;
65  public const PARAM_DEPRECATED = ParamValidator::PARAM_DEPRECATED;
66  public const PARAM_REQUIRED = ParamValidator::PARAM_REQUIRED;
67  public const PARAM_SUBMODULE_MAP = SubmoduleDef::PARAM_SUBMODULE_MAP;
68  public const PARAM_SUBMODULE_PARAM_PREFIX = SubmoduleDef::PARAM_SUBMODULE_PARAM_PREFIX;
69  public const PARAM_ALL = ParamValidator::PARAM_ALL;
70  public const PARAM_EXTRA_NAMESPACES = NamespaceDef::PARAM_EXTRA_NAMESPACES;
71  public const PARAM_SENSITIVE = ParamValidator::PARAM_SENSITIVE;
72  public const PARAM_DEPRECATED_VALUES = EnumDef::PARAM_DEPRECATED_VALUES;
73  public const PARAM_ISMULTI_LIMIT1 = ParamValidator::PARAM_ISMULTI_LIMIT1;
74  public const PARAM_ISMULTI_LIMIT2 = ParamValidator::PARAM_ISMULTI_LIMIT2;
75  public const PARAM_MAX_BYTES = StringDef::PARAM_MAX_BYTES;
76  public const PARAM_MAX_CHARS = StringDef::PARAM_MAX_CHARS;
77 
82  public const PARAM_RANGE_ENFORCE = 'api-param-range-enforce';
83 
96  public const PARAM_HELP_MSG = 'api-param-help-msg';
97 
103  public const PARAM_HELP_MSG_APPEND = 'api-param-help-msg-append';
104 
113  public const PARAM_HELP_MSG_INFO = 'api-param-help-msg-info';
114 
120  public const PARAM_VALUE_LINKS = 'api-param-value-links';
121 
129  public const PARAM_HELP_MSG_PER_VALUE = 'api-param-help-msg-per-value';
130 
147  public const PARAM_TEMPLATE_VARS = 'param-template-vars';
148 
151  public const ALL_DEFAULT_STRING = '*';
152 
154  public const LIMIT_BIG1 = 500;
156  public const LIMIT_BIG2 = 5000;
158  public const LIMIT_SML1 = 50;
160  public const LIMIT_SML2 = 500;
161 
167  public const GET_VALUES_FOR_HELP = 1;
168 
170  private static $extensionInfo = null;
171 
173  private static $filterIDsCache = [];
174 
176  private static $blockMsgMap = [
177  'blockedtext' => [ 'apierror-blocked', 'blocked' ],
178  'blockedtext-partial' => [ 'apierror-blocked-partial', 'blocked' ],
179  'autoblockedtext' => [ 'apierror-autoblocked', 'autoblocked' ],
180  'systemblockedtext' => [ 'apierror-systemblocked', 'blocked' ],
181  'blockedtext-composite' => [ 'apierror-blocked', 'blocked' ],
182  ];
183 
185  private $mMainModule;
188  private $mReplicaDB = null;
192  private $mParamCache = [];
194  private $mModuleSource = false;
195 
201  public function __construct( ApiMain $mainModule, $moduleName, $modulePrefix = '' ) {
202  $this->mMainModule = $mainModule;
203  $this->mModuleName = $moduleName;
204  $this->mModulePrefix = $modulePrefix;
205 
206  if ( !$this->isMain() ) {
207  $this->setContext( $mainModule->getContext() );
208  }
209  }
210 
211  /************************************************************************/
232  abstract public function execute();
233 
239  public function getModuleManager() {
240  return null;
241  }
242 
252  public function getCustomPrinter() {
253  return null;
254  }
255 
267  protected function getExamplesMessages() {
268  return [];
269  }
270 
276  public function getHelpUrls() {
277  return [];
278  }
279 
292  protected function getAllowedParams( /* $flags = 0 */ ) {
293  // int $flags is not declared because it causes "Strict standards"
294  // warning. Most derived classes do not implement it.
295  return [];
296  }
297 
302  public function shouldCheckMaxlag() {
303  return true;
304  }
305 
310  public function isReadMode() {
311  return true;
312  }
313 
325  public function isWriteMode() {
326  return false;
327  }
328 
333  public function mustBePosted() {
334  return $this->needsToken() !== false;
335  }
336 
342  public function isDeprecated() {
343  return false;
344  }
345 
352  public function isInternal() {
353  return false;
354  }
355 
374  public function needsToken() {
375  return false;
376  }
377 
387  protected function getWebUITokenSalt( array $params ) {
388  return null;
389  }
390 
403  public function getConditionalRequestData( $condition ) {
404  return null;
405  }
406 
409  /************************************************************************/
418  public function getModuleName() {
419  return $this->mModuleName;
420  }
421 
426  public function getModulePrefix() {
427  return $this->mModulePrefix;
428  }
429 
434  public function getMain() {
435  return $this->mMainModule;
436  }
437 
443  public function isMain() {
444  return $this === $this->mMainModule;
445  }
446 
452  public function getParent() {
453  return $this->isMain() ? null : $this->getMain();
454  }
455 
466  public function lacksSameOriginSecurity() {
467  // Main module has this method overridden
468  // Safety - avoid infinite loop:
469  if ( $this->isMain() ) {
470  self::dieDebug( __METHOD__, 'base method was called on main module.' );
471  }
472 
473  return $this->getMain()->lacksSameOriginSecurity();
474  }
475 
482  public function getModulePath() {
483  if ( $this->isMain() ) {
484  return 'main';
485  } elseif ( $this->getParent()->isMain() ) {
486  return $this->getModuleName();
487  } else {
488  return $this->getParent()->getModulePath() . '+' . $this->getModuleName();
489  }
490  }
491 
500  public function getModuleFromPath( $path ) {
501  $module = $this->getMain();
502  if ( $path === 'main' ) {
503  return $module;
504  }
505 
506  $parts = explode( '+', $path );
507  if ( count( $parts ) === 1 ) {
508  // In case the '+' was typed into URL, it resolves as a space
509  $parts = explode( ' ', $path );
510  }
511 
512  $count = count( $parts );
513  for ( $i = 0; $i < $count; $i++ ) {
514  $parent = $module;
515  $manager = $parent->getModuleManager();
516  if ( $manager === null ) {
517  $errorPath = implode( '+', array_slice( $parts, 0, $i ) );
518  $this->dieWithError( [ 'apierror-badmodule-nosubmodules', $errorPath ], 'badmodule' );
519  }
520  $module = $manager->getModule( $parts[$i] );
521 
522  if ( $module === null ) {
523  $errorPath = $i ? implode( '+', array_slice( $parts, 0, $i ) ) : $parent->getModuleName();
524  $this->dieWithError(
525  [ 'apierror-badmodule-badsubmodule', $errorPath, wfEscapeWikiText( $parts[$i] ) ],
526  'badmodule'
527  );
528  }
529  }
530 
531  return $module;
532  }
533 
538  public function getResult() {
539  // Main module has getResult() method overridden
540  // Safety - avoid infinite loop:
541  if ( $this->isMain() ) {
542  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
543  }
544 
545  return $this->getMain()->getResult();
546  }
547 
552  public function getErrorFormatter() {
553  // Main module has getErrorFormatter() method overridden
554  // Safety - avoid infinite loop:
555  if ( $this->isMain() ) {
556  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
557  }
558 
559  return $this->getMain()->getErrorFormatter();
560  }
561 
566  protected function getDB() {
567  if ( !isset( $this->mReplicaDB ) ) {
568  $this->mReplicaDB = wfGetDB( DB_REPLICA, 'api' );
569  }
570 
571  return $this->mReplicaDB;
572  }
573 
578  public function getContinuationManager() {
579  // Main module has getContinuationManager() method overridden
580  // Safety - avoid infinite loop:
581  if ( $this->isMain() ) {
582  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
583  }
584 
585  return $this->getMain()->getContinuationManager();
586  }
587 
592  public function setContinuationManager( ApiContinuationManager $manager = null ) {
593  // Main module has setContinuationManager() method overridden
594  // Safety - avoid infinite loop:
595  if ( $this->isMain() ) {
596  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
597  }
598 
599  $this->getMain()->setContinuationManager( $manager );
600  }
601 
608  protected function getPermissionManager(): PermissionManager {
609  return MediaWikiServices::getInstance()->getPermissionManager();
610  }
611 
614  /************************************************************************/
626  public function dynamicParameterDocumentation() {
627  return null;
628  }
629 
637  public function encodeParamName( $paramName ) {
638  if ( is_array( $paramName ) ) {
639  return array_map( function ( $name ) {
640  return $this->mModulePrefix . $name;
641  }, $paramName );
642  } else {
643  return $this->mModulePrefix . $paramName;
644  }
645  }
646 
659  public function extractRequestParams( $options = [] ) {
660  if ( is_bool( $options ) ) {
661  $options = [ 'parseLimit' => $options ];
662  }
663  $options += [
664  'parseLimit' => true,
665  'safeMode' => false,
666  ];
667 
668  $parseLimit = (bool)$options['parseLimit'];
669  $cacheKey = (int)$parseLimit;
670 
671  // Cache parameters, for performance and to avoid T26564.
672  if ( !isset( $this->mParamCache[$cacheKey] ) ) {
673  $params = $this->getFinalParams() ?: [];
674  $results = [];
675  $warned = [];
676 
677  // Process all non-templates and save templates for secondary
678  // processing.
679  $toProcess = [];
680  foreach ( $params as $paramName => $paramSettings ) {
681  if ( isset( $paramSettings[self::PARAM_TEMPLATE_VARS] ) ) {
682  $toProcess[] = [ $paramName, $paramSettings[self::PARAM_TEMPLATE_VARS], $paramSettings ];
683  } else {
684  try {
685  $results[$paramName] = $this->getParameterFromSettings(
686  $paramName, $paramSettings, $parseLimit
687  );
688  } catch ( ApiUsageException $ex ) {
689  $results[$paramName] = $ex;
690  }
691  }
692  }
693 
694  // Now process all the templates by successively replacing the
695  // placeholders with all client-supplied values.
696  // This bit duplicates JavaScript logic in
697  // ApiSandbox.PageLayout.prototype.updateTemplatedParams().
698  // If you update this, see if that needs updating too.
699  while ( $toProcess ) {
700  list( $name, $targets, $settings ) = array_shift( $toProcess );
701 
702  foreach ( $targets as $placeholder => $target ) {
703  if ( !array_key_exists( $target, $results ) ) {
704  // The target wasn't processed yet, try the next one.
705  // If all hit this case, the parameter has no expansions.
706  continue;
707  }
708  if ( !is_array( $results[$target] ) || !$results[$target] ) {
709  // The target was processed but has no (valid) values.
710  // That means it has no expansions.
711  break;
712  }
713 
714  // Expand this target in the name and all other targets,
715  // then requeue if there are more targets left or put in
716  // $results if all are done.
717  unset( $targets[$placeholder] );
718  $placeholder = '{' . $placeholder . '}';
719  // @phan-suppress-next-line PhanTypeNoAccessiblePropertiesForeach
720  foreach ( $results[$target] as $value ) {
721  if ( !preg_match( '/^[^{}]*$/', $value ) ) {
722  // Skip values that make invalid parameter names.
723  $encTargetName = $this->encodeParamName( $target );
724  if ( !isset( $warned[$encTargetName][$value] ) ) {
725  $warned[$encTargetName][$value] = true;
726  $this->addWarning( [
727  'apiwarn-ignoring-invalid-templated-value',
728  wfEscapeWikiText( $encTargetName ),
729  wfEscapeWikiText( $value ),
730  ] );
731  }
732  continue;
733  }
734 
735  $newName = str_replace( $placeholder, $value, $name );
736  if ( !$targets ) {
737  try {
738  $results[$newName] = $this->getParameterFromSettings(
739  $newName,
740  $settings,
741  $parseLimit
742  );
743  } catch ( ApiUsageException $ex ) {
744  $results[$newName] = $ex;
745  }
746  } else {
747  $newTargets = [];
748  foreach ( $targets as $k => $v ) {
749  $newTargets[$k] = str_replace( $placeholder, $value, $v );
750  }
751  $toProcess[] = [ $newName, $newTargets, $settings ];
752  }
753  }
754  break;
755  }
756  }
757 
758  $this->mParamCache[$cacheKey] = $results;
759  }
760 
761  $ret = $this->mParamCache[$cacheKey];
762  if ( !$options['safeMode'] ) {
763  foreach ( $ret as $v ) {
764  if ( $v instanceof ApiUsageException ) {
765  throw $v;
766  }
767  }
768  }
769 
770  return $this->mParamCache[$cacheKey];
771  }
772 
779  protected function getParameter( $paramName, $parseLimit = true ) {
780  $ret = $this->extractRequestParams( [
781  'parseLimit' => $parseLimit,
782  'safeMode' => true,
783  ] )[$paramName];
784  if ( $ret instanceof ApiUsageException ) {
785  throw $ret;
786  }
787  return $ret;
788  }
789 
796  public function requireOnlyOneParameter( $params, ...$required ) {
797  $intersection = array_intersect( array_keys( array_filter( $params,
798  [ $this, 'parameterNotEmpty' ] ) ), $required );
799 
800  if ( count( $intersection ) > 1 ) {
801  $this->dieWithError( [
802  'apierror-invalidparammix',
803  Message::listParam( array_map(
804  function ( $p ) {
805  return '<var>' . $this->encodeParamName( $p ) . '</var>';
806  },
807  array_values( $intersection )
808  ) ),
809  count( $intersection ),
810  ] );
811  } elseif ( count( $intersection ) == 0 ) {
812  $this->dieWithError( [
813  'apierror-missingparam-one-of',
814  Message::listParam( array_map(
815  function ( $p ) {
816  return '<var>' . $this->encodeParamName( $p ) . '</var>';
817  },
818  $required
819  ) ),
820  count( $required ),
821  ], 'missingparam' );
822  }
823  }
824 
831  public function requireMaxOneParameter( $params, ...$required ) {
832  $intersection = array_intersect( array_keys( array_filter( $params,
833  [ $this, 'parameterNotEmpty' ] ) ), $required );
834 
835  if ( count( $intersection ) > 1 ) {
836  $this->dieWithError( [
837  'apierror-invalidparammix',
838  Message::listParam( array_map(
839  function ( $p ) {
840  return '<var>' . $this->encodeParamName( $p ) . '</var>';
841  },
842  array_values( $intersection )
843  ) ),
844  count( $intersection ),
845  ] );
846  }
847  }
848 
856  public function requireAtLeastOneParameter( $params, ...$required ) {
857  $intersection = array_intersect(
858  array_keys( array_filter( $params, [ $this, 'parameterNotEmpty' ] ) ),
859  $required
860  );
861 
862  if ( count( $intersection ) == 0 ) {
863  $this->dieWithError( [
864  'apierror-missingparam-at-least-one-of',
865  Message::listParam( array_map(
866  function ( $p ) {
867  return '<var>' . $this->encodeParamName( $p ) . '</var>';
868  },
869  $required
870  ) ),
871  count( $required ),
872  ], 'missingparam' );
873  }
874  }
875 
883  public function requirePostedParameters( $params, $prefix = 'prefix' ) {
884  // Skip if $wgDebugAPI is set or we're in internal mode
885  if ( $this->getConfig()->get( 'DebugAPI' ) || $this->getMain()->isInternalMode() ) {
886  return;
887  }
888 
889  $queryValues = $this->getRequest()->getQueryValuesOnly();
890  $badParams = [];
891  foreach ( $params as $param ) {
892  if ( $prefix !== 'noprefix' ) {
893  $param = $this->encodeParamName( $param );
894  }
895  if ( array_key_exists( $param, $queryValues ) ) {
896  $badParams[] = $param;
897  }
898  }
899 
900  if ( $badParams ) {
901  $this->dieWithError(
902  [ 'apierror-mustpostparams', implode( ', ', $badParams ), count( $badParams ) ]
903  );
904  }
905  }
906 
913  private function parameterNotEmpty( $x ) {
914  return $x !== null && $x !== false;
915  }
916 
928  public function getTitleOrPageId( $params, $load = false ) {
929  $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
930 
931  $pageObj = null;
932  if ( isset( $params['title'] ) ) {
933  $titleObj = Title::newFromText( $params['title'] );
934  if ( !$titleObj || $titleObj->isExternal() ) {
935  $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
936  }
937  if ( !$titleObj->canExist() ) {
938  $this->dieWithError( 'apierror-pagecannotexist' );
939  }
940  $pageObj = WikiPage::factory( $titleObj );
941  if ( $load !== false ) {
942  $pageObj->loadPageData( $load );
943  }
944  } elseif ( isset( $params['pageid'] ) ) {
945  if ( $load === false ) {
946  $load = 'fromdb';
947  }
948  $pageObj = WikiPage::newFromID( $params['pageid'], $load );
949  if ( !$pageObj ) {
950  $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
951  }
952  }
953 
954  return $pageObj;
955  }
956 
965  public function getTitleFromTitleOrPageId( $params ) {
966  $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
967 
968  $titleObj = null;
969  if ( isset( $params['title'] ) ) {
970  $titleObj = Title::newFromText( $params['title'] );
971  if ( !$titleObj || $titleObj->isExternal() ) {
972  $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
973  }
974  return $titleObj;
975  } elseif ( isset( $params['pageid'] ) ) {
976  $titleObj = Title::newFromID( $params['pageid'] );
977  if ( !$titleObj ) {
978  $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
979  }
980  }
981 
982  return $titleObj;
983  }
984 
993  protected function getWatchlistValue( $watchlist, $titleObj, $userOption = null ) {
994  $userWatching = $this->getUser()->isWatched( $titleObj, User::IGNORE_USER_RIGHTS );
995 
996  switch ( $watchlist ) {
997  case 'watch':
998  return true;
999 
1000  case 'unwatch':
1001  return false;
1002 
1003  case 'preferences':
1004  # If the user is already watching, don't bother checking
1005  if ( $userWatching ) {
1006  return true;
1007  }
1008  # If no user option was passed, use watchdefault and watchcreations
1009  if ( $userOption === null ) {
1010  return $this->getUser()->getBoolOption( 'watchdefault' ) ||
1011  $this->getUser()->getBoolOption( 'watchcreations' ) && !$titleObj->exists();
1012  }
1013 
1014  # Watch the article based on the user preference
1015  return $this->getUser()->getBoolOption( $userOption );
1016 
1017  case 'nochange':
1018  return $userWatching;
1019 
1020  default:
1021  return $userWatching;
1022  }
1023  }
1024 
1034  protected function getParameterFromSettings( $name, $settings, $parseLimit ) {
1035  $validator = $this->getMain()->getParamValidator();
1036  $value = $validator->getValue( $this, $name, $settings, [
1037  'parse-limit' => $parseLimit,
1038  ] );
1039 
1040  // @todo Deprecate and remove this, if possible.
1041  if ( $parseLimit && isset( $settings[ParamValidator::PARAM_TYPE] ) &&
1042  $settings[ParamValidator::PARAM_TYPE] === 'limit' &&
1043  $this->getMain()->getVal( $this->encodeParamName( $name ) ) === 'max'
1044  ) {
1045  $this->getResult()->addParsedLimit( $this->getModuleName(), $value );
1046  }
1047 
1048  return $value;
1049  }
1050 
1060  public function handleParamNormalization( $paramName, $value, $rawValue ) {
1061  $this->addWarning( [ 'apiwarn-badutf8', $paramName ] );
1062  }
1063 
1073  final public function validateToken( $token, array $params ) {
1074  $tokenType = $this->needsToken();
1076  if ( !isset( $salts[$tokenType] ) ) {
1077  throw new MWException(
1078  "Module '{$this->getModuleName()}' tried to use token type '$tokenType' " .
1079  'without registering it'
1080  );
1081  }
1082 
1083  $tokenObj = ApiQueryTokens::getToken(
1084  $this->getUser(), $this->getRequest()->getSession(), $salts[$tokenType]
1085  );
1086  if ( $tokenObj->match( $token ) ) {
1087  return true;
1088  }
1089 
1090  $webUiSalt = $this->getWebUITokenSalt( $params );
1091  if ( $webUiSalt !== null && $this->getUser()->matchEditToken(
1092  $token,
1093  $webUiSalt,
1094  $this->getRequest()
1095  ) ) {
1096  return true;
1097  }
1098 
1099  return false;
1100  }
1101 
1104  /************************************************************************/
1115  protected function setWatch( $watch, $titleObj, $userOption = null ) {
1116  $value = $this->getWatchlistValue( $watch, $titleObj, $userOption );
1117  if ( $value === null ) {
1118  return;
1119  }
1120 
1121  WatchAction::doWatchOrUnwatch( $value, $titleObj, $this->getUser() );
1122  }
1123 
1130  public function getWatchlistUser( $params ) {
1131  if ( $params['owner'] !== null && $params['token'] !== null ) {
1132  $user = User::newFromName( $params['owner'], false );
1133  if ( !( $user && $user->getId() ) ) {
1134  $this->dieWithError(
1135  [ 'nosuchusershort', wfEscapeWikiText( $params['owner'] ) ], 'bad_wlowner'
1136  );
1137  }
1138  $token = $user->getOption( 'watchlisttoken' );
1139  if ( $token == '' || !hash_equals( $token, $params['token'] ) ) {
1140  $this->dieWithError( 'apierror-bad-watchlist-token', 'bad_wltoken' );
1141  }
1142  } else {
1143  if ( !$this->getUser()->isLoggedIn() ) {
1144  $this->dieWithError( 'watchlistanontext', 'notloggedin' );
1145  }
1146  $this->checkUserRightsAny( 'viewmywatchlist' );
1147  $user = $this->getUser();
1148  }
1149 
1150  return $user;
1151  }
1152 
1165  public static function makeMessage( $msg, IContextSource $context, array $params = null ) {
1166  if ( is_string( $msg ) ) {
1167  $msg = wfMessage( $msg );
1168  } elseif ( is_array( $msg ) ) {
1169  $msg = wfMessage( ...$msg );
1170  }
1171  if ( !$msg instanceof Message ) {
1172  return null;
1173  }
1174 
1175  $msg->setContext( $context );
1176  if ( $params ) {
1177  $msg->params( $params );
1178  }
1179 
1180  return $msg;
1181  }
1182 
1190  public function errorArrayToStatus( array $errors, User $user = null ) {
1191  if ( $user === null ) {
1192  $user = $this->getUser();
1193  }
1194 
1195  $status = Status::newGood();
1196  foreach ( $errors as $error ) {
1197  if ( !is_array( $error ) ) {
1198  $error = [ $error ];
1199  }
1200  if ( is_string( $error[0] ) && isset( self::$blockMsgMap[$error[0]] ) && $user->getBlock() ) {
1201  list( $msg, $code ) = self::$blockMsgMap[$error[0]];
1202  $status->fatal( ApiMessage::create( $msg, $code,
1203  [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ]
1204  ) );
1205  } else {
1206  $status->fatal( ...$error );
1207  }
1208  }
1209  return $status;
1210  }
1211 
1218  public function addBlockInfoToStatus( StatusValue $status, User $user = null ) {
1219  if ( $user === null ) {
1220  $user = $this->getUser();
1221  }
1222 
1223  foreach ( self::$blockMsgMap as $msg => list( $apiMsg, $code ) ) {
1224  if ( $status->hasMessage( $msg ) && $user->getBlock() ) {
1225  $status->replaceMessage( $msg, ApiMessage::create( $apiMsg, $code,
1226  [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ]
1227  ) );
1228  }
1229  }
1230  }
1231 
1236  protected function useTransactionalTimeLimit() {
1237  if ( $this->getRequest()->wasPosted() ) {
1239  }
1240  }
1241 
1250  protected function filterIDs( $fields, array $ids ) {
1251  $min = INF;
1252  $max = 0;
1253  foreach ( $fields as list( $table, $field ) ) {
1254  if ( isset( self::$filterIDsCache[$table][$field] ) ) {
1255  $row = self::$filterIDsCache[$table][$field];
1256  } else {
1257  $row = $this->getDB()->selectRow(
1258  $table,
1259  [
1260  'min_id' => "MIN($field)",
1261  'max_id' => "MAX($field)",
1262  ],
1263  '',
1264  __METHOD__
1265  );
1266  self::$filterIDsCache[$table][$field] = $row;
1267  }
1268  $min = min( $min, $row->min_id );
1269  $max = max( $max, $row->max_id );
1270  }
1271  return array_filter( $ids, function ( $id ) use ( $min, $max ) {
1272  return ( is_int( $id ) && $id >= 0 || ctype_digit( $id ) )
1273  && $id >= $min && $id <= $max;
1274  } );
1275  }
1276 
1279  /************************************************************************/
1298  public function addWarning( $msg, $code = null, $data = null ) {
1299  $this->getErrorFormatter()->addWarning( $this->getModulePath(), $msg, $code, $data );
1300  }
1301 
1312  public function addDeprecation( $msg, $feature, $data = [] ) {
1313  $data = (array)$data;
1314  if ( $feature !== null ) {
1315  $data['feature'] = $feature;
1316  $this->logFeatureUsage( $feature );
1317  }
1318  $this->addWarning( $msg, 'deprecation', $data );
1319 
1320  // No real need to deduplicate here, ApiErrorFormatter does that for
1321  // us (assuming the hook is deterministic).
1322  $msgs = [ $this->msg( 'api-usage-mailinglist-ref' ) ];
1323  Hooks::run( 'ApiDeprecationHelp', [ &$msgs ] );
1324  if ( count( $msgs ) > 1 ) {
1325  $key = '$' . implode( ' $', range( 1, count( $msgs ) ) );
1326  $msg = ( new RawMessage( $key ) )->params( $msgs );
1327  } else {
1328  $msg = reset( $msgs );
1329  }
1330  $this->getMain()->addWarning( $msg, 'deprecation-help' );
1331  }
1332 
1345  public function addError( $msg, $code = null, $data = null ) {
1346  $this->getErrorFormatter()->addError( $this->getModulePath(), $msg, $code, $data );
1347  }
1348 
1358  public function addMessagesFromStatus(
1359  StatusValue $status, $types = [ 'warning', 'error' ], array $filter = []
1360  ) {
1361  $this->getErrorFormatter()->addMessagesFromStatus(
1362  $this->getModulePath(), $status, $types, $filter
1363  );
1364  }
1365 
1379  public function dieWithError( $msg, $code = null, $data = null, $httpCode = null ) {
1380  throw ApiUsageException::newWithMessage( $this, $msg, $code, $data, $httpCode );
1381  }
1382 
1391  public function dieWithException( Throwable $exception, array $options = [] ) {
1392  $this->dieWithError(
1393  // @phan-suppress-next-line PhanTypeMismatchArgument
1394  $this->getErrorFormatter()->getMessageFromException( $exception, $options )
1395  );
1396  }
1397 
1406  public function dieBlocked( AbstractBlock $block ) {
1407  // Die using the appropriate message depending on block type
1408  if ( $block->getType() == DatabaseBlock::TYPE_AUTO ) {
1409  $this->dieWithError(
1410  'apierror-autoblocked',
1411  'autoblocked',
1412  [ 'blockinfo' => $this->getBlockDetails( $block ) ]
1413  );
1414  } elseif ( !$block->isSitewide() ) {
1415  $this->dieWithError(
1416  'apierror-blocked-partial',
1417  'blocked',
1418  [ 'blockinfo' => $this->getBlockDetails( $block ) ]
1419  );
1420  } else {
1421  $this->dieWithError(
1422  'apierror-blocked',
1423  'blocked',
1424  [ 'blockinfo' => $this->getBlockDetails( $block ) ]
1425  );
1426  }
1427  }
1428 
1437  public function dieStatus( StatusValue $status ) {
1438  if ( $status->isGood() ) {
1439  throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
1440  }
1441 
1442  // ApiUsageException needs a fatal status, but this method has
1443  // historically accepted any non-good status. Convert it if necessary.
1444  $status->setOK( false );
1445  if ( !$status->getErrorsByType( 'error' ) ) {
1446  $newStatus = Status::newGood();
1447  foreach ( $status->getErrorsByType( 'warning' ) as $err ) {
1448  $newStatus->fatal( $err['message'], ...$err['params'] );
1449  }
1450  if ( !$newStatus->getErrorsByType( 'error' ) ) {
1451  $newStatus->fatal( 'unknownerror-nocode' );
1452  }
1453  $status = $newStatus;
1454  }
1455 
1456  $this->addBlockInfoToStatus( $status );
1457  throw new ApiUsageException( $this, $status );
1458  }
1459 
1465  public function dieReadOnly() {
1466  $this->dieWithError(
1467  'apierror-readonly',
1468  'readonly',
1469  [ 'readonlyreason' => wfReadOnlyReason() ]
1470  );
1471  }
1472 
1481  public function checkUserRightsAny( $rights, $user = null ) {
1482  if ( !$user ) {
1483  $user = $this->getUser();
1484  }
1485  $rights = (array)$rights;
1486  if ( !$this->getPermissionManager()
1487  ->userHasAnyRight( $user, ...$rights )
1488  ) {
1489  $this->dieWithError( [ 'apierror-permissiondenied', $this->msg( "action-{$rights[0]}" ) ] );
1490  }
1491  }
1492 
1506  public function checkTitleUserPermissions(
1507  LinkTarget $linkTarget,
1508  $actions,
1509  array $options = []
1510  ) {
1511  $user = $options['user'] ?? $this->getUser();
1512 
1513  $errors = [];
1514  foreach ( (array)$actions as $action ) {
1515  $errors = array_merge(
1516  $errors,
1517  $this->getPermissionManager()->getPermissionErrors( $action, $user, $linkTarget )
1518  );
1519  }
1520 
1521  if ( $errors ) {
1522  if ( !empty( $options['autoblock'] ) ) {
1523  $user->spreadAnyEditBlock();
1524  }
1525 
1526  $this->dieStatus( $this->errorArrayToStatus( $errors, $user ) );
1527  }
1528  }
1529 
1541  public function dieWithErrorOrDebug( $msg, $code = null, $data = null, $httpCode = null ) {
1542  if ( $this->getConfig()->get( 'DebugAPI' ) !== true ) {
1543  $this->dieWithError( $msg, $code, $data, $httpCode );
1544  } else {
1545  $this->addWarning( $msg, $code, $data );
1546  }
1547  }
1548 
1559  protected function dieContinueUsageIf( $condition ) {
1560  if ( $condition ) {
1561  $this->dieWithError( 'apierror-badcontinue' );
1562  }
1563  }
1564 
1571  protected static function dieDebug( $method, $message ) {
1572  throw new MWException( "Internal error in $method: $message" );
1573  }
1574 
1581  public function logFeatureUsage( $feature ) {
1582  static $loggedFeatures = [];
1583 
1584  // Only log each feature once per request. We can get multiple calls from calls to
1585  // extractRequestParams() with different values for 'parseLimit', for example.
1586  if ( isset( $loggedFeatures[$feature] ) ) {
1587  return;
1588  }
1589  $loggedFeatures[$feature] = true;
1590 
1591  $request = $this->getRequest();
1592  $ctx = [
1593  'feature' => $feature,
1594  // Spaces to underscores in 'username' for historical reasons.
1595  'username' => str_replace( ' ', '_', $this->getUser()->getName() ),
1596  'clientip' => $request->getIP(),
1597  'referer' => (string)$request->getHeader( 'Referer' ),
1598  'agent' => $this->getMain()->getUserAgent(),
1599  ];
1600 
1601  // Text string is deprecated. Remove (or replace with just $feature) in MW 1.34.
1602  $s = '"' . addslashes( $ctx['feature'] ) . '"' .
1603  ' "' . wfUrlencode( $ctx['username'] ) . '"' .
1604  ' "' . $ctx['clientip'] . '"' .
1605  ' "' . addslashes( $ctx['referer'] ) . '"' .
1606  ' "' . addslashes( $ctx['agent'] ) . '"';
1607 
1608  wfDebugLog( 'api-feature-usage', $s, 'private', $ctx );
1609  }
1610 
1613  /************************************************************************/
1627  protected function getSummaryMessage() {
1628  return "apihelp-{$this->getModulePath()}-summary";
1629  }
1630 
1640  protected function getExtendedDescription() {
1641  return [ [
1642  "apihelp-{$this->getModulePath()}-extended-description",
1643  'api-help-no-extended-description',
1644  ] ];
1645  }
1646 
1653  public function getFinalSummary() {
1654  $msg = self::makeMessage( $this->getSummaryMessage(), $this->getContext(), [
1655  $this->getModulePrefix(),
1656  $this->getModuleName(),
1657  $this->getModulePath(),
1658  ] );
1659  return $msg;
1660  }
1661 
1669  public function getFinalDescription() {
1670  $summary = self::makeMessage( $this->getSummaryMessage(), $this->getContext(), [
1671  $this->getModulePrefix(),
1672  $this->getModuleName(),
1673  $this->getModulePath(),
1674  ] );
1675  $extendedDescription = self::makeMessage(
1676  $this->getExtendedDescription(), $this->getContext(), [
1677  $this->getModulePrefix(),
1678  $this->getModuleName(),
1679  $this->getModulePath(),
1680  ]
1681  );
1682 
1683  $msgs = [ $summary, $extendedDescription ];
1684 
1685  Hooks::run( 'APIGetDescriptionMessages', [ $this, &$msgs ] );
1686 
1687  return $msgs;
1688  }
1689 
1698  public function getFinalParams( $flags = 0 ) {
1699  // @phan-suppress-next-line PhanParamTooMany
1700  $params = $this->getAllowedParams( $flags );
1701  if ( !$params ) {
1702  $params = [];
1703  }
1704 
1705  if ( $this->needsToken() ) {
1706  $params['token'] = [
1707  self::PARAM_TYPE => 'string',
1708  self::PARAM_REQUIRED => true,
1709  self::PARAM_SENSITIVE => true,
1710  self::PARAM_HELP_MSG => [
1711  'api-help-param-token',
1712  $this->needsToken(),
1713  ],
1714  ] + ( $params['token'] ?? [] );
1715  }
1716 
1717  // Avoid PHP 7.1 warning of passing $this by reference
1718  $apiModule = $this;
1719  Hooks::run( 'APIGetAllowedParams', [ &$apiModule, &$params, $flags ] );
1720 
1721  return $params;
1722  }
1723 
1731  public function getFinalParamDescription() {
1732  $prefix = $this->getModulePrefix();
1733  $name = $this->getModuleName();
1734  $path = $this->getModulePath();
1735 
1736  $params = $this->getFinalParams( self::GET_VALUES_FOR_HELP );
1737  $msgs = [];
1738  foreach ( $params as $param => $settings ) {
1739  if ( !is_array( $settings ) ) {
1740  $settings = [];
1741  }
1742 
1743  if ( isset( $settings[self::PARAM_HELP_MSG] ) ) {
1744  $msg = $settings[self::PARAM_HELP_MSG];
1745  } else {
1746  $msg = $this->msg( "apihelp-{$path}-param-{$param}" );
1747  }
1748  $msg = self::makeMessage( $msg, $this->getContext(),
1749  [ $prefix, $param, $name, $path ] );
1750  if ( !$msg ) {
1751  self::dieDebug( __METHOD__,
1752  'Value in ApiBase::PARAM_HELP_MSG is not valid' );
1753  }
1754  $msgs[$param] = [ $msg ];
1755 
1756  if ( isset( $settings[self::PARAM_TYPE] ) &&
1757  $settings[self::PARAM_TYPE] === 'submodule'
1758  ) {
1759  if ( isset( $settings[self::PARAM_SUBMODULE_MAP] ) ) {
1760  $map = $settings[self::PARAM_SUBMODULE_MAP];
1761  } else {
1762  $prefix = $this->isMain() ? '' : ( $this->getModulePath() . '+' );
1763  $map = [];
1764  foreach ( $this->getModuleManager()->getNames( $param ) as $submoduleName ) {
1765  $map[$submoduleName] = $prefix . $submoduleName;
1766  }
1767  }
1768 
1769  $submodules = [];
1770  $submoduleFlags = []; // for sorting: higher flags are sorted later
1771  $submoduleNames = []; // for sorting: lexicographical, ascending
1772  foreach ( $map as $v => $m ) {
1773  $isDeprecated = false;
1774  $isInternal = false;
1775  $summary = null;
1776  try {
1777  $submod = $this->getModuleFromPath( $m );
1778  if ( $submod ) {
1779  $summary = $submod->getFinalSummary();
1780  $isDeprecated = $submod->isDeprecated();
1781  $isInternal = $submod->isInternal();
1782  }
1783  } catch ( ApiUsageException $ex ) {
1784  // Ignore
1785  }
1786  if ( $summary ) {
1787  $key = $summary->getKey();
1788  $params = $summary->getParams();
1789  } else {
1790  $key = 'api-help-undocumented-module';
1791  $params = [ $m ];
1792  }
1793  $m = new ApiHelpParamValueMessage(
1794  "[[Special:ApiHelp/$m|$v]]",
1795  $key,
1796  $params,
1797  $isDeprecated,
1798  $isInternal
1799  );
1800  $submodules[] = $m->setContext( $this->getContext() );
1801  $submoduleFlags[] = ( $isDeprecated ? 1 : 0 ) | ( $isInternal ? 2 : 0 );
1802  $submoduleNames[] = $v;
1803  }
1804  // sort $submodules by $submoduleFlags and $submoduleNames
1805  array_multisort( $submoduleFlags, $submoduleNames, $submodules );
1806  $msgs[$param] = array_merge( $msgs[$param], $submodules );
1807  } elseif ( isset( $settings[self::PARAM_HELP_MSG_PER_VALUE] ) ) {
1808  if ( !is_array( $settings[self::PARAM_HELP_MSG_PER_VALUE] ) ) {
1809  self::dieDebug( __METHOD__,
1810  'ApiBase::PARAM_HELP_MSG_PER_VALUE is not valid' );
1811  }
1812  if ( !is_array( $settings[self::PARAM_TYPE] ) ) {
1813  self::dieDebug( __METHOD__,
1814  'ApiBase::PARAM_HELP_MSG_PER_VALUE may only be used when ' .
1815  'ApiBase::PARAM_TYPE is an array' );
1816  }
1817 
1818  $valueMsgs = $settings[self::PARAM_HELP_MSG_PER_VALUE];
1819  $deprecatedValues = $settings[self::PARAM_DEPRECATED_VALUES] ?? [];
1820 
1821  foreach ( $settings[self::PARAM_TYPE] as $value ) {
1822  if ( isset( $valueMsgs[$value] ) ) {
1823  $msg = $valueMsgs[$value];
1824  } else {
1825  $msg = "apihelp-{$path}-paramvalue-{$param}-{$value}";
1826  }
1827  $m = self::makeMessage( $msg, $this->getContext(),
1828  [ $prefix, $param, $name, $path, $value ] );
1829  if ( $m ) {
1830  $m = new ApiHelpParamValueMessage(
1831  $value,
1832  // @phan-suppress-next-line PhanTypeMismatchArgument
1833  [ $m->getKey(), 'api-help-param-no-description' ],
1834  $m->getParams(),
1835  isset( $deprecatedValues[$value] )
1836  );
1837  $msgs[$param][] = $m->setContext( $this->getContext() );
1838  } else {
1839  self::dieDebug( __METHOD__,
1840  "Value in ApiBase::PARAM_HELP_MSG_PER_VALUE for $value is not valid" );
1841  }
1842  }
1843  }
1844 
1845  if ( isset( $settings[self::PARAM_HELP_MSG_APPEND] ) ) {
1846  if ( !is_array( $settings[self::PARAM_HELP_MSG_APPEND] ) ) {
1847  self::dieDebug( __METHOD__,
1848  'Value for ApiBase::PARAM_HELP_MSG_APPEND is not an array' );
1849  }
1850  foreach ( $settings[self::PARAM_HELP_MSG_APPEND] as $m ) {
1851  $m = self::makeMessage( $m, $this->getContext(),
1852  [ $prefix, $param, $name, $path ] );
1853  if ( $m ) {
1854  $msgs[$param][] = $m;
1855  } else {
1856  self::dieDebug( __METHOD__,
1857  'Value in ApiBase::PARAM_HELP_MSG_APPEND is not valid' );
1858  }
1859  }
1860  }
1861  }
1862 
1863  Hooks::run( 'APIGetParamDescriptionMessages', [ $this, &$msgs ] );
1864 
1865  return $msgs;
1866  }
1867 
1877  protected function getHelpFlags() {
1878  $flags = [];
1879 
1880  if ( $this->isDeprecated() ) {
1881  $flags[] = 'deprecated';
1882  }
1883  if ( $this->isInternal() ) {
1884  $flags[] = 'internal';
1885  }
1886  if ( $this->isReadMode() ) {
1887  $flags[] = 'readrights';
1888  }
1889  if ( $this->isWriteMode() ) {
1890  $flags[] = 'writerights';
1891  }
1892  if ( $this->mustBePosted() ) {
1893  $flags[] = 'mustbeposted';
1894  }
1895 
1896  return $flags;
1897  }
1898 
1910  protected function getModuleSourceInfo() {
1911  global $IP;
1912 
1913  if ( $this->mModuleSource !== false ) {
1914  return $this->mModuleSource;
1915  }
1916 
1917  // First, try to find where the module comes from...
1918  $rClass = new ReflectionClass( $this );
1919  $path = $rClass->getFileName();
1920  if ( !$path ) {
1921  // No path known?
1922  $this->mModuleSource = null;
1923  return null;
1924  }
1925  $path = realpath( $path ) ?: $path;
1926 
1927  // Build map of extension directories to extension info
1928  if ( self::$extensionInfo === null ) {
1929  $extDir = $this->getConfig()->get( 'ExtensionDirectory' );
1930  self::$extensionInfo = [
1931  realpath( __DIR__ ) ?: __DIR__ => [
1932  'path' => $IP,
1933  'name' => 'MediaWiki',
1934  'license-name' => 'GPL-2.0-or-later',
1935  ],
1936  realpath( "$IP/extensions" ) ?: "$IP/extensions" => null,
1937  realpath( $extDir ) ?: $extDir => null,
1938  ];
1939  $keep = [
1940  'path' => null,
1941  'name' => null,
1942  'namemsg' => null,
1943  'license-name' => null,
1944  ];
1945  foreach ( $this->getConfig()->get( 'ExtensionCredits' ) as $group ) {
1946  foreach ( $group as $ext ) {
1947  if ( !isset( $ext['path'] ) || !isset( $ext['name'] ) ) {
1948  // This shouldn't happen, but does anyway.
1949  continue;
1950  }
1951 
1952  $extpath = $ext['path'];
1953  if ( !is_dir( $extpath ) ) {
1954  $extpath = dirname( $extpath );
1955  }
1956  self::$extensionInfo[realpath( $extpath ) ?: $extpath] =
1957  array_intersect_key( $ext, $keep );
1958  }
1959  }
1960  foreach ( ExtensionRegistry::getInstance()->getAllThings() as $ext ) {
1961  $extpath = $ext['path'];
1962  if ( !is_dir( $extpath ) ) {
1963  $extpath = dirname( $extpath );
1964  }
1965  self::$extensionInfo[realpath( $extpath ) ?: $extpath] =
1966  array_intersect_key( $ext, $keep );
1967  }
1968  }
1969 
1970  // Now traverse parent directories until we find a match or run out of
1971  // parents.
1972  do {
1973  if ( array_key_exists( $path, self::$extensionInfo ) ) {
1974  // Found it!
1975  $this->mModuleSource = self::$extensionInfo[$path];
1976  return $this->mModuleSource;
1977  }
1978 
1979  $oldpath = $path;
1980  $path = dirname( $path );
1981  } while ( $path !== $oldpath );
1982 
1983  // No idea what extension this might be.
1984  $this->mModuleSource = null;
1985  return null;
1986  }
1987 
1999  public function modifyHelp( array &$help, array $options, array &$tocData ) {
2000  }
2001 
2004  /************************************************************************/
2017  protected function explodeMultiValue( $value, $limit ) {
2018  wfDeprecated( __METHOD__, '1.35' );
2019  return ParamValidator::explodeMultiValue( $value, $limit );
2020  }
2021 
2040  protected function parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues,
2041  $allSpecifier = null, $limit1 = null, $limit2 = null
2042  ) {
2043  wfDeprecated( __METHOD__, '1.35' );
2044 
2045  if ( ( $value === '' || $value === "\x1f" ) && $allowMultiple ) {
2046  return [];
2047  }
2048  $limit1 = $limit1 ?: self::LIMIT_SML1;
2049  $limit2 = $limit2 ?: self::LIMIT_SML2;
2050 
2051  // This is a bit awkward, but we want to avoid calling canApiHighLimits()
2052  // because it unstubs $wgUser
2053  $valuesList = $this->explodeMultiValue( $value, $limit2 + 1 );
2054  $sizeLimit = count( $valuesList ) > $limit1 && $this->mMainModule->canApiHighLimits()
2055  ? $limit2
2056  : $limit1;
2057 
2058  if ( $allowMultiple && is_array( $allowedValues ) && $allSpecifier &&
2059  count( $valuesList ) === 1 && $valuesList[0] === $allSpecifier
2060  ) {
2061  return $allowedValues;
2062  }
2063 
2064  if ( count( $valuesList ) > $sizeLimit ) {
2065  $this->dieWithError(
2066  [ 'apierror-toomanyvalues', $valueName, $sizeLimit ],
2067  "too-many-$valueName"
2068  );
2069  }
2070 
2071  if ( !$allowMultiple && count( $valuesList ) != 1 ) {
2072  // T35482 - Allow entries with | in them for non-multiple values
2073  if ( in_array( $value, $allowedValues, true ) ) {
2074  return $value;
2075  }
2076 
2077  $values = array_map( function ( $v ) {
2078  return '<kbd>' . wfEscapeWikiText( $v ) . '</kbd>';
2079  }, $allowedValues );
2080  $this->dieWithError( [
2081  'apierror-multival-only-one-of',
2082  $valueName,
2083  Message::listParam( $values ),
2084  count( $values ),
2085  ], "multival_$valueName" );
2086  }
2087 
2088  if ( is_array( $allowedValues ) ) {
2089  // Check for unknown values
2090  $unknown = array_map( 'wfEscapeWikiText', array_diff( $valuesList, $allowedValues ) );
2091  if ( count( $unknown ) ) {
2092  if ( $allowMultiple ) {
2093  $this->addWarning( [
2094  'apiwarn-unrecognizedvalues',
2095  $valueName,
2096  Message::listParam( $unknown, 'comma' ),
2097  count( $unknown ),
2098  ] );
2099  } else {
2100  $this->dieWithError(
2101  [ 'apierror-unrecognizedvalue', $valueName, wfEscapeWikiText( $valuesList[0] ) ],
2102  "unknown_$valueName"
2103  );
2104  }
2105  }
2106  // Now throw them out
2107  $valuesList = array_intersect( $valuesList, $allowedValues );
2108  }
2109 
2110  return $allowMultiple ? $valuesList : $valuesList[0];
2111  }
2112 
2124  protected function validateLimit( $name, &$value, $min, $max, $botMax = null,
2125  $enforceLimits = false
2126  ) {
2127  wfDeprecated( __METHOD__, '1.35' );
2128  $value = $this->getMain()->getParamValidator()->validateValue(
2129  $this, $name, $value, [
2130  ParamValidator::PARAM_TYPE => 'limit',
2131  IntegerDef::PARAM_MIN => $min,
2132  IntegerDef::PARAM_MAX => $max,
2133  IntegerDef::PARAM_MAX2 => $botMax,
2134  IntegerDef::PARAM_IGNORE_RANGE => !$enforceLimits,
2135  ]
2136  );
2137  }
2138 
2146  protected function validateTimestamp( $value, $encParamName ) {
2147  wfDeprecated( __METHOD__, '1.35' );
2148 
2149  // Sigh.
2150  $name = $encParamName;
2151  $p = (string)$this->getModulePrefix();
2152  $l = strlen( $p );
2153  if ( $l && substr( $name, 0, $l ) === $p ) {
2154  $name = substr( $name, $l );
2155  }
2156 
2157  return $this->getMain()->getParamValidator()->validateValue(
2158  $this, $name, $value, [
2159  ParamValidator::PARAM_TYPE => 'timestamp',
2160  ]
2161  );
2162  }
2163 
2166 }
2167 
ApiMain
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:44
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:33
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:63
ApiBase\PARAM_SUBMODULE_MAP
const PARAM_SUBMODULE_MAP
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:67
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:332
ApiUsageException
Exception used to abort API execution with an error.
Definition: ApiUsageException.php:28
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:40
ApiBase\$mMainModule
ApiMain $mMainModule
Definition: ApiBase.php:185
StatusValue
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: StatusValue.php:42
ApiBase\getParent
getParent()
Get the parent of this module.
Definition: ApiBase.php:452
ApiBase\addWarning
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition: ApiBase.php:1298
ApiBase\getSummaryMessage
getSummaryMessage()
Return the summary message.
Definition: ApiBase.php:1627
ApiUsageException\newWithMessage
static newWithMessage(?ApiBase $module, $msg, $code=null, $data=null, $httpCode=0, Throwable $previous=null)
Definition: ApiUsageException.php:65
ApiBase\getFinalParams
getFinalParams( $flags=0)
Get final list of parameters, after hooks have had a chance to tweak it as needed.
Definition: ApiBase.php:1698
ApiBase\PARAM_REQUIRED
const PARAM_REQUIRED
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:66
StatusValue\getErrorsByType
getErrorsByType( $type)
Returns a list of status messages of the given type.
Definition: StatusValue.php:243
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:137
ApiBase\parameterNotEmpty
parameterNotEmpty( $x)
Callback function used in requireOnlyOneParameter to check whether required parameters are set.
Definition: ApiBase.php:913
ApiBase\$mModuleSource
array null bool $mModuleSource
Definition: ApiBase.php:194
ApiBase\validateToken
validateToken( $token, array $params)
Validate the supplied token.
Definition: ApiBase.php:1073
ApiContinuationManager
This manages continuation state.
Definition: ApiContinuationManager.php:26
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1379
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:96
ApiBase\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiBase.php:267
StatusValue\replaceMessage
replaceMessage( $source, $dest)
If the specified source message exists, replace it with the specified destination message,...
Definition: StatusValue.php:289
ApiBase\PARAM_ALL
const PARAM_ALL
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:69
ApiBase\validateTimestamp
validateTimestamp( $value, $encParamName)
Validate and normalize parameters of type 'timestamp'.
Definition: ApiBase.php:2146
ApiBase\$extensionInfo
static array $extensionInfo
Maps extension paths to info arrays.
Definition: ApiBase.php:170
ApiBase\getTitleOrPageId
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition: ApiBase.php:928
ApiBase\PARAM_TYPE
const PARAM_TYPE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:60
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:538
ApiBase\__construct
__construct(ApiMain $mainModule, $moduleName, $modulePrefix='')
Definition: ApiBase.php:201
ApiBase\getParameterFromSettings
getParameterFromSettings( $name, $settings, $parseLimit)
Using the settings determine the value for the given parameter.
Definition: ApiBase.php:1034
ApiBase\$blockMsgMap
static $blockMsgMap
$var array Map of web UI block messages to corresponding API messages and codes
Definition: ApiBase.php:176
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:309
ApiBase\mustBePosted
mustBePosted()
Indicates whether this module must be called with a POST request.
Definition: ApiBase.php:333
ApiBase\logFeatureUsage
logFeatureUsage( $feature)
Write logging information for API features to a debug log, for usage analysis.
Definition: ApiBase.php:1581
ApiBase\checkUserRightsAny
checkUserRightsAny( $rights, $user=null)
Helper function for permission-denied errors.
Definition: ApiBase.php:1481
ApiBase\shouldCheckMaxlag
shouldCheckMaxlag()
Indicates if this module needs maxlag to be checked.
Definition: ApiBase.php:302
ApiBase\dieWithErrorOrDebug
dieWithErrorOrDebug( $msg, $code=null, $data=null, $httpCode=null)
Will only set a warning instead of failing if the global $wgDebugAPI is set to true.
Definition: ApiBase.php:1541
ApiBase\setContinuationManager
setContinuationManager(ApiContinuationManager $manager=null)
Set the continuation manager.
Definition: ApiBase.php:592
Wikimedia\ParamValidator\TypeDef\EnumDef
Type definition for enumeration types.
Definition: EnumDef.php:32
ApiBase\getExtendedDescription
getExtendedDescription()
Return the extended help text message.
Definition: ApiBase.php:1640
ApiBase\PARAM_ISMULTI_LIMIT1
const PARAM_ISMULTI_LIMIT1
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:73
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:535
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1201
ApiBase\addBlockInfoToStatus
addBlockInfoToStatus(StatusValue $status, User $user=null)
Add block info to block messages in a Status.
Definition: ApiBase.php:1218
$s
$s
Definition: mergeMessageFileList.php:185
ApiBase\dieBlocked
dieBlocked(AbstractBlock $block)
Throw an ApiUsageException, which will (if uncaught) call the main module's error handler and die wit...
Definition: ApiBase.php:1406
ApiBase\getDB
getDB()
Gets a default replica DB connection object.
Definition: ApiBase.php:566
ApiBase\addMessagesFromStatus
addMessagesFromStatus(StatusValue $status, $types=[ 'warning', 'error'], array $filter=[])
Add warnings and/or errors from a Status.
Definition: ApiBase.php:1358
ApiBase\makeMessage
static makeMessage( $msg, IContextSource $context, array $params=null)
Create a Message from a string or array.
Definition: ApiBase.php:1165
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:71
ApiBase\dynamicParameterDocumentation
dynamicParameterDocumentation()
Indicate if the module supports dynamically-determined parameters that cannot be included in self::ge...
Definition: ApiBase.php:626
ApiBase\modifyHelp
modifyHelp(array &$help, array $options, array &$tocData)
Called from ApiHelp before the pieces are joined together and returned.
Definition: ApiBase.php:1999
ApiBase\PARAM_ALLOW_DUPLICATES
const PARAM_ALLOW_DUPLICATES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:64
Message
ContextSource\getUser
getUser()
Definition: ContextSource.php:120
StatusValue\setOK
setOK( $ok)
Change operation status.
Definition: StatusValue.php:157
ApiBase\PARAM_DEPRECATED_VALUES
const PARAM_DEPRECATED_VALUES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:72
ApiBase\lacksSameOriginSecurity
lacksSameOriginSecurity()
Returns true if the current request breaks the same-origin policy.
Definition: ApiBase.php:466
ApiBase\PARAM_HELP_MSG_APPEND
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
Definition: ApiBase.php:103
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:995
ApiBase\getWebUITokenSalt
getWebUITokenSalt(array $params)
Fetch the salt used in the Web UI corresponding to this module.
Definition: ApiBase.php:387
ApiBase\isMain
isMain()
Returns true if this module is the main module ($this === $this->mMainModule), false otherwise.
Definition: ApiBase.php:443
ApiBase\isReadMode
isReadMode()
Indicates whether this module requires read rights.
Definition: ApiBase.php:310
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:48
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
ApiBase\getModuleFromPath
getModuleFromPath( $path)
Get a module from its module path.
Definition: ApiBase.php:500
ApiBase\getFinalParamDescription
getFinalParamDescription()
Get final parameter descriptions, after hooks have had a chance to tweak it as needed.
Definition: ApiBase.php:1731
ApiBase\PARAM_SENSITIVE
const PARAM_SENSITIVE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:71
ApiBase\PARAM_ISMULTI_LIMIT2
const PARAM_ISMULTI_LIMIT2
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:74
ExtensionRegistry\getInstance
static getInstance()
Definition: ExtensionRegistry.php:130
ApiBase\getFinalSummary
getFinalSummary()
Get final module summary.
Definition: ApiBase.php:1653
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:65
ApiBase\explodeMultiValue
explodeMultiValue( $value, $limit)
Split a multi-valued parameter string, like explode()
Definition: ApiBase.php:2017
MediaWiki\Block\DatabaseBlock
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
Definition: DatabaseBlock.php:54
ApiBase\PARAM_MIN
const PARAM_MIN
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:63
StatusValue\isGood
isGood()
Returns whether the operation completed and didn't have any error or warnings.
Definition: StatusValue.php:121
MWException
MediaWiki exception.
Definition: MWException.php:26
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:143
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Definition: GlobalFunctions.php:1033
ApiBase\getCustomPrinter
getCustomPrinter()
If the module may only be used with a certain format module, it should override this method to return...
Definition: ApiBase.php:252
ApiBase\getFinalDescription
getFinalDescription()
Get final module description, after hooks have had a chance to tweak it as needed.
Definition: ApiBase.php:1669
wfTransactionalTimeLimit
wfTransactionalTimeLimit()
Set PHP's time limit to the larger of php.ini or $wgTransactionalTimeLimit.
Definition: GlobalFunctions.php:2722
ApiBase\getModulePath
getModulePath()
Get the path to this module.
Definition: ApiBase.php:482
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2500
ApiBase\LIMIT_BIG1
const LIMIT_BIG1
Fast query, standard limit.
Definition: ApiBase.php:154
ContextSource
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
Definition: ContextSource.php:29
ApiQueryTokens\getTokenTypeSalts
static getTokenTypeSalts()
Get the salts for known token types.
Definition: ApiQueryTokens.php:63
ApiBase\PARAM_MAX
const PARAM_MAX
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:61
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:659
WatchAction\doWatchOrUnwatch
static doWatchOrUnwatch( $watch, Title $title, User $user)
Watch or unwatch a page.
Definition: WatchAction.php:91
ApiBase\handleParamNormalization
handleParamNormalization( $paramName, $value, $rawValue)
Handle when a parameter was Unicode-normalized.
Definition: ApiBase.php:1060
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
ApiBase\isDeprecated
isDeprecated()
Indicates whether this module is deprecated.
Definition: ApiBase.php:342
ApiBase\requireAtLeastOneParameter
requireAtLeastOneParameter( $params,... $required)
Die if none of a certain set of parameters is set and not false.
Definition: ApiBase.php:856
ApiBase\$mReplicaDB
$mReplicaDB
Definition: ApiBase.php:188
MediaWiki\Block\AbstractBlock\getType
getType()
Get the type of target for this particular block.
Definition: AbstractBlock.php:432
MediaWiki\Block\AbstractBlock\isSitewide
isSitewide( $x=null)
Indicates that the block is a sitewide block.
Definition: AbstractBlock.php:213
ApiMessage\create
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
Definition: ApiMessage.php:40
ApiBase\PARAM_EXTRA_NAMESPACES
const PARAM_EXTRA_NAMESPACES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:70
ApiBase\ALL_DEFAULT_STRING
const ALL_DEFAULT_STRING
Definition: ApiBase.php:151
ContextSource\setContext
setContext(IContextSource $context)
Definition: ContextSource.php:55
Wikimedia\ParamValidator\TypeDef\StringDef
Type definition for string types.
Definition: StringDef.php:24
ApiBase\getHelpUrls
getHelpUrls()
Return links to more detailed help pages about the module.
Definition: ApiBase.php:276
ApiBlockInfoTrait
trait ApiBlockInfoTrait
Definition: ApiBlockInfoTrait.php:27
ApiBase\getWatchlistValue
getWatchlistValue( $watchlist, $titleObj, $userOption=null)
Return true if we're to watch the page, false if not, null if no change.
Definition: ApiBase.php:993
ApiBase\needsToken
needsToken()
Returns the token type this module requires in order to execute.
Definition: ApiBase.php:374
ApiBase\getModulePrefix
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition: ApiBase.php:426
ApiBase\$mModuleName
string $mModuleName
Definition: ApiBase.php:187
ApiBase\setWatch
setWatch( $watch, $titleObj, $userOption=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
Definition: ApiBase.php:1115
ApiBase\getContinuationManager
getContinuationManager()
Get the continuation manager.
Definition: ApiBase.php:578
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:168
ApiBase\validateLimit
validateLimit( $name, &$value, $min, $max, $botMax=null, $enforceLimits=false)
Validate the value against the minimum and user/bot maximum limits.
Definition: ApiBase.php:2124
ApiBase\addError
addError( $msg, $code=null, $data=null)
Add an error for this module without aborting.
Definition: ApiBase.php:1345
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:48
ApiBase\getWatchlistUser
getWatchlistUser( $params)
Gets the user for whom to get the watchlist.
Definition: ApiBase.php:1130
ApiBase\requireOnlyOneParameter
requireOnlyOneParameter( $params,... $required)
Die if none or more than one of a certain set of parameters is set and not false.
Definition: ApiBase.php:796
ApiBase\requireMaxOneParameter
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
Definition: ApiBase.php:831
ApiBase\dieContinueUsageIf
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
Definition: ApiBase.php:1559
ApiBase\addDeprecation
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition: ApiBase.php:1312
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:81
ApiBase\LIMIT_SML2
const LIMIT_SML2
Slow query, apihighlimits limit.
Definition: ApiBase.php:160
ApiBase\encodeParamName
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition: ApiBase.php:637
ApiBase\dieReadOnly
dieReadOnly()
Helper function for readonly errors.
Definition: ApiBase.php:1465
ApiBase\GET_VALUES_FOR_HELP
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
Definition: ApiBase.php:167
WikiPage\newFromID
static newFromID( $id, $from='fromdb')
Constructor from a page id.
Definition: WikiPage.php:181
ApiBase\getPermissionManager
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition: ApiBase.php:608
ApiBase\useTransactionalTimeLimit
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: ApiBase.php:1236
ApiBase\getConditionalRequestData
getConditionalRequestData( $condition)
Returns data for HTTP conditional request mechanisms.
Definition: ApiBase.php:403
ApiBase\isWriteMode
isWriteMode()
Indicates whether this module requires write mode.
Definition: ApiBase.php:325
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1488
ApiBase\PARAM_HELP_MSG_INFO
const PARAM_HELP_MSG_INFO
(array) Specify additional information tags for the parameter.
Definition: ApiBase.php:113
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:53
ApiBase\PARAM_RANGE_ENFORCE
const PARAM_RANGE_ENFORCE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:82
ApiBase\PARAM_VALUE_LINKS
const PARAM_VALUE_LINKS
Deprecated and unused.
Definition: ApiBase.php:120
Wikimedia\ParamValidator\TypeDef\IntegerDef
Type definition for integer types.
Definition: IntegerDef.php:23
ApiBase\PARAM_TEMPLATE_VARS
const PARAM_TEMPLATE_VARS
(array) Indicate that this is a templated parameter, and specify replacements.
Definition: ApiBase.php:147
ApiBase\filterIDs
filterIDs( $fields, array $ids)
Filter out-of-range values from a list of positive integer IDs.
Definition: ApiBase.php:1250
ApiBase\LIMIT_BIG2
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition: ApiBase.php:156
wfReadOnlyReason
wfReadOnlyReason()
Check if the site is in read-only mode and return the message if so.
Definition: GlobalFunctions.php:1120
ApiQueryTokens\getToken
static getToken(User $user, MediaWiki\Session\Session $session, $salt)
Get a token from a salt.
Definition: ApiQueryTokens.php:94
ApiBase\getModuleManager
getModuleManager()
Get the module manager, or null if this module has no sub-modules.
Definition: ApiBase.php:239
Wikimedia\ParamValidator\ParamValidator::TypeDef\NamespaceDef
Type definition for namespace types.
Definition: NamespaceDef.php:18
ApiBase\isInternal
isInternal()
Indicates whether this module is "internal" Internal API modules are not (yet) intended for 3rd party...
Definition: ApiBase.php:352
ApiBase\getModuleSourceInfo
getModuleSourceInfo()
Returns information about the source of this module, if known.
Definition: ApiBase.php:1910
$path
$path
Definition: NoLocalSettings.php:25
ApiBase\PARAM_DFLT
const PARAM_DFLT
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:58
ApiBase\getParameter
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
Definition: ApiBase.php:779
ApiBase\dieWithException
dieWithException(Throwable $exception, array $options=[])
Abort execution with an error derived from a throwable.
Definition: ApiBase.php:1391
ApiBase\dieStatus
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition: ApiBase.php:1437
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:418
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:59
ApiBase\PARAM_MAX2
const PARAM_MAX2
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:62
StatusValue\hasMessage
hasMessage( $message)
Returns true if the specified message is present as a warning or error.
Definition: StatusValue.php:261
ApiBase\getAllowedParams
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition: ApiBase.php:292
ApiBase\parseMultiValue
parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues, $allSpecifier=null, $limit1=null, $limit2=null)
Return an array of values that were given in a 'a|b|c' notation, after it optionally validates them a...
Definition: ApiBase.php:2040
$help
$help
Definition: mcc.php:32
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:434
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
ApiBase\PARAM_MAX_CHARS
const PARAM_MAX_CHARS
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:76
MediaWiki\Block\AbstractBlock
Definition: AbstractBlock.php:36
ApiBase\checkTitleUserPermissions
checkTitleUserPermissions(LinkTarget $linkTarget, $actions, array $options=[])
Helper function for permission-denied errors.
Definition: ApiBase.php:1506
ApiBase\getTitleFromTitleOrPageId
getTitleFromTitleOrPageId( $params)
Get a Title object from a title or pageid param, if possible.
Definition: ApiBase.php:965
User\IGNORE_USER_RIGHTS
const IGNORE_USER_RIGHTS
Definition: User.php:85
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
ApiBase\$mModulePrefix
string $mModulePrefix
Definition: ApiBase.php:187
RawMessage
Variant of the Message class.
Definition: RawMessage.php:34
ApiBase\PARAM_HELP_MSG_PER_VALUE
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
Definition: ApiBase.php:129
ApiBase\PARAM_SUBMODULE_PARAM_PREFIX
const PARAM_SUBMODULE_PARAM_PREFIX
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:68
ApiBase\$mParamCache
array $mParamCache
Definition: ApiBase.php:192
ApiBase\PARAM_MAX_BYTES
const PARAM_MAX_BYTES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:75
ApiHelpParamValueMessage
Message subclass that prepends wikitext for API help.
Definition: ApiHelpParamValueMessage.php:33
$IP
$IP
Definition: WebStart.php:49
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:53
Title\newFromID
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Definition: Title.php:476
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
ApiBase\dieDebug
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
Definition: ApiBase.php:1571
ApiBase\execute
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
ApiBase\errorArrayToStatus
errorArrayToStatus(array $errors, User $user=null)
Turn an array of message keys or key+param arrays into a Status.
Definition: ApiBase.php:1190
ApiBase\getErrorFormatter
getErrorFormatter()
Get the error formatter.
Definition: ApiBase.php:552
MediaWiki\Api\Validator\SubmoduleDef
Type definition for submodule types.
Definition: SubmoduleDef.php:17
ApiBase\requirePostedParameters
requirePostedParameters( $params, $prefix='prefix')
Die if any of the specified parameters were found in the query part of the URL rather than the post b...
Definition: ApiBase.php:883
Wikimedia\ParamValidator\ParamValidator
Service for formatting and validating API parameters.
Definition: ParamValidator.php:42
ApiBase\LIMIT_SML1
const LIMIT_SML1
Slow query, standard limit.
Definition: ApiBase.php:158
ApiBase\getHelpFlags
getHelpFlags()
Generates the list of flags for the help screen and for action=paraminfo.
Definition: ApiBase.php:1877
ApiBase\$filterIDsCache
static stdClass[][] $filterIDsCache
Cache for self::filterIDs()
Definition: ApiBase.php:173