MediaWiki  master
ApiBase.php
Go to the documentation of this file.
1 <?php
37 
50 abstract class ApiBase extends ContextSource {
51 
53 
55  private $hookContainer;
56 
58  private $hookRunner;
59 
66  public const PARAM_DFLT = ParamValidator::PARAM_DEFAULT;
67  public const PARAM_ISMULTI = ParamValidator::PARAM_ISMULTI;
68  public const PARAM_TYPE = ParamValidator::PARAM_TYPE;
69  public const PARAM_MAX = IntegerDef::PARAM_MAX;
70  public const PARAM_MAX2 = IntegerDef::PARAM_MAX2;
71  public const PARAM_MIN = IntegerDef::PARAM_MIN;
72  public const PARAM_ALLOW_DUPLICATES = ParamValidator::PARAM_ALLOW_DUPLICATES;
73  public const PARAM_DEPRECATED = ParamValidator::PARAM_DEPRECATED;
74  public const PARAM_REQUIRED = ParamValidator::PARAM_REQUIRED;
75  public const PARAM_SUBMODULE_MAP = SubmoduleDef::PARAM_SUBMODULE_MAP;
76  public const PARAM_SUBMODULE_PARAM_PREFIX = SubmoduleDef::PARAM_SUBMODULE_PARAM_PREFIX;
77  public const PARAM_ALL = ParamValidator::PARAM_ALL;
78  public const PARAM_EXTRA_NAMESPACES = NamespaceDef::PARAM_EXTRA_NAMESPACES;
79  public const PARAM_SENSITIVE = ParamValidator::PARAM_SENSITIVE;
80  public const PARAM_DEPRECATED_VALUES = EnumDef::PARAM_DEPRECATED_VALUES;
81  public const PARAM_ISMULTI_LIMIT1 = ParamValidator::PARAM_ISMULTI_LIMIT1;
82  public const PARAM_ISMULTI_LIMIT2 = ParamValidator::PARAM_ISMULTI_LIMIT2;
83  public const PARAM_MAX_BYTES = StringDef::PARAM_MAX_BYTES;
84  public const PARAM_MAX_CHARS = StringDef::PARAM_MAX_CHARS;
85 
90  public const PARAM_RANGE_ENFORCE = 'api-param-range-enforce';
91 
104  public const PARAM_HELP_MSG = 'api-param-help-msg';
105 
111  public const PARAM_HELP_MSG_APPEND = 'api-param-help-msg-append';
112 
121  public const PARAM_HELP_MSG_INFO = 'api-param-help-msg-info';
122 
128  public const PARAM_VALUE_LINKS = 'api-param-value-links';
129 
137  public const PARAM_HELP_MSG_PER_VALUE = 'api-param-help-msg-per-value';
138 
155  public const PARAM_TEMPLATE_VARS = 'param-template-vars';
156 
159  public const ALL_DEFAULT_STRING = '*';
160 
162  public const LIMIT_BIG1 = 500;
164  public const LIMIT_BIG2 = 5000;
166  public const LIMIT_SML1 = 50;
168  public const LIMIT_SML2 = 500;
169 
175  public const GET_VALUES_FOR_HELP = 1;
176 
178  private static $extensionInfo = null;
179 
181  private static $filterIDsCache = [];
182 
184  private static $blockMsgMap = [
185  'blockedtext' => [ 'apierror-blocked', 'blocked' ],
186  'blockedtext-partial' => [ 'apierror-blocked-partial', 'blocked' ],
187  'autoblockedtext' => [ 'apierror-autoblocked', 'autoblocked' ],
188  'systemblockedtext' => [ 'apierror-systemblocked', 'blocked' ],
189  'blockedtext-composite' => [ 'apierror-blocked', 'blocked' ],
190  ];
191 
193  private $mMainModule;
196  private $mReplicaDB = null;
200  private $mParamCache = [];
202  private $mModuleSource = false;
203 
209  public function __construct( ApiMain $mainModule, $moduleName, $modulePrefix = '' ) {
210  $this->mMainModule = $mainModule;
211  $this->mModuleName = $moduleName;
212  $this->mModulePrefix = $modulePrefix;
213 
214  if ( !$this->isMain() ) {
215  $this->setContext( $mainModule->getContext() );
216  }
217  }
218 
219  /************************************************************************/
240  abstract public function execute();
241 
247  public function getModuleManager() {
248  return null;
249  }
250 
260  public function getCustomPrinter() {
261  return null;
262  }
263 
275  protected function getExamplesMessages() {
276  return [];
277  }
278 
284  public function getHelpUrls() {
285  return [];
286  }
287 
300  protected function getAllowedParams( /* $flags = 0 */ ) {
301  // int $flags is not declared because it causes "Strict standards"
302  // warning. Most derived classes do not implement it.
303  return [];
304  }
305 
310  public function shouldCheckMaxlag() {
311  return true;
312  }
313 
318  public function isReadMode() {
319  return true;
320  }
321 
333  public function isWriteMode() {
334  return false;
335  }
336 
341  public function mustBePosted() {
342  return $this->needsToken() !== false;
343  }
344 
350  public function isDeprecated() {
351  return false;
352  }
353 
360  public function isInternal() {
361  return false;
362  }
363 
382  public function needsToken() {
383  return false;
384  }
385 
395  protected function getWebUITokenSalt( array $params ) {
396  return null;
397  }
398 
411  public function getConditionalRequestData( $condition ) {
412  return null;
413  }
414 
417  /************************************************************************/
426  public function getModuleName() {
427  return $this->mModuleName;
428  }
429 
434  public function getModulePrefix() {
435  return $this->mModulePrefix;
436  }
437 
442  public function getMain() {
443  return $this->mMainModule;
444  }
445 
451  public function isMain() {
452  return $this === $this->mMainModule;
453  }
454 
460  public function getParent() {
461  return $this->isMain() ? null : $this->getMain();
462  }
463 
474  public function lacksSameOriginSecurity() {
475  // Main module has this method overridden
476  // Safety - avoid infinite loop:
477  if ( $this->isMain() ) {
478  self::dieDebug( __METHOD__, 'base method was called on main module.' );
479  }
480 
481  return $this->getMain()->lacksSameOriginSecurity();
482  }
483 
490  public function getModulePath() {
491  if ( $this->isMain() ) {
492  return 'main';
493  } elseif ( $this->getParent()->isMain() ) {
494  return $this->getModuleName();
495  } else {
496  return $this->getParent()->getModulePath() . '+' . $this->getModuleName();
497  }
498  }
499 
508  public function getModuleFromPath( $path ) {
509  $module = $this->getMain();
510  if ( $path === 'main' ) {
511  return $module;
512  }
513 
514  $parts = explode( '+', $path );
515  if ( count( $parts ) === 1 ) {
516  // In case the '+' was typed into URL, it resolves as a space
517  $parts = explode( ' ', $path );
518  }
519 
520  $count = count( $parts );
521  for ( $i = 0; $i < $count; $i++ ) {
522  $parent = $module;
523  $manager = $parent->getModuleManager();
524  if ( $manager === null ) {
525  $errorPath = implode( '+', array_slice( $parts, 0, $i ) );
526  $this->dieWithError( [ 'apierror-badmodule-nosubmodules', $errorPath ], 'badmodule' );
527  }
528  $module = $manager->getModule( $parts[$i] );
529 
530  if ( $module === null ) {
531  $errorPath = $i ? implode( '+', array_slice( $parts, 0, $i ) ) : $parent->getModuleName();
532  $this->dieWithError(
533  [ 'apierror-badmodule-badsubmodule', $errorPath, wfEscapeWikiText( $parts[$i] ) ],
534  'badmodule'
535  );
536  }
537  }
538 
539  return $module;
540  }
541 
546  public function getResult() {
547  // Main module has getResult() method overridden
548  // Safety - avoid infinite loop:
549  if ( $this->isMain() ) {
550  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
551  }
552 
553  return $this->getMain()->getResult();
554  }
555 
560  public function getErrorFormatter() {
561  // Main module has getErrorFormatter() method overridden
562  // Safety - avoid infinite loop:
563  if ( $this->isMain() ) {
564  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
565  }
566 
567  return $this->getMain()->getErrorFormatter();
568  }
569 
574  protected function getDB() {
575  if ( !isset( $this->mReplicaDB ) ) {
576  $this->mReplicaDB = wfGetDB( DB_REPLICA, 'api' );
577  }
578 
579  return $this->mReplicaDB;
580  }
581 
586  public function getContinuationManager() {
587  // Main module has getContinuationManager() method overridden
588  // Safety - avoid infinite loop:
589  if ( $this->isMain() ) {
590  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
591  }
592 
593  return $this->getMain()->getContinuationManager();
594  }
595 
600  public function setContinuationManager( ApiContinuationManager $manager = null ) {
601  // Main module has setContinuationManager() method overridden
602  // Safety - avoid infinite loop:
603  if ( $this->isMain() ) {
604  self::dieDebug( __METHOD__, 'base method was called on main module. ' );
605  }
606 
607  $this->getMain()->setContinuationManager( $manager );
608  }
609 
616  protected function getPermissionManager(): PermissionManager {
617  return MediaWikiServices::getInstance()->getPermissionManager();
618  }
619 
626  protected function getHookContainer() {
627  if ( !$this->hookContainer ) {
628  $this->hookContainer = MediaWikiServices::getInstance()->getHookContainer();
629  }
630  return $this->hookContainer;
631  }
632 
641  protected function getHookRunner() {
642  if ( !$this->hookRunner ) {
643  $this->hookRunner = new ApiHookRunner( $this->getHookContainer() );
644  }
645  return $this->hookRunner;
646  }
647 
650  /************************************************************************/
662  public function dynamicParameterDocumentation() {
663  return null;
664  }
665 
673  public function encodeParamName( $paramName ) {
674  if ( is_array( $paramName ) ) {
675  return array_map( function ( $name ) {
676  return $this->mModulePrefix . $name;
677  }, $paramName );
678  } else {
679  return $this->mModulePrefix . $paramName;
680  }
681  }
682 
695  public function extractRequestParams( $options = [] ) {
696  if ( is_bool( $options ) ) {
697  $options = [ 'parseLimit' => $options ];
698  }
699  $options += [
700  'parseLimit' => true,
701  'safeMode' => false,
702  ];
703 
704  $parseLimit = (bool)$options['parseLimit'];
705  $cacheKey = (int)$parseLimit;
706 
707  // Cache parameters, for performance and to avoid T26564.
708  if ( !isset( $this->mParamCache[$cacheKey] ) ) {
709  $params = $this->getFinalParams() ?: [];
710  $results = [];
711  $warned = [];
712 
713  // Process all non-templates and save templates for secondary
714  // processing.
715  $toProcess = [];
716  foreach ( $params as $paramName => $paramSettings ) {
717  if ( isset( $paramSettings[self::PARAM_TEMPLATE_VARS] ) ) {
718  $toProcess[] = [ $paramName, $paramSettings[self::PARAM_TEMPLATE_VARS], $paramSettings ];
719  } else {
720  try {
721  $results[$paramName] = $this->getParameterFromSettings(
722  $paramName, $paramSettings, $parseLimit
723  );
724  } catch ( ApiUsageException $ex ) {
725  $results[$paramName] = $ex;
726  }
727  }
728  }
729 
730  // Now process all the templates by successively replacing the
731  // placeholders with all client-supplied values.
732  // This bit duplicates JavaScript logic in
733  // ApiSandbox.PageLayout.prototype.updateTemplatedParams().
734  // If you update this, see if that needs updating too.
735  while ( $toProcess ) {
736  list( $name, $targets, $settings ) = array_shift( $toProcess );
737 
738  foreach ( $targets as $placeholder => $target ) {
739  if ( !array_key_exists( $target, $results ) ) {
740  // The target wasn't processed yet, try the next one.
741  // If all hit this case, the parameter has no expansions.
742  continue;
743  }
744  if ( !is_array( $results[$target] ) || !$results[$target] ) {
745  // The target was processed but has no (valid) values.
746  // That means it has no expansions.
747  break;
748  }
749 
750  // Expand this target in the name and all other targets,
751  // then requeue if there are more targets left or put in
752  // $results if all are done.
753  unset( $targets[$placeholder] );
754  $placeholder = '{' . $placeholder . '}';
755  // @phan-suppress-next-line PhanTypeNoAccessiblePropertiesForeach
756  foreach ( $results[$target] as $value ) {
757  if ( !preg_match( '/^[^{}]*$/', $value ) ) {
758  // Skip values that make invalid parameter names.
759  $encTargetName = $this->encodeParamName( $target );
760  if ( !isset( $warned[$encTargetName][$value] ) ) {
761  $warned[$encTargetName][$value] = true;
762  $this->addWarning( [
763  'apiwarn-ignoring-invalid-templated-value',
764  wfEscapeWikiText( $encTargetName ),
765  wfEscapeWikiText( $value ),
766  ] );
767  }
768  continue;
769  }
770 
771  $newName = str_replace( $placeholder, $value, $name );
772  if ( !$targets ) {
773  try {
774  $results[$newName] = $this->getParameterFromSettings(
775  $newName,
776  $settings,
777  $parseLimit
778  );
779  } catch ( ApiUsageException $ex ) {
780  $results[$newName] = $ex;
781  }
782  } else {
783  $newTargets = [];
784  foreach ( $targets as $k => $v ) {
785  $newTargets[$k] = str_replace( $placeholder, $value, $v );
786  }
787  $toProcess[] = [ $newName, $newTargets, $settings ];
788  }
789  }
790  break;
791  }
792  }
793 
794  $this->mParamCache[$cacheKey] = $results;
795  }
796 
797  $ret = $this->mParamCache[$cacheKey];
798  if ( !$options['safeMode'] ) {
799  foreach ( $ret as $v ) {
800  if ( $v instanceof ApiUsageException ) {
801  throw $v;
802  }
803  }
804  }
805 
806  return $this->mParamCache[$cacheKey];
807  }
808 
815  protected function getParameter( $paramName, $parseLimit = true ) {
816  $ret = $this->extractRequestParams( [
817  'parseLimit' => $parseLimit,
818  'safeMode' => true,
819  ] )[$paramName];
820  if ( $ret instanceof ApiUsageException ) {
821  throw $ret;
822  }
823  return $ret;
824  }
825 
832  public function requireOnlyOneParameter( $params, ...$required ) {
833  $intersection = array_intersect( array_keys( array_filter( $params,
834  [ $this, 'parameterNotEmpty' ] ) ), $required );
835 
836  if ( count( $intersection ) > 1 ) {
837  $this->dieWithError( [
838  'apierror-invalidparammix',
839  Message::listParam( array_map(
840  function ( $p ) {
841  return '<var>' . $this->encodeParamName( $p ) . '</var>';
842  },
843  array_values( $intersection )
844  ) ),
845  count( $intersection ),
846  ] );
847  } elseif ( count( $intersection ) == 0 ) {
848  $this->dieWithError( [
849  'apierror-missingparam-one-of',
850  Message::listParam( array_map(
851  function ( $p ) {
852  return '<var>' . $this->encodeParamName( $p ) . '</var>';
853  },
854  $required
855  ) ),
856  count( $required ),
857  ], 'missingparam' );
858  }
859  }
860 
867  public function requireMaxOneParameter( $params, ...$required ) {
868  $intersection = array_intersect( array_keys( array_filter( $params,
869  [ $this, 'parameterNotEmpty' ] ) ), $required );
870 
871  if ( count( $intersection ) > 1 ) {
872  $this->dieWithError( [
873  'apierror-invalidparammix',
874  Message::listParam( array_map(
875  function ( $p ) {
876  return '<var>' . $this->encodeParamName( $p ) . '</var>';
877  },
878  array_values( $intersection )
879  ) ),
880  count( $intersection ),
881  ] );
882  }
883  }
884 
892  public function requireAtLeastOneParameter( $params, ...$required ) {
893  $intersection = array_intersect(
894  array_keys( array_filter( $params, [ $this, 'parameterNotEmpty' ] ) ),
895  $required
896  );
897 
898  if ( count( $intersection ) == 0 ) {
899  $this->dieWithError( [
900  'apierror-missingparam-at-least-one-of',
901  Message::listParam( array_map(
902  function ( $p ) {
903  return '<var>' . $this->encodeParamName( $p ) . '</var>';
904  },
905  $required
906  ) ),
907  count( $required ),
908  ], 'missingparam' );
909  }
910  }
911 
919  public function requirePostedParameters( $params, $prefix = 'prefix' ) {
920  // Skip if $wgDebugAPI is set or we're in internal mode
921  if ( $this->getConfig()->get( 'DebugAPI' ) || $this->getMain()->isInternalMode() ) {
922  return;
923  }
924 
925  $queryValues = $this->getRequest()->getQueryValuesOnly();
926  $badParams = [];
927  foreach ( $params as $param ) {
928  if ( $prefix !== 'noprefix' ) {
929  $param = $this->encodeParamName( $param );
930  }
931  if ( array_key_exists( $param, $queryValues ) ) {
932  $badParams[] = $param;
933  }
934  }
935 
936  if ( $badParams ) {
937  $this->dieWithError(
938  [ 'apierror-mustpostparams', implode( ', ', $badParams ), count( $badParams ) ]
939  );
940  }
941  }
942 
949  private function parameterNotEmpty( $x ) {
950  return $x !== null && $x !== false;
951  }
952 
964  public function getTitleOrPageId( $params, $load = false ) {
965  $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
966 
967  $pageObj = null;
968  if ( isset( $params['title'] ) ) {
969  $titleObj = Title::newFromText( $params['title'] );
970  if ( !$titleObj || $titleObj->isExternal() ) {
971  $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
972  }
973  if ( !$titleObj->canExist() ) {
974  $this->dieWithError( 'apierror-pagecannotexist' );
975  }
976  $pageObj = WikiPage::factory( $titleObj );
977  if ( $load !== false ) {
978  $pageObj->loadPageData( $load );
979  }
980  } elseif ( isset( $params['pageid'] ) ) {
981  if ( $load === false ) {
982  $load = 'fromdb';
983  }
984  $pageObj = WikiPage::newFromID( $params['pageid'], $load );
985  if ( !$pageObj ) {
986  $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
987  }
988  }
989 
990  return $pageObj;
991  }
992 
1001  public function getTitleFromTitleOrPageId( $params ) {
1002  $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
1003 
1004  $titleObj = null;
1005  if ( isset( $params['title'] ) ) {
1006  $titleObj = Title::newFromText( $params['title'] );
1007  if ( !$titleObj || $titleObj->isExternal() ) {
1008  $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
1009  }
1010  return $titleObj;
1011  } elseif ( isset( $params['pageid'] ) ) {
1012  $titleObj = Title::newFromID( $params['pageid'] );
1013  if ( !$titleObj ) {
1014  $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
1015  }
1016  }
1017 
1018  return $titleObj;
1019  }
1020 
1029  protected function getWatchlistValue( $watchlist, $titleObj, $userOption = null ) {
1030  $userWatching = $this->getUser()->isWatched( $titleObj, User::IGNORE_USER_RIGHTS );
1031 
1032  switch ( $watchlist ) {
1033  case 'watch':
1034  return true;
1035 
1036  case 'unwatch':
1037  return false;
1038 
1039  case 'preferences':
1040  # If the user is already watching, don't bother checking
1041  if ( $userWatching ) {
1042  return true;
1043  }
1044  # If no user option was passed, use watchdefault and watchcreations
1045  if ( $userOption === null ) {
1046  return $this->getUser()->getBoolOption( 'watchdefault' ) ||
1047  $this->getUser()->getBoolOption( 'watchcreations' ) && !$titleObj->exists();
1048  }
1049 
1050  # Watch the article based on the user preference
1051  return $this->getUser()->getBoolOption( $userOption );
1052 
1053  case 'nochange':
1054  return $userWatching;
1055 
1056  default:
1057  return $userWatching;
1058  }
1059  }
1060 
1070  protected function getParameterFromSettings( $name, $settings, $parseLimit ) {
1071  $validator = $this->getMain()->getParamValidator();
1072  $value = $validator->getValue( $this, $name, $settings, [
1073  'parse-limit' => $parseLimit,
1074  ] );
1075 
1076  // @todo Deprecate and remove this, if possible.
1077  if ( $parseLimit && isset( $settings[ParamValidator::PARAM_TYPE] ) &&
1078  $settings[ParamValidator::PARAM_TYPE] === 'limit' &&
1079  $this->getMain()->getVal( $this->encodeParamName( $name ) ) === 'max'
1080  ) {
1081  $this->getResult()->addParsedLimit( $this->getModuleName(), $value );
1082  }
1083 
1084  return $value;
1085  }
1086 
1096  public function handleParamNormalization( $paramName, $value, $rawValue ) {
1097  $this->addWarning( [ 'apiwarn-badutf8', $paramName ] );
1098  }
1099 
1109  final public function validateToken( $token, array $params ) {
1110  $tokenType = $this->needsToken();
1112  if ( !isset( $salts[$tokenType] ) ) {
1113  throw new MWException(
1114  "Module '{$this->getModuleName()}' tried to use token type '$tokenType' " .
1115  'without registering it'
1116  );
1117  }
1118 
1119  $tokenObj = ApiQueryTokens::getToken(
1120  $this->getUser(), $this->getRequest()->getSession(), $salts[$tokenType]
1121  );
1122  if ( $tokenObj->match( $token ) ) {
1123  return true;
1124  }
1125 
1126  $webUiSalt = $this->getWebUITokenSalt( $params );
1127  if ( $webUiSalt !== null && $this->getUser()->matchEditToken(
1128  $token,
1129  $webUiSalt,
1130  $this->getRequest()
1131  ) ) {
1132  return true;
1133  }
1134 
1135  return false;
1136  }
1137 
1140  /************************************************************************/
1151  protected function setWatch( $watch, $titleObj, $userOption = null ) {
1152  $value = $this->getWatchlistValue( $watch, $titleObj, $userOption );
1153  if ( $value === null ) {
1154  return;
1155  }
1156 
1157  WatchAction::doWatchOrUnwatch( $value, $titleObj, $this->getUser() );
1158  }
1159 
1166  public function getWatchlistUser( $params ) {
1167  if ( $params['owner'] !== null && $params['token'] !== null ) {
1168  $user = User::newFromName( $params['owner'], false );
1169  if ( !( $user && $user->getId() ) ) {
1170  $this->dieWithError(
1171  [ 'nosuchusershort', wfEscapeWikiText( $params['owner'] ) ], 'bad_wlowner'
1172  );
1173  }
1174  $token = $user->getOption( 'watchlisttoken' );
1175  if ( $token == '' || !hash_equals( $token, $params['token'] ) ) {
1176  $this->dieWithError( 'apierror-bad-watchlist-token', 'bad_wltoken' );
1177  }
1178  } else {
1179  if ( !$this->getUser()->isLoggedIn() ) {
1180  $this->dieWithError( 'watchlistanontext', 'notloggedin' );
1181  }
1182  $this->checkUserRightsAny( 'viewmywatchlist' );
1183  $user = $this->getUser();
1184  }
1185 
1186  return $user;
1187  }
1188 
1201  public static function makeMessage( $msg, IContextSource $context, array $params = null ) {
1202  if ( is_string( $msg ) ) {
1203  $msg = wfMessage( $msg );
1204  } elseif ( is_array( $msg ) ) {
1205  $msg = wfMessage( ...$msg );
1206  }
1207  if ( !$msg instanceof Message ) {
1208  return null;
1209  }
1210 
1211  $msg->setContext( $context );
1212  if ( $params ) {
1213  $msg->params( $params );
1214  }
1215 
1216  return $msg;
1217  }
1218 
1226  public function errorArrayToStatus( array $errors, User $user = null ) {
1227  if ( $user === null ) {
1228  $user = $this->getUser();
1229  }
1230 
1231  $status = Status::newGood();
1232  foreach ( $errors as $error ) {
1233  if ( !is_array( $error ) ) {
1234  $error = [ $error ];
1235  }
1236  if ( is_string( $error[0] ) && isset( self::$blockMsgMap[$error[0]] ) && $user->getBlock() ) {
1237  list( $msg, $code ) = self::$blockMsgMap[$error[0]];
1238  $status->fatal( ApiMessage::create( $msg, $code,
1239  [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ]
1240  ) );
1241  } else {
1242  $status->fatal( ...$error );
1243  }
1244  }
1245  return $status;
1246  }
1247 
1254  public function addBlockInfoToStatus( StatusValue $status, User $user = null ) {
1255  if ( $user === null ) {
1256  $user = $this->getUser();
1257  }
1258 
1259  foreach ( self::$blockMsgMap as $msg => list( $apiMsg, $code ) ) {
1260  if ( $status->hasMessage( $msg ) && $user->getBlock() ) {
1261  $status->replaceMessage( $msg, ApiMessage::create( $apiMsg, $code,
1262  [ 'blockinfo' => $this->getBlockDetails( $user->getBlock() ) ]
1263  ) );
1264  }
1265  }
1266  }
1267 
1272  protected function useTransactionalTimeLimit() {
1273  if ( $this->getRequest()->wasPosted() ) {
1275  }
1276  }
1277 
1286  protected function filterIDs( $fields, array $ids ) {
1287  $min = INF;
1288  $max = 0;
1289  foreach ( $fields as list( $table, $field ) ) {
1290  if ( isset( self::$filterIDsCache[$table][$field] ) ) {
1291  $row = self::$filterIDsCache[$table][$field];
1292  } else {
1293  $row = $this->getDB()->selectRow(
1294  $table,
1295  [
1296  'min_id' => "MIN($field)",
1297  'max_id' => "MAX($field)",
1298  ],
1299  '',
1300  __METHOD__
1301  );
1302  self::$filterIDsCache[$table][$field] = $row;
1303  }
1304  $min = min( $min, $row->min_id );
1305  $max = max( $max, $row->max_id );
1306  }
1307  return array_filter( $ids, function ( $id ) use ( $min, $max ) {
1308  return ( is_int( $id ) && $id >= 0 || ctype_digit( $id ) )
1309  && $id >= $min && $id <= $max;
1310  } );
1311  }
1312 
1315  /************************************************************************/
1334  public function addWarning( $msg, $code = null, $data = null ) {
1335  $this->getErrorFormatter()->addWarning( $this->getModulePath(), $msg, $code, $data );
1336  }
1337 
1348  public function addDeprecation( $msg, $feature, $data = [] ) {
1349  $data = (array)$data;
1350  if ( $feature !== null ) {
1351  $data['feature'] = $feature;
1352  $this->logFeatureUsage( $feature );
1353  }
1354  $this->addWarning( $msg, 'deprecation', $data );
1355 
1356  // No real need to deduplicate here, ApiErrorFormatter does that for
1357  // us (assuming the hook is deterministic).
1358  $msgs = [ $this->msg( 'api-usage-mailinglist-ref' ) ];
1359  $this->getHookRunner()->onApiDeprecationHelp( $msgs );
1360  if ( count( $msgs ) > 1 ) {
1361  $key = '$' . implode( ' $', range( 1, count( $msgs ) ) );
1362  $msg = ( new RawMessage( $key ) )->params( $msgs );
1363  } else {
1364  $msg = reset( $msgs );
1365  }
1366  $this->getMain()->addWarning( $msg, 'deprecation-help' );
1367  }
1368 
1381  public function addError( $msg, $code = null, $data = null ) {
1382  $this->getErrorFormatter()->addError( $this->getModulePath(), $msg, $code, $data );
1383  }
1384 
1394  public function addMessagesFromStatus(
1395  StatusValue $status, $types = [ 'warning', 'error' ], array $filter = []
1396  ) {
1397  $this->getErrorFormatter()->addMessagesFromStatus(
1398  $this->getModulePath(), $status, $types, $filter
1399  );
1400  }
1401 
1415  public function dieWithError( $msg, $code = null, $data = null, $httpCode = null ) {
1416  throw ApiUsageException::newWithMessage( $this, $msg, $code, $data, $httpCode );
1417  }
1418 
1427  public function dieWithException( Throwable $exception, array $options = [] ) {
1428  $this->dieWithError(
1429  // @phan-suppress-next-line PhanTypeMismatchArgument
1430  $this->getErrorFormatter()->getMessageFromException( $exception, $options )
1431  );
1432  }
1433 
1442  public function dieBlocked( AbstractBlock $block ) {
1443  // Die using the appropriate message depending on block type
1444  if ( $block->getType() == DatabaseBlock::TYPE_AUTO ) {
1445  $this->dieWithError(
1446  'apierror-autoblocked',
1447  'autoblocked',
1448  [ 'blockinfo' => $this->getBlockDetails( $block ) ]
1449  );
1450  } elseif ( !$block->isSitewide() ) {
1451  $this->dieWithError(
1452  'apierror-blocked-partial',
1453  'blocked',
1454  [ 'blockinfo' => $this->getBlockDetails( $block ) ]
1455  );
1456  } else {
1457  $this->dieWithError(
1458  'apierror-blocked',
1459  'blocked',
1460  [ 'blockinfo' => $this->getBlockDetails( $block ) ]
1461  );
1462  }
1463  }
1464 
1473  public function dieStatus( StatusValue $status ) {
1474  if ( $status->isGood() ) {
1475  throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
1476  }
1477 
1478  // ApiUsageException needs a fatal status, but this method has
1479  // historically accepted any non-good status. Convert it if necessary.
1480  $status->setOK( false );
1481  if ( !$status->getErrorsByType( 'error' ) ) {
1482  $newStatus = Status::newGood();
1483  foreach ( $status->getErrorsByType( 'warning' ) as $err ) {
1484  $newStatus->fatal( $err['message'], ...$err['params'] );
1485  }
1486  if ( !$newStatus->getErrorsByType( 'error' ) ) {
1487  $newStatus->fatal( 'unknownerror-nocode' );
1488  }
1489  $status = $newStatus;
1490  }
1491 
1492  $this->addBlockInfoToStatus( $status );
1493  throw new ApiUsageException( $this, $status );
1494  }
1495 
1501  public function dieReadOnly() {
1502  $this->dieWithError(
1503  'apierror-readonly',
1504  'readonly',
1505  [ 'readonlyreason' => wfReadOnlyReason() ]
1506  );
1507  }
1508 
1517  public function checkUserRightsAny( $rights, $user = null ) {
1518  if ( !$user ) {
1519  $user = $this->getUser();
1520  }
1521  $rights = (array)$rights;
1522  if ( !$this->getPermissionManager()
1523  ->userHasAnyRight( $user, ...$rights )
1524  ) {
1525  $this->dieWithError( [ 'apierror-permissiondenied', $this->msg( "action-{$rights[0]}" ) ] );
1526  }
1527  }
1528 
1542  public function checkTitleUserPermissions(
1543  LinkTarget $linkTarget,
1544  $actions,
1545  array $options = []
1546  ) {
1547  $user = $options['user'] ?? $this->getUser();
1548 
1549  $errors = [];
1550  foreach ( (array)$actions as $action ) {
1551  $errors = array_merge(
1552  $errors,
1553  $this->getPermissionManager()->getPermissionErrors( $action, $user, $linkTarget )
1554  );
1555  }
1556 
1557  if ( $errors ) {
1558  if ( !empty( $options['autoblock'] ) ) {
1559  $user->spreadAnyEditBlock();
1560  }
1561 
1562  $this->dieStatus( $this->errorArrayToStatus( $errors, $user ) );
1563  }
1564  }
1565 
1577  public function dieWithErrorOrDebug( $msg, $code = null, $data = null, $httpCode = null ) {
1578  if ( $this->getConfig()->get( 'DebugAPI' ) !== true ) {
1579  $this->dieWithError( $msg, $code, $data, $httpCode );
1580  } else {
1581  $this->addWarning( $msg, $code, $data );
1582  }
1583  }
1584 
1595  protected function dieContinueUsageIf( $condition ) {
1596  if ( $condition ) {
1597  $this->dieWithError( 'apierror-badcontinue' );
1598  }
1599  }
1600 
1607  protected static function dieDebug( $method, $message ) {
1608  throw new MWException( "Internal error in $method: $message" );
1609  }
1610 
1617  public function logFeatureUsage( $feature ) {
1618  static $loggedFeatures = [];
1619 
1620  // Only log each feature once per request. We can get multiple calls from calls to
1621  // extractRequestParams() with different values for 'parseLimit', for example.
1622  if ( isset( $loggedFeatures[$feature] ) ) {
1623  return;
1624  }
1625  $loggedFeatures[$feature] = true;
1626 
1627  $request = $this->getRequest();
1628  $ctx = [
1629  'feature' => $feature,
1630  // Spaces to underscores in 'username' for historical reasons.
1631  'username' => str_replace( ' ', '_', $this->getUser()->getName() ),
1632  'clientip' => $request->getIP(),
1633  'referer' => (string)$request->getHeader( 'Referer' ),
1634  'agent' => $this->getMain()->getUserAgent(),
1635  ];
1636 
1637  // Text string is deprecated. Remove (or replace with just $feature) in MW 1.34.
1638  $s = '"' . addslashes( $ctx['feature'] ) . '"' .
1639  ' "' . wfUrlencode( $ctx['username'] ) . '"' .
1640  ' "' . $ctx['clientip'] . '"' .
1641  ' "' . addslashes( $ctx['referer'] ) . '"' .
1642  ' "' . addslashes( $ctx['agent'] ) . '"';
1643 
1644  wfDebugLog( 'api-feature-usage', $s, 'private', $ctx );
1645  }
1646 
1649  /************************************************************************/
1663  protected function getSummaryMessage() {
1664  return "apihelp-{$this->getModulePath()}-summary";
1665  }
1666 
1676  protected function getExtendedDescription() {
1677  return [ [
1678  "apihelp-{$this->getModulePath()}-extended-description",
1679  'api-help-no-extended-description',
1680  ] ];
1681  }
1682 
1689  public function getFinalSummary() {
1690  $msg = self::makeMessage( $this->getSummaryMessage(), $this->getContext(), [
1691  $this->getModulePrefix(),
1692  $this->getModuleName(),
1693  $this->getModulePath(),
1694  ] );
1695  return $msg;
1696  }
1697 
1705  public function getFinalDescription() {
1706  $summary = self::makeMessage( $this->getSummaryMessage(), $this->getContext(), [
1707  $this->getModulePrefix(),
1708  $this->getModuleName(),
1709  $this->getModulePath(),
1710  ] );
1711  $extendedDescription = self::makeMessage(
1712  $this->getExtendedDescription(), $this->getContext(), [
1713  $this->getModulePrefix(),
1714  $this->getModuleName(),
1715  $this->getModulePath(),
1716  ]
1717  );
1718 
1719  $msgs = [ $summary, $extendedDescription ];
1720 
1721  $this->getHookRunner()->onAPIGetDescriptionMessages( $this, $msgs );
1722 
1723  return $msgs;
1724  }
1725 
1734  public function getFinalParams( $flags = 0 ) {
1735  // @phan-suppress-next-line PhanParamTooMany
1736  $params = $this->getAllowedParams( $flags );
1737  if ( !$params ) {
1738  $params = [];
1739  }
1740 
1741  if ( $this->needsToken() ) {
1742  $params['token'] = [
1743  self::PARAM_TYPE => 'string',
1744  self::PARAM_REQUIRED => true,
1745  self::PARAM_SENSITIVE => true,
1746  self::PARAM_HELP_MSG => [
1747  'api-help-param-token',
1748  $this->needsToken(),
1749  ],
1750  ] + ( $params['token'] ?? [] );
1751  }
1752 
1753  $this->getHookRunner()->onAPIGetAllowedParams( $this, $params, $flags );
1754 
1755  return $params;
1756  }
1757 
1765  public function getFinalParamDescription() {
1766  $prefix = $this->getModulePrefix();
1767  $name = $this->getModuleName();
1768  $path = $this->getModulePath();
1769 
1770  $params = $this->getFinalParams( self::GET_VALUES_FOR_HELP );
1771  $msgs = [];
1772  foreach ( $params as $param => $settings ) {
1773  if ( !is_array( $settings ) ) {
1774  $settings = [];
1775  }
1776 
1777  if ( isset( $settings[self::PARAM_HELP_MSG] ) ) {
1778  $msg = $settings[self::PARAM_HELP_MSG];
1779  } else {
1780  $msg = $this->msg( "apihelp-{$path}-param-{$param}" );
1781  }
1782  $msg = self::makeMessage( $msg, $this->getContext(),
1783  [ $prefix, $param, $name, $path ] );
1784  if ( !$msg ) {
1785  self::dieDebug( __METHOD__,
1786  'Value in ApiBase::PARAM_HELP_MSG is not valid' );
1787  }
1788  $msgs[$param] = [ $msg ];
1789 
1790  if ( isset( $settings[self::PARAM_TYPE] ) &&
1791  $settings[self::PARAM_TYPE] === 'submodule'
1792  ) {
1793  if ( isset( $settings[self::PARAM_SUBMODULE_MAP] ) ) {
1794  $map = $settings[self::PARAM_SUBMODULE_MAP];
1795  } else {
1796  $prefix = $this->isMain() ? '' : ( $this->getModulePath() . '+' );
1797  $map = [];
1798  foreach ( $this->getModuleManager()->getNames( $param ) as $submoduleName ) {
1799  $map[$submoduleName] = $prefix . $submoduleName;
1800  }
1801  }
1802 
1803  $submodules = [];
1804  $submoduleFlags = []; // for sorting: higher flags are sorted later
1805  $submoduleNames = []; // for sorting: lexicographical, ascending
1806  foreach ( $map as $v => $m ) {
1807  $isDeprecated = false;
1808  $isInternal = false;
1809  $summary = null;
1810  try {
1811  $submod = $this->getModuleFromPath( $m );
1812  if ( $submod ) {
1813  $summary = $submod->getFinalSummary();
1814  $isDeprecated = $submod->isDeprecated();
1815  $isInternal = $submod->isInternal();
1816  }
1817  } catch ( ApiUsageException $ex ) {
1818  // Ignore
1819  }
1820  if ( $summary ) {
1821  $key = $summary->getKey();
1822  $params = $summary->getParams();
1823  } else {
1824  $key = 'api-help-undocumented-module';
1825  $params = [ $m ];
1826  }
1827  $m = new ApiHelpParamValueMessage(
1828  "[[Special:ApiHelp/$m|$v]]",
1829  $key,
1830  $params,
1831  $isDeprecated,
1832  $isInternal
1833  );
1834  $submodules[] = $m->setContext( $this->getContext() );
1835  $submoduleFlags[] = ( $isDeprecated ? 1 : 0 ) | ( $isInternal ? 2 : 0 );
1836  $submoduleNames[] = $v;
1837  }
1838  // sort $submodules by $submoduleFlags and $submoduleNames
1839  array_multisort( $submoduleFlags, $submoduleNames, $submodules );
1840  $msgs[$param] = array_merge( $msgs[$param], $submodules );
1841  } elseif ( isset( $settings[self::PARAM_HELP_MSG_PER_VALUE] ) ) {
1842  if ( !is_array( $settings[self::PARAM_HELP_MSG_PER_VALUE] ) ) {
1843  self::dieDebug( __METHOD__,
1844  'ApiBase::PARAM_HELP_MSG_PER_VALUE is not valid' );
1845  }
1846  if ( !is_array( $settings[self::PARAM_TYPE] ) ) {
1847  self::dieDebug( __METHOD__,
1848  'ApiBase::PARAM_HELP_MSG_PER_VALUE may only be used when ' .
1849  'ApiBase::PARAM_TYPE is an array' );
1850  }
1851 
1852  $valueMsgs = $settings[self::PARAM_HELP_MSG_PER_VALUE];
1853  $deprecatedValues = $settings[self::PARAM_DEPRECATED_VALUES] ?? [];
1854 
1855  foreach ( $settings[self::PARAM_TYPE] as $value ) {
1856  if ( isset( $valueMsgs[$value] ) ) {
1857  $msg = $valueMsgs[$value];
1858  } else {
1859  $msg = "apihelp-{$path}-paramvalue-{$param}-{$value}";
1860  }
1861  $m = self::makeMessage( $msg, $this->getContext(),
1862  [ $prefix, $param, $name, $path, $value ] );
1863  if ( $m ) {
1864  $m = new ApiHelpParamValueMessage(
1865  $value,
1866  // @phan-suppress-next-line PhanTypeMismatchArgument
1867  [ $m->getKey(), 'api-help-param-no-description' ],
1868  $m->getParams(),
1869  isset( $deprecatedValues[$value] )
1870  );
1871  $msgs[$param][] = $m->setContext( $this->getContext() );
1872  } else {
1873  self::dieDebug( __METHOD__,
1874  "Value in ApiBase::PARAM_HELP_MSG_PER_VALUE for $value is not valid" );
1875  }
1876  }
1877  }
1878 
1879  if ( isset( $settings[self::PARAM_HELP_MSG_APPEND] ) ) {
1880  if ( !is_array( $settings[self::PARAM_HELP_MSG_APPEND] ) ) {
1881  self::dieDebug( __METHOD__,
1882  'Value for ApiBase::PARAM_HELP_MSG_APPEND is not an array' );
1883  }
1884  foreach ( $settings[self::PARAM_HELP_MSG_APPEND] as $m ) {
1885  $m = self::makeMessage( $m, $this->getContext(),
1886  [ $prefix, $param, $name, $path ] );
1887  if ( $m ) {
1888  $msgs[$param][] = $m;
1889  } else {
1890  self::dieDebug( __METHOD__,
1891  'Value in ApiBase::PARAM_HELP_MSG_APPEND is not valid' );
1892  }
1893  }
1894  }
1895  }
1896 
1897  $this->getHookRunner()->onAPIGetParamDescriptionMessages( $this, $msgs );
1898 
1899  return $msgs;
1900  }
1901 
1911  protected function getHelpFlags() {
1912  $flags = [];
1913 
1914  if ( $this->isDeprecated() ) {
1915  $flags[] = 'deprecated';
1916  }
1917  if ( $this->isInternal() ) {
1918  $flags[] = 'internal';
1919  }
1920  if ( $this->isReadMode() ) {
1921  $flags[] = 'readrights';
1922  }
1923  if ( $this->isWriteMode() ) {
1924  $flags[] = 'writerights';
1925  }
1926  if ( $this->mustBePosted() ) {
1927  $flags[] = 'mustbeposted';
1928  }
1929 
1930  return $flags;
1931  }
1932 
1944  protected function getModuleSourceInfo() {
1945  global $IP;
1946 
1947  if ( $this->mModuleSource !== false ) {
1948  return $this->mModuleSource;
1949  }
1950 
1951  // First, try to find where the module comes from...
1952  $rClass = new ReflectionClass( $this );
1953  $path = $rClass->getFileName();
1954  if ( !$path ) {
1955  // No path known?
1956  $this->mModuleSource = null;
1957  return null;
1958  }
1959  $path = realpath( $path ) ?: $path;
1960 
1961  // Build map of extension directories to extension info
1962  if ( self::$extensionInfo === null ) {
1963  $extDir = $this->getConfig()->get( 'ExtensionDirectory' );
1964  self::$extensionInfo = [
1965  realpath( __DIR__ ) ?: __DIR__ => [
1966  'path' => $IP,
1967  'name' => 'MediaWiki',
1968  'license-name' => 'GPL-2.0-or-later',
1969  ],
1970  realpath( "$IP/extensions" ) ?: "$IP/extensions" => null,
1971  realpath( $extDir ) ?: $extDir => null,
1972  ];
1973  $keep = [
1974  'path' => null,
1975  'name' => null,
1976  'namemsg' => null,
1977  'license-name' => null,
1978  ];
1980  foreach ( $credits as $group ) {
1981  foreach ( $group as $ext ) {
1982  if ( !isset( $ext['path'] ) || !isset( $ext['name'] ) ) {
1983  // This shouldn't happen, but does anyway.
1984  continue;
1985  }
1986 
1987  $extpath = $ext['path'];
1988  if ( !is_dir( $extpath ) ) {
1989  $extpath = dirname( $extpath );
1990  }
1991  self::$extensionInfo[realpath( $extpath ) ?: $extpath] =
1992  array_intersect_key( $ext, $keep );
1993  }
1994  }
1995  }
1996 
1997  // Now traverse parent directories until we find a match or run out of
1998  // parents.
1999  do {
2000  if ( array_key_exists( $path, self::$extensionInfo ) ) {
2001  // Found it!
2002  $this->mModuleSource = self::$extensionInfo[$path];
2003  return $this->mModuleSource;
2004  }
2005 
2006  $oldpath = $path;
2007  $path = dirname( $path );
2008  } while ( $path !== $oldpath );
2009 
2010  // No idea what extension this might be.
2011  $this->mModuleSource = null;
2012  return null;
2013  }
2014 
2026  public function modifyHelp( array &$help, array $options, array &$tocData ) {
2027  }
2028 
2031  /************************************************************************/
2044  protected function explodeMultiValue( $value, $limit ) {
2045  wfDeprecated( __METHOD__, '1.35' );
2046  return ParamValidator::explodeMultiValue( $value, $limit );
2047  }
2048 
2067  protected function parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues,
2068  $allSpecifier = null, $limit1 = null, $limit2 = null
2069  ) {
2070  wfDeprecated( __METHOD__, '1.35' );
2071 
2072  if ( ( $value === '' || $value === "\x1f" ) && $allowMultiple ) {
2073  return [];
2074  }
2075  $limit1 = $limit1 ?: self::LIMIT_SML1;
2076  $limit2 = $limit2 ?: self::LIMIT_SML2;
2077 
2078  // This is a bit awkward, but we want to avoid calling canApiHighLimits()
2079  // because it unstubs $wgUser
2080  $valuesList = $this->explodeMultiValue( $value, $limit2 + 1 );
2081  $sizeLimit = count( $valuesList ) > $limit1 && $this->mMainModule->canApiHighLimits()
2082  ? $limit2
2083  : $limit1;
2084 
2085  if ( $allowMultiple && is_array( $allowedValues ) && $allSpecifier &&
2086  count( $valuesList ) === 1 && $valuesList[0] === $allSpecifier
2087  ) {
2088  return $allowedValues;
2089  }
2090 
2091  if ( count( $valuesList ) > $sizeLimit ) {
2092  $this->dieWithError(
2093  [ 'apierror-toomanyvalues', $valueName, $sizeLimit ],
2094  "too-many-$valueName"
2095  );
2096  }
2097 
2098  if ( !$allowMultiple && count( $valuesList ) != 1 ) {
2099  // T35482 - Allow entries with | in them for non-multiple values
2100  if ( in_array( $value, $allowedValues, true ) ) {
2101  return $value;
2102  }
2103 
2104  $values = array_map( function ( $v ) {
2105  return '<kbd>' . wfEscapeWikiText( $v ) . '</kbd>';
2106  }, $allowedValues );
2107  $this->dieWithError( [
2108  'apierror-multival-only-one-of',
2109  $valueName,
2110  Message::listParam( $values ),
2111  count( $values ),
2112  ], "multival_$valueName" );
2113  }
2114 
2115  if ( is_array( $allowedValues ) ) {
2116  // Check for unknown values
2117  $unknown = array_map( 'wfEscapeWikiText', array_diff( $valuesList, $allowedValues ) );
2118  if ( count( $unknown ) ) {
2119  if ( $allowMultiple ) {
2120  $this->addWarning( [
2121  'apiwarn-unrecognizedvalues',
2122  $valueName,
2123  Message::listParam( $unknown, 'comma' ),
2124  count( $unknown ),
2125  ] );
2126  } else {
2127  $this->dieWithError(
2128  [ 'apierror-unrecognizedvalue', $valueName, wfEscapeWikiText( $valuesList[0] ) ],
2129  "unknown_$valueName"
2130  );
2131  }
2132  }
2133  // Now throw them out
2134  $valuesList = array_intersect( $valuesList, $allowedValues );
2135  }
2136 
2137  return $allowMultiple ? $valuesList : $valuesList[0];
2138  }
2139 
2151  protected function validateLimit( $name, &$value, $min, $max, $botMax = null,
2152  $enforceLimits = false
2153  ) {
2154  wfDeprecated( __METHOD__, '1.35' );
2155  $value = $this->getMain()->getParamValidator()->validateValue(
2156  $this, $name, $value, [
2157  ParamValidator::PARAM_TYPE => 'limit',
2158  IntegerDef::PARAM_MIN => $min,
2159  IntegerDef::PARAM_MAX => $max,
2160  IntegerDef::PARAM_MAX2 => $botMax,
2161  IntegerDef::PARAM_IGNORE_RANGE => !$enforceLimits,
2162  ]
2163  );
2164  }
2165 
2173  protected function validateTimestamp( $value, $encParamName ) {
2174  wfDeprecated( __METHOD__, '1.35' );
2175 
2176  // Sigh.
2177  $name = $encParamName;
2178  $p = (string)$this->getModulePrefix();
2179  $l = strlen( $p );
2180  if ( $l && substr( $name, 0, $l ) === $p ) {
2181  $name = substr( $name, $l );
2182  }
2183 
2184  return $this->getMain()->getParamValidator()->validateValue(
2185  $this, $name, $value, [
2186  ParamValidator::PARAM_TYPE => 'timestamp',
2187  ]
2188  );
2189  }
2190 
2193 }
2194 
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:75
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:329
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:193
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:460
ApiBase\addWarning
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition: ApiBase.php:1334
ApiBase\getSummaryMessage
getSummaryMessage()
Return the summary message.
Definition: ApiBase.php:1663
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:1734
ApiBase\PARAM_REQUIRED
const PARAM_REQUIRED
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:74
StatusValue\getErrorsByType
getErrorsByType( $type)
Returns a list of status messages of the given type.
Definition: StatusValue.php:243
ApiBase\$hookContainer
HookContainer $hookContainer
Definition: ApiBase.php:55
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:152
ApiBase\parameterNotEmpty
parameterNotEmpty( $x)
Callback function used in requireOnlyOneParameter to check whether required parameters are set.
Definition: ApiBase.php:949
ApiBase\$mModuleSource
array null bool $mModuleSource
Definition: ApiBase.php:202
ApiBase\validateToken
validateToken( $token, array $params)
Validate the supplied token.
Definition: ApiBase.php:1109
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:1415
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:104
ApiBase\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiBase.php:275
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:77
ApiBase\validateTimestamp
validateTimestamp( $value, $encParamName)
Validate and normalize parameters of type 'timestamp'.
Definition: ApiBase.php:2173
ApiBase\$extensionInfo
static array $extensionInfo
Maps extension paths to info arrays.
Definition: ApiBase.php:178
ApiBase\getTitleOrPageId
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition: ApiBase.php:964
ApiBase\PARAM_TYPE
const PARAM_TYPE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:68
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:546
ApiBase\__construct
__construct(ApiMain $mainModule, $moduleName, $modulePrefix='')
Definition: ApiBase.php:209
ApiBase\getParameterFromSettings
getParameterFromSettings( $name, $settings, $parseLimit)
Using the settings determine the value for the given parameter.
Definition: ApiBase.php:1070
ApiBase\$blockMsgMap
static $blockMsgMap
$var array Map of web UI block messages to corresponding API messages and codes
Definition: ApiBase.php:184
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:308
ApiBase\mustBePosted
mustBePosted()
Indicates whether this module must be called with a POST request.
Definition: ApiBase.php:341
ApiBase\logFeatureUsage
logFeatureUsage( $feature)
Write logging information for API features to a debug log, for usage analysis.
Definition: ApiBase.php:1617
ApiBase\checkUserRightsAny
checkUserRightsAny( $rights, $user=null)
Helper function for permission-denied errors.
Definition: ApiBase.php:1517
ApiBase\shouldCheckMaxlag
shouldCheckMaxlag()
Indicates if this module needs maxlag to be checked.
Definition: ApiBase.php:310
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:1577
ApiBase\setContinuationManager
setContinuationManager(ApiContinuationManager $manager=null)
Set the continuation manager.
Definition: ApiBase.php:600
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:1676
ApiBase\PARAM_ISMULTI_LIMIT1
const PARAM_ISMULTI_LIMIT1
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:81
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:533
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1222
ApiBase\addBlockInfoToStatus
addBlockInfoToStatus(StatusValue $status, User $user=null)
Add block info to block messages in a Status.
Definition: ApiBase.php:1254
ApiBase\getHookContainer
getHookContainer()
Get a HookContainer, for running extension hooks or for hook metadata.
Definition: ApiBase.php:626
$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:1442
ApiBase\getDB
getDB()
Gets a default replica DB connection object.
Definition: ApiBase.php:574
ApiBase\addMessagesFromStatus
addMessagesFromStatus(StatusValue $status, $types=[ 'warning', 'error'], array $filter=[])
Add warnings and/or errors from a Status.
Definition: ApiBase.php:1394
ApiBase\makeMessage
static makeMessage( $msg, IContextSource $context, array $params=null)
Create a Message from a string or array.
Definition: ApiBase.php:1201
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:662
ApiBase\modifyHelp
modifyHelp(array &$help, array $options, array &$tocData)
Called from ApiHelp before the pieces are joined together and returned.
Definition: ApiBase.php:2026
ApiBase\PARAM_ALLOW_DUPLICATES
const PARAM_ALLOW_DUPLICATES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:72
ContextSource\getUser
getUser()
Definition: ContextSource.php:120
MediaWiki\Api\ApiHookRunner
This class provides an implementation of the hook interfaces used by the core Action API,...
Definition: ApiHookRunner.php:58
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:80
ApiBase\lacksSameOriginSecurity
lacksSameOriginSecurity()
Returns true if the current request breaks the same-origin policy.
Definition: ApiBase.php:474
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:111
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:991
ApiBase\getWebUITokenSalt
getWebUITokenSalt(array $params)
Fetch the salt used in the Web UI corresponding to this module.
Definition: ApiBase.php:395
Message\listParam
static listParam(array $list, $type='text')
Definition: Message.php:1123
ApiBase\isMain
isMain()
Returns true if this module is the main module ($this === $this->mMainModule), false otherwise.
Definition: ApiBase.php:451
ApiBase\isReadMode
isReadMode()
Indicates whether this module requires read rights.
Definition: ApiBase.php:318
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:50
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:508
ApiBase\getFinalParamDescription
getFinalParamDescription()
Get final parameter descriptions, after hooks have had a chance to tweak it as needed.
Definition: ApiBase.php:1765
ApiBase\PARAM_SENSITIVE
const PARAM_SENSITIVE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:79
ApiBase\PARAM_ISMULTI_LIMIT2
const PARAM_ISMULTI_LIMIT2
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:82
ExtensionRegistry\getInstance
static getInstance()
Definition: ExtensionRegistry.php:136
ApiBase\getFinalSummary
getFinalSummary()
Get final module summary.
Definition: ApiBase.php:1689
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:73
ApiBase\explodeMultiValue
explodeMultiValue( $value, $limit)
Split a multi-valued parameter string, like explode()
Definition: ApiBase.php:2044
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:71
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:154
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Definition: GlobalFunctions.php:1029
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:260
ApiBase\getFinalDescription
getFinalDescription()
Get final module description, after hooks have had a chance to tweak it as needed.
Definition: ApiBase.php:1705
wfTransactionalTimeLimit
wfTransactionalTimeLimit()
Set PHP's time limit to the larger of php.ini or $wgTransactionalTimeLimit.
Definition: GlobalFunctions.php:2689
ApiBase\getModulePath
getModulePath()
Get the path to this module.
Definition: ApiBase.php:490
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2464
ApiBase\LIMIT_BIG1
const LIMIT_BIG1
Fast query, standard limit.
Definition: ApiBase.php:162
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:66
ApiBase\$hookRunner
ApiHookRunner $hookRunner
Definition: ApiBase.php:58
ApiBase\PARAM_MAX
const PARAM_MAX
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:69
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:695
ApiBase\handleParamNormalization
handleParamNormalization( $paramName, $value, $rawValue)
Handle when a parameter was Unicode-normalized.
Definition: ApiBase.php:1096
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
ApiBase\isDeprecated
isDeprecated()
Indicates whether this module is deprecated.
Definition: ApiBase.php:350
ApiBase\requireAtLeastOneParameter
requireAtLeastOneParameter( $params,... $required)
Die if none of a certain set of parameters is set and not false.
Definition: ApiBase.php:892
ApiBase\$mReplicaDB
$mReplicaDB
Definition: ApiBase.php:196
MediaWiki\Block\AbstractBlock\getType
getType()
Get the type of target for this particular block.
Definition: AbstractBlock.php:434
MediaWiki\Block\AbstractBlock\isSitewide
isSitewide( $x=null)
Indicates that the block is a sitewide block.
Definition: AbstractBlock.php:214
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:78
ApiBase\ALL_DEFAULT_STRING
const ALL_DEFAULT_STRING
Definition: ApiBase.php:159
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:284
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:1029
ApiBase\needsToken
needsToken()
Returns the token type this module requires in order to execute.
Definition: ApiBase.php:382
ApiBase\getModulePrefix
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition: ApiBase.php:434
ApiBase\$mModuleName
string $mModuleName
Definition: ApiBase.php:195
ApiBase\setWatch
setWatch( $watch, $titleObj, $userOption=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
Definition: ApiBase.php:1151
ApiBase\getContinuationManager
getContinuationManager()
Get the continuation manager.
Definition: ApiBase.php:586
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:2151
ApiBase\addError
addError( $msg, $code=null, $data=null)
Add an error for this module without aborting.
Definition: ApiBase.php:1381
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:49
ApiBase\getWatchlistUser
getWatchlistUser( $params)
Gets the user for whom to get the watchlist.
Definition: ApiBase.php:1166
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:832
ApiBase\requireMaxOneParameter
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
Definition: ApiBase.php:867
ApiBase\dieContinueUsageIf
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
Definition: ApiBase.php:1595
SpecialVersion\getCredits
static getCredits(ExtensionRegistry $reg, Config $conf)
Definition: SpecialVersion.php:63
ApiBase\addDeprecation
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition: ApiBase.php:1348
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:168
ApiBase\encodeParamName
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition: ApiBase.php:673
ApiBase\dieReadOnly
dieReadOnly()
Helper function for readonly errors.
Definition: ApiBase.php:1501
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:175
WikiPage\newFromID
static newFromID( $id, $from='fromdb')
Constructor from a page id.
Definition: WikiPage.php:192
ApiBase\getPermissionManager
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition: ApiBase.php:616
ApiBase\useTransactionalTimeLimit
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: ApiBase.php:1272
ApiBase\getConditionalRequestData
getConditionalRequestData( $condition)
Returns data for HTTP conditional request mechanisms.
Definition: ApiBase.php:411
ApiBase\isWriteMode
isWriteMode()
Indicates whether this module requires write mode.
Definition: ApiBase.php:333
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1490
ApiBase\PARAM_HELP_MSG_INFO
const PARAM_HELP_MSG_INFO
(array) Specify additional information tags for the parameter.
Definition: ApiBase.php:121
WatchAction\doWatchOrUnwatch
static doWatchOrUnwatch( $watch, Title $title, User $user, string $expiry=null)
Watch or unwatch a page.
Definition: WatchAction.php:172
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:90
ApiBase\PARAM_VALUE_LINKS
const PARAM_VALUE_LINKS
Deprecated and unused.
Definition: ApiBase.php:128
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:155
ApiBase\filterIDs
filterIDs( $fields, array $ids)
Filter out-of-range values from a list of positive integer IDs.
Definition: ApiBase.php:1286
ApiBase\LIMIT_BIG2
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition: ApiBase.php:164
wfReadOnlyReason
wfReadOnlyReason()
Check if the site is in read-only mode and return the message if so.
Definition: GlobalFunctions.php:1141
ApiQueryTokens\getToken
static getToken(User $user, MediaWiki\Session\Session $session, $salt)
Get a token from a salt.
Definition: ApiQueryTokens.php:99
ApiBase\getModuleManager
getModuleManager()
Get the module manager, or null if this module has no sub-modules.
Definition: ApiBase.php:247
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:360
ApiBase\getModuleSourceInfo
getModuleSourceInfo()
Returns information about the source of this module, if known.
Definition: ApiBase.php:1944
$path
$path
Definition: NoLocalSettings.php:25
ApiBase\PARAM_DFLT
const PARAM_DFLT
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:66
ApiBase\getParameter
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
Definition: ApiBase.php:815
ApiBase\dieWithException
dieWithException(Throwable $exception, array $options=[])
Abort execution with an error derived from a throwable.
Definition: ApiBase.php:1427
ApiBase\dieStatus
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition: ApiBase.php:1473
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:426
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:67
Message
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition: Message.php:160
ApiBase\PARAM_MAX2
const PARAM_MAX2
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:70
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:300
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:2067
$help
$help
Definition: mcc.php:32
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:442
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:44
ApiBase\PARAM_MAX_CHARS
const PARAM_MAX_CHARS
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:84
MediaWiki\Block\AbstractBlock
Definition: AbstractBlock.php:37
ApiBase\checkTitleUserPermissions
checkTitleUserPermissions(LinkTarget $linkTarget, $actions, array $options=[])
Helper function for permission-denied errors.
Definition: ApiBase.php:1542
ApiBase\getTitleFromTitleOrPageId
getTitleFromTitleOrPageId( $params)
Get a Title object from a title or pageid param, if possible.
Definition: ApiBase.php:1001
User\IGNORE_USER_RIGHTS
const IGNORE_USER_RIGHTS
Definition: User.php:88
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
ApiBase\$mModulePrefix
string $mModulePrefix
Definition: ApiBase.php:195
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:137
ApiBase\PARAM_SUBMODULE_PARAM_PREFIX
const PARAM_SUBMODULE_PARAM_PREFIX
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:76
ApiBase\$mParamCache
array $mParamCache
Definition: ApiBase.php:200
ApiBase\PARAM_MAX_BYTES
const PARAM_MAX_BYTES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:83
ApiHelpParamValueMessage
Message subclass that prepends wikitext for API help.
Definition: ApiHelpParamValueMessage.php:33
ApiBase\getHookRunner
getHookRunner()
Get an ApiHookRunner for running core API hooks.
Definition: ApiBase.php:641
$IP
$IP
Definition: WebStart.php:49
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:54
Title\newFromID
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Definition: Title.php:473
ApiBase\dieDebug
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
Definition: ApiBase.php:1607
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:1226
ApiBase\getErrorFormatter
getErrorFormatter()
Get the error formatter.
Definition: ApiBase.php:560
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:919
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:166
ApiBase\getHelpFlags
getHelpFlags()
Generates the list of flags for the help screen and for action=paraminfo.
Definition: ApiBase.php:1911
ApiBase\$filterIDsCache
static stdClass[][] $filterIDsCache
Cache for self::filterIDs()
Definition: ApiBase.php:181