api: Minor cleanup of some Api Base classes
Change-Id: Ieff6b5be8340571fe0f45a9213813b69869c9f36
This commit is contained in:
parent
3107279180
commit
49a2f5cd12
2 changed files with 175 additions and 123 deletions
|
|
@ -39,15 +39,17 @@ use Wikimedia\ParamValidator\ParamValidator;
|
|||
use Wikimedia\ParamValidator\TypeDef\EnumDef;
|
||||
use Wikimedia\ParamValidator\TypeDef\IntegerDef;
|
||||
use Wikimedia\ParamValidator\TypeDef\StringDef;
|
||||
use Wikimedia\Rdbms\IReadableDatabase;
|
||||
use Wikimedia\Timestamp\TimestampException;
|
||||
|
||||
/**
|
||||
* This abstract class implements many basic API functions, and is the base of
|
||||
* all API classes.
|
||||
*
|
||||
* The class functions are divided into several areas of functionality:
|
||||
*
|
||||
* Module parameters: Derived classes can define getAllowedParams() to specify
|
||||
* which parameters to expect, how to parse and validate them.
|
||||
* which parameters to expect, how to parse and validate them.
|
||||
*
|
||||
* Self-documentation: code to allow the API to document its own state
|
||||
*
|
||||
|
|
@ -172,8 +174,8 @@ abstract class ApiBase extends ContextSource {
|
|||
public const PARAM_HELP_MSG_APPEND = 'api-param-help-msg-append';
|
||||
|
||||
/**
|
||||
* (array) Specify additional information tags for the parameter. Value is
|
||||
* an array of arrays, with the first member being the 'tag' for the info
|
||||
* (array) Specify additional information tags for the parameter.
|
||||
* The value is an array of arrays, with the first member being the 'tag' for the info
|
||||
* and the remaining members being the values. In the help, this is
|
||||
* formatted using apihelp-{$path}-paraminfo-{$tag}, which is passed
|
||||
* $1 = count, $2 = comma-joined list of values, $3 = module prefix.
|
||||
|
|
@ -193,10 +195,12 @@ abstract class ApiBase extends ContextSource {
|
|||
* with PARAM_ISMULTI, this is an array mapping parameter values to help
|
||||
* message specifiers (to be passed to ApiBase::makeMessage()) about
|
||||
* those values.
|
||||
*
|
||||
* When PARAM_TYPE is an array, any value not having a mapping will use
|
||||
* the apihelp-{$path}-paramvalue-{$param}-{$value} message. (This means
|
||||
* you can use an empty array to use the default message key for all
|
||||
* values.)
|
||||
*
|
||||
* @since 1.25
|
||||
* @note Use with PARAM_TYPE = 'string' is allowed since 1.40.
|
||||
*/
|
||||
|
|
@ -234,7 +238,7 @@ abstract class ApiBase extends ContextSource {
|
|||
public const LIMIT_SML2 = 500;
|
||||
|
||||
/**
|
||||
* getAllowedParams() flag: When set, the result could take longer to generate,
|
||||
* getAllowedParams() flag: When this is set, the result could take longer to generate,
|
||||
* but should be more thorough. E.g. get the list of generators for ApiSandBox extension
|
||||
* @since 1.21
|
||||
*/
|
||||
|
|
@ -312,7 +316,8 @@ abstract class ApiBase extends ContextSource {
|
|||
abstract public function execute();
|
||||
|
||||
/**
|
||||
* Get the module manager, or null if this module has no sub-modules
|
||||
* Get the module manager, or null if this module has no submodules.
|
||||
*
|
||||
* @since 1.21
|
||||
* @stable to override
|
||||
* @return ApiModuleManager|null
|
||||
|
|
@ -325,11 +330,13 @@ abstract class ApiBase extends ContextSource {
|
|||
* If the module may only be used with a certain format module,
|
||||
* it should override this method to return an instance of that formatter.
|
||||
* A value of null means the default format will be used.
|
||||
*
|
||||
* @note Do not use this just because you don't want to support non-json
|
||||
* formats. This should be used only when there is a fundamental
|
||||
* requirement for a specific format.
|
||||
*
|
||||
* @stable to override
|
||||
* @return ApiFormatBase|null Instance of a derived class of ApiFormatBase, or null
|
||||
* @return ApiFormatBase|null An instance of a class derived from ApiFormatBase, or null
|
||||
*/
|
||||
public function getCustomPrinter() {
|
||||
return null;
|
||||
|
|
@ -353,6 +360,7 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* Return links to more detailed help pages about the module.
|
||||
*
|
||||
* @since 1.25, returning boolean false is deprecated
|
||||
* @stable to override
|
||||
* @return string|array
|
||||
|
|
@ -375,13 +383,14 @@ abstract class ApiBase extends ContextSource {
|
|||
* @return array
|
||||
*/
|
||||
protected function getAllowedParams( /* $flags = 0 */ ) {
|
||||
// int $flags is not declared because it causes "Strict standards"
|
||||
// $flags is not declared because it causes "Strict standards"
|
||||
// warning. Most derived classes do not implement it.
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this module needs maxlag to be checked
|
||||
* Indicates if this module needs maxlag to be checked.
|
||||
*
|
||||
* @stable to override
|
||||
* @return bool
|
||||
*/
|
||||
|
|
@ -390,7 +399,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this module requires read rights
|
||||
* Indicates whether this module requires read rights.
|
||||
*
|
||||
* @stable to override
|
||||
* @return bool
|
||||
*/
|
||||
|
|
@ -399,7 +409,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this module requires write mode
|
||||
* Indicates whether this module requires write mode.
|
||||
*
|
||||
* This should return true for modules that may require synchronous database writes.
|
||||
* Modules that do not need such writes should also not rely on primary database access,
|
||||
|
|
@ -415,7 +425,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this module must be called with a POST request
|
||||
* Indicates whether this module must be called with a POST request.
|
||||
*
|
||||
* @stable to override
|
||||
* @return bool
|
||||
*/
|
||||
|
|
@ -424,7 +435,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this module is deprecated
|
||||
* Indicates whether this module is deprecated.
|
||||
*
|
||||
* @since 1.25
|
||||
* @stable to override
|
||||
* @return bool
|
||||
|
|
@ -434,8 +446,10 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this module is "internal"
|
||||
* Indicates whether this module is considered to be "internal".
|
||||
*
|
||||
* Internal API modules are not (yet) intended for 3rd party use and may be unstable.
|
||||
*
|
||||
* @since 1.25
|
||||
* @stable to override
|
||||
* @return bool
|
||||
|
|
@ -505,7 +519,8 @@ abstract class ApiBase extends ContextSource {
|
|||
/** @name Data access methods */
|
||||
|
||||
/**
|
||||
* Get the name of the module being executed by this instance
|
||||
* Get the name of the module being executed by this instance.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getModuleName() {
|
||||
|
|
@ -514,6 +529,7 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* Get parameter prefix (usually two letters or an empty string).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getModulePrefix() {
|
||||
|
|
@ -521,7 +537,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the main module
|
||||
* Get the main module.
|
||||
*
|
||||
* @return ApiMain
|
||||
*/
|
||||
public function getMain() {
|
||||
|
|
@ -531,6 +548,7 @@ abstract class ApiBase extends ContextSource {
|
|||
/**
|
||||
* Returns true if this module is the main module ($this === $this->mMainModule),
|
||||
* false otherwise.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMain() {
|
||||
|
|
@ -538,7 +556,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the parent of this module
|
||||
* Get the parent of this module.
|
||||
*
|
||||
* @stable to override
|
||||
* @since 1.25
|
||||
* @return ApiBase|null
|
||||
|
|
@ -571,14 +590,14 @@ abstract class ApiBase extends ContextSource {
|
|||
* @return bool
|
||||
*/
|
||||
public function lacksSameOriginSecurity() {
|
||||
// Main module has this method overridden, avoid infinite loops
|
||||
// The Main module has this method overridden, avoid infinite loops
|
||||
$this->dieIfMain( __METHOD__ );
|
||||
|
||||
return $this->getMain()->lacksSameOriginSecurity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to this module
|
||||
* Get the path to this module.
|
||||
*
|
||||
* @since 1.25
|
||||
* @return string
|
||||
|
|
@ -586,15 +605,17 @@ abstract class ApiBase extends ContextSource {
|
|||
public function getModulePath() {
|
||||
if ( $this->isMain() ) {
|
||||
return 'main';
|
||||
} elseif ( $this->getParent()->isMain() ) {
|
||||
return $this->getModuleName();
|
||||
} else {
|
||||
return $this->getParent()->getModulePath() . '+' . $this->getModuleName();
|
||||
}
|
||||
|
||||
if ( $this->getParent()->isMain() ) {
|
||||
return $this->getModuleName();
|
||||
}
|
||||
|
||||
return $this->getParent()->getModulePath() . '+' . $this->getModuleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a module from its module path
|
||||
* Get a module from its module path.
|
||||
*
|
||||
* @since 1.25
|
||||
* @param string $path
|
||||
|
|
@ -613,20 +634,21 @@ abstract class ApiBase extends ContextSource {
|
|||
$parts = explode( ' ', $path );
|
||||
}
|
||||
|
||||
$count = count( $parts );
|
||||
for ( $i = 0; $i < $count; $i++ ) {
|
||||
foreach ( $parts as $i => $v ) {
|
||||
$parent = $module;
|
||||
$manager = $parent->getModuleManager();
|
||||
if ( $manager === null ) {
|
||||
$errorPath = implode( '+', array_slice( $parts, 0, $i ) );
|
||||
$this->dieWithError( [ 'apierror-badmodule-nosubmodules', $errorPath ], 'badmodule' );
|
||||
}
|
||||
$module = $manager->getModule( $parts[$i] );
|
||||
$module = $manager->getModule( $v );
|
||||
|
||||
if ( $module === null ) {
|
||||
$errorPath = $i ? implode( '+', array_slice( $parts, 0, $i ) ) : $parent->getModuleName();
|
||||
$errorPath = $i
|
||||
? implode( '+', array_slice( $parts, 0, $i ) )
|
||||
: $parent->getModuleName();
|
||||
$this->dieWithError(
|
||||
[ 'apierror-badmodule-badsubmodule', $errorPath, wfEscapeWikiText( $parts[$i] ) ],
|
||||
[ 'apierror-badmodule-badsubmodule', $errorPath, wfEscapeWikiText( $v ) ],
|
||||
'badmodule'
|
||||
);
|
||||
}
|
||||
|
|
@ -636,11 +658,12 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the result object
|
||||
* Get the result object.
|
||||
*
|
||||
* @return ApiResult
|
||||
*/
|
||||
public function getResult() {
|
||||
// Main module has this method overridden, avoid infinite loops
|
||||
// The Main module has this method overridden, avoid infinite loops
|
||||
$this->dieIfMain( __METHOD__ );
|
||||
|
||||
return $this->getMain()->getResult();
|
||||
|
|
@ -651,16 +674,17 @@ abstract class ApiBase extends ContextSource {
|
|||
* @return ApiErrorFormatter
|
||||
*/
|
||||
public function getErrorFormatter() {
|
||||
// Main module has this method overridden, avoid infinite loops
|
||||
// The Main module has this method overridden, avoid infinite loops
|
||||
$this->dieIfMain( __METHOD__ );
|
||||
|
||||
return $this->getMain()->getErrorFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a default replica DB connection object
|
||||
* Gets a default replica DB connection object.
|
||||
*
|
||||
* @stable to override
|
||||
* @return \Wikimedia\Rdbms\IReadableDatabase
|
||||
* @return IReadableDatabase
|
||||
*/
|
||||
protected function getDB() {
|
||||
if ( !isset( $this->mReplicaDB ) ) {
|
||||
|
|
@ -676,7 +700,7 @@ abstract class ApiBase extends ContextSource {
|
|||
* @return ApiContinuationManager|null
|
||||
*/
|
||||
public function getContinuationManager() {
|
||||
// Main module has this method overridden, avoid infinite loops
|
||||
// The Main module has this method overridden, avoid infinite loops
|
||||
$this->dieIfMain( __METHOD__ );
|
||||
|
||||
return $this->getMain()->getContinuationManager();
|
||||
|
|
@ -686,7 +710,7 @@ abstract class ApiBase extends ContextSource {
|
|||
* @param ApiContinuationManager|null $manager
|
||||
*/
|
||||
public function setContinuationManager( ApiContinuationManager $manager = null ) {
|
||||
// Main module has this method overridden, avoid infinite loops
|
||||
// The Main module has this method overridden, avoid infinite loops
|
||||
$this->dieIfMain( __METHOD__ );
|
||||
|
||||
$this->getMain()->setContinuationManager( $manager );
|
||||
|
|
@ -719,7 +743,7 @@ abstract class ApiBase extends ContextSource {
|
|||
* Get an ApiHookRunner for running core API hooks.
|
||||
*
|
||||
* @internal This is for use by core only. Hook interfaces may be removed
|
||||
* without notice.
|
||||
* without notice.
|
||||
* @since 1.35
|
||||
* @return ApiHookRunner
|
||||
*/
|
||||
|
|
@ -750,7 +774,8 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* This method mangles parameter name based on the prefix supplied to the constructor.
|
||||
* Override this method to change parameter name during runtime
|
||||
* Override this method to change parameter name during runtime.
|
||||
*
|
||||
* @param string|string[] $paramName Parameter name
|
||||
* @return string|string[] Prefixed parameter name
|
||||
* @since 1.29 accepts an array of strings
|
||||
|
|
@ -760,14 +785,14 @@ abstract class ApiBase extends ContextSource {
|
|||
return array_map( function ( $name ) {
|
||||
return $this->mModulePrefix . $name;
|
||||
}, $paramName );
|
||||
} else {
|
||||
return $this->mModulePrefix . $paramName;
|
||||
}
|
||||
|
||||
return $this->mModulePrefix . $paramName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using getAllowedParams(), this function makes an array of the values
|
||||
* provided by the user, with key being the name of the variable, and
|
||||
* provided by the user, with the key being the name of the variable, and
|
||||
* value - validated value from user or default. limits will not be
|
||||
* parsed if $parseLimit is set to false; use this when the max
|
||||
* limit is not definitive yet, e.g. when getting revisions.
|
||||
|
|
@ -893,7 +918,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a value for the given parameter
|
||||
* Get a value for the given parameter.
|
||||
*
|
||||
* @param string $paramName Parameter name
|
||||
* @param bool $parseLimit See extractRequestParams()
|
||||
* @return mixed Parameter value
|
||||
|
|
@ -910,9 +936,9 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Die if none or more than one of a certain set of parameters is set and not false.
|
||||
* Die if 0 or more than one of a certain set of parameters is set and not false.
|
||||
*
|
||||
* @param array $params User provided set of parameters, as from $this->extractRequestParams()
|
||||
* @param array $params User provided parameter set, as from $this->extractRequestParams()
|
||||
* @param string ...$required Names of parameters of which exactly one must be set
|
||||
*/
|
||||
public function requireOnlyOneParameter( $params, ...$required ) {
|
||||
|
|
@ -945,10 +971,10 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Die if more than one of a certain set of parameters is set and not false.
|
||||
* Dies if more than one parameter from a certain set of parameters are set and not false.
|
||||
*
|
||||
* @param array $params User provided set of parameters, as from $this->extractRequestParams()
|
||||
* @param string ...$required Names of parameters of which at most one must be set
|
||||
* @param array $params User provided parameters set, as from $this->extractRequestParams()
|
||||
* @param string ...$required Parameter names that cannot have more than one set
|
||||
*/
|
||||
public function requireMaxOneParameter( $params, ...$required ) {
|
||||
$intersection = array_intersect( array_keys( array_filter( $params,
|
||||
|
|
@ -969,10 +995,10 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Die if none of a certain set of parameters is set and not false.
|
||||
* Die if 0 of a certain set of parameters is set and not false.
|
||||
*
|
||||
* @since 1.23
|
||||
* @param array $params User provided set of parameters, as from $this->extractRequestParams()
|
||||
* @param array $params User provided parameters set, as from $this->extractRequestParams()
|
||||
* @param string ...$required Names of parameters of which at least one must be set
|
||||
*/
|
||||
public function requireAtLeastOneParameter( $params, ...$required ) {
|
||||
|
|
@ -997,13 +1023,14 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* Die if any of the specified parameters were found in the query part of
|
||||
* the URL rather than the post body.
|
||||
* the URL rather than the HTTP post body contents.
|
||||
*
|
||||
* @since 1.28
|
||||
* @param string[] $params Parameters to check
|
||||
* @param string $prefix Set to 'noprefix' to skip calling $this->encodeParamName()
|
||||
*/
|
||||
public function requirePostedParameters( $params, $prefix = 'prefix' ) {
|
||||
// Skip if $wgDebugAPI is set or we're in internal mode
|
||||
// Skip if $wgDebugAPI is set, or if we're in internal mode
|
||||
if ( $this->getConfig()->get( MainConfigNames::DebugAPI ) ||
|
||||
$this->getMain()->isInternalMode() ) {
|
||||
return;
|
||||
|
|
@ -1028,7 +1055,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Callback function used in requireOnlyOneParameter to check whether required parameters are set
|
||||
* Callback function used in requireOnlyOneParameter to check whether required parameters are set.
|
||||
*
|
||||
* @param mixed $x Parameter to check is not null/false
|
||||
* @return bool
|
||||
|
|
@ -1038,14 +1065,14 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a WikiPage object from a title or pageid param, if possible.
|
||||
* Can die, if no param is set or if the title or page id is not valid.
|
||||
* Attempts to load a WikiPage object from a title or pageid parameter, if possible.
|
||||
* It can die if no param is set or if the title or page ID is not valid.
|
||||
*
|
||||
* @param array $params User provided set of parameters, as from $this->extractRequestParams()
|
||||
* @param array $params User provided parameter set, as from $this->extractRequestParams()
|
||||
* @param string|false $load Whether load the object's state from the database:
|
||||
* - false: don't load (if the pageid is given, it will still be loaded)
|
||||
* - 'fromdb': load from a replica DB
|
||||
* - 'fromdbmaster': load from the primary database
|
||||
* - false: don't load (if the pageid is given, it will still be loaded)
|
||||
* - 'fromdb': load from a replica DB
|
||||
* - 'fromdbmaster': load from the primary database
|
||||
* @return WikiPage
|
||||
*/
|
||||
public function getTitleOrPageId( $params, $load = false ) {
|
||||
|
|
@ -1080,11 +1107,11 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a Title object from a title or pageid param, if possible.
|
||||
* Can die, if no param is set or if the title or page id is not valid.
|
||||
* Get a Title object from a title or pageid param, if it is possible.
|
||||
* It can die if no param is set or if the title or page ID is not valid.
|
||||
*
|
||||
* @since 1.29
|
||||
* @param array $params User provided set of parameters, as from $this->extractRequestParams()
|
||||
* @param array $params User provided parameter set, as from $this->extractRequestParams()
|
||||
* @return Title
|
||||
*/
|
||||
public function getTitleFromTitleOrPageId( $params ) {
|
||||
|
|
@ -1098,7 +1125,9 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
// @phan-suppress-next-line PhanTypeMismatchReturnNullable T240141
|
||||
return $titleObj;
|
||||
} elseif ( isset( $params['pageid'] ) ) {
|
||||
}
|
||||
|
||||
if ( isset( $params['pageid'] ) ) {
|
||||
$titleObj = Title::newFromID( $params['pageid'] );
|
||||
if ( !$titleObj ) {
|
||||
$this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
|
||||
|
|
@ -1110,7 +1139,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Using the settings determine the value for the given parameter
|
||||
* Using the settings, determine the value for the given parameter.
|
||||
*
|
||||
* @param string $name Parameter name
|
||||
* @param array|mixed $settings Default value or an array of settings
|
||||
|
|
@ -1137,7 +1166,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handle when a parameter was Unicode-normalized
|
||||
* Handle when a parameter was Unicode-normalized.
|
||||
*
|
||||
* @since 1.28
|
||||
* @since 1.35 $paramName is prefixed
|
||||
* @internal For overriding by subclasses and use by ApiParamValidatorCallbacks only.
|
||||
|
|
@ -1306,24 +1336,26 @@ abstract class ApiBase extends ContextSource {
|
|||
$block = $user->getBlock();
|
||||
}
|
||||
|
||||
if ( $block ) {
|
||||
foreach ( $status->getErrors() as $error ) {
|
||||
$msgKey = $error['message'] instanceof MessageSpecifier ?
|
||||
$error['message']->getKey() :
|
||||
$error['message'];
|
||||
if ( isset( self::BLOCK_CODE_MAP[$msgKey] ) ) {
|
||||
$status->replaceMessage( $msgKey, ApiMessage::create(
|
||||
$error,
|
||||
$this->getBlockCode( $block ),
|
||||
[ 'blockinfo' => $this->getBlockDetails( $block ) ]
|
||||
) );
|
||||
}
|
||||
if ( !$block ) {
|
||||
return;
|
||||
}
|
||||
foreach ( $status->getErrors() as $error ) {
|
||||
$msgKey = $error['message'] instanceof MessageSpecifier ?
|
||||
$error['message']->getKey() :
|
||||
$error['message'];
|
||||
if ( isset( self::BLOCK_CODE_MAP[$msgKey] ) ) {
|
||||
$status->replaceMessage( $msgKey, ApiMessage::create(
|
||||
$error,
|
||||
$this->getBlockCode( $block ),
|
||||
[ 'blockinfo' => $this->getBlockDetails( $block ) ]
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call wfTransactionalTimeLimit() if this request was POSTed
|
||||
* Call wfTransactionalTimeLimit() if this request was POSTed.
|
||||
*
|
||||
* @since 1.26
|
||||
*/
|
||||
protected function useTransactionalTimeLimit() {
|
||||
|
|
@ -1346,10 +1378,11 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* Filter out-of-range values from a list of positive integer IDs
|
||||
*
|
||||
* @since 1.33
|
||||
* @param string[][] $fields Array of pairs of table and field to check
|
||||
* @param string[][] $fields Array of table and field pairs to check
|
||||
* @param (string|int)[] $ids IDs to filter. Strings in the array are
|
||||
* expected to be stringified ints.
|
||||
* expected to be stringified integers.
|
||||
* @return (string|int)[] Filtered IDs.
|
||||
*/
|
||||
protected function filterIDs( $fields, array $ids ) {
|
||||
|
|
@ -1388,8 +1421,9 @@ abstract class ApiBase extends ContextSource {
|
|||
/**
|
||||
* Add a warning for this module.
|
||||
*
|
||||
* Users should monitor this section to notice any changes in API. Multiple
|
||||
* calls to this function will result in multiple warning messages.
|
||||
* Users should monitor this section to notice any changes in the API.
|
||||
*
|
||||
* Multiple calls to this function will result in multiple warning messages.
|
||||
*
|
||||
* If $msg is not an ApiMessage, the message code will be derived from the
|
||||
* message key by stripping any "apiwarn-" or "apierror-" prefix.
|
||||
|
|
@ -1547,10 +1581,12 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
}
|
||||
|
||||
if ( $status instanceof PermissionStatus ) {
|
||||
if ( $status->isRateLimitExceeded() && !$status->hasMessage( 'apierror-ratelimited' ) ) {
|
||||
$status->fatal( ApiMessage::create( 'apierror-ratelimited', 'ratelimited' ) );
|
||||
}
|
||||
if (
|
||||
$status instanceof PermissionStatus
|
||||
&& $status->isRateLimitExceeded()
|
||||
&& !$status->hasMessage( 'apierror-ratelimited' )
|
||||
) {
|
||||
$status->fatal( ApiMessage::create( 'apierror-ratelimited', 'ratelimited' ) );
|
||||
}
|
||||
|
||||
// ApiUsageException needs a fatal status, but this method has
|
||||
|
|
@ -1573,7 +1609,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Helper function for readonly errors
|
||||
* Helper function for readonly errors.
|
||||
*
|
||||
* @throws ApiUsageException always
|
||||
* @return never
|
||||
|
|
@ -1587,7 +1623,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Helper function for permission-denied errors
|
||||
* Helper function for permission-denied errors.
|
||||
*
|
||||
* @since 1.29
|
||||
* @param string|string[] $rights
|
||||
* @param User|null $user deprecated since 1.36
|
||||
|
|
@ -1607,14 +1644,15 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Helper function for permission-denied errors
|
||||
* Helper function for permission-denied errors.
|
||||
*
|
||||
* @param PageIdentity|LinkTarget $pageIdentity deprecated passing LinkTarget since 1.36
|
||||
* @param string|string[] $actions
|
||||
* @param array $options Additional options
|
||||
* - user: (User) User to use rather than $this->getUser()
|
||||
* - autoblock: (bool, default false) Whether to spread autoblocks
|
||||
* @throws ApiUsageException if the user doesn't have all of the rights.
|
||||
* - user: (User) User to use rather than $this->getUser().
|
||||
* - autoblock: (bool, default false) Whether to spread autoblocks.
|
||||
*
|
||||
* @throws ApiUsageException if the user doesn't have all the necessary rights.
|
||||
*
|
||||
* @since 1.29
|
||||
* @since 1.33 Changed the third parameter from $user to $options.
|
||||
|
|
@ -1648,7 +1686,9 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* Will only set a warning instead of failing if the global $wgDebugAPI
|
||||
* is set to true. Otherwise behaves exactly as self::dieWithError().
|
||||
* is set to true.
|
||||
*
|
||||
* Otherwise, it behaves exactly as self::dieWithError().
|
||||
*
|
||||
* @since 1.29
|
||||
* @param string|array|Message $msg
|
||||
|
|
@ -1667,7 +1707,7 @@ abstract class ApiBase extends ContextSource {
|
|||
|
||||
/**
|
||||
* Parse the 'continue' parameter in the usual format and validate the types of each part,
|
||||
* or die with the 'badcontinue' error if the format, types, or number of parts is wrong.
|
||||
* or die with the 'badcontinue' error if the format, types, or the number of parts is wrong.
|
||||
*
|
||||
* @param string $continue Value of 'continue' parameter obtained from extractRequestParams()
|
||||
* @param string[] $types Types of the expected parts in order, 'string', 'int' or 'timestamp'
|
||||
|
|
@ -1721,7 +1761,8 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Internal code errors should be reported with this method
|
||||
* Internal code errors should be reported with this method.
|
||||
*
|
||||
* @param string $method Method or function name
|
||||
* @param string $message Error message
|
||||
* @throws MWException always
|
||||
|
|
@ -1734,6 +1775,7 @@ abstract class ApiBase extends ContextSource {
|
|||
/**
|
||||
* Write logging information for API features to a debug log, for usage
|
||||
* analysis.
|
||||
*
|
||||
* @note Consider using $this->addDeprecation() instead to both warn and log.
|
||||
* @param string $feature Feature being used.
|
||||
*/
|
||||
|
|
@ -1750,7 +1792,7 @@ abstract class ApiBase extends ContextSource {
|
|||
$request = $this->getRequest();
|
||||
$ctx = [
|
||||
'feature' => $feature,
|
||||
// Spaces to underscores in 'username' for historical reasons.
|
||||
// Replace spaces with underscores in 'username' for historical reasons.
|
||||
'username' => str_replace( ' ', '_', $this->getUser()->getName() ),
|
||||
'clientip' => $request->getIP(),
|
||||
'referer' => (string)$request->getHeader( 'Referer' ),
|
||||
|
|
@ -1805,7 +1847,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get final module summary
|
||||
* Get the final module summary
|
||||
*
|
||||
* @since 1.30
|
||||
* @stable to override
|
||||
|
|
@ -1820,7 +1862,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get final module description, after hooks have had a chance to tweak it as
|
||||
* Get the final module description, after hooks have had a chance to tweak it as
|
||||
* needed.
|
||||
*
|
||||
* @since 1.25, returns Message[] rather than string[]
|
||||
|
|
@ -1848,7 +1890,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get final list of parameters, after hooks have had a chance to
|
||||
* Get the final list of parameters, after hooks have had a chance to
|
||||
* tweak it as needed.
|
||||
*
|
||||
* @param int $flags Zero or more flags like GET_VALUES_FOR_HELP
|
||||
|
|
@ -1964,8 +2006,10 @@ abstract class ApiBase extends ContextSource {
|
|||
'ApiBase::PARAM_HELP_MSG_PER_VALUE is not valid' );
|
||||
}
|
||||
$isArrayOfStrings = is_array( $settings[ParamValidator::PARAM_TYPE] )
|
||||
|| $settings[ParamValidator::PARAM_TYPE] === 'string'
|
||||
&& ( $settings[ParamValidator::PARAM_ISMULTI] ?? false );
|
||||
|| (
|
||||
$settings[ParamValidator::PARAM_TYPE] === 'string'
|
||||
&& ( $settings[ParamValidator::PARAM_ISMULTI] ?? false )
|
||||
);
|
||||
if ( !$isArrayOfStrings ) {
|
||||
self::dieDebug( __METHOD__,
|
||||
'ApiBase::PARAM_HELP_MSG_PER_VALUE may only be used when ' .
|
||||
|
|
@ -2023,7 +2067,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates the list of flags for the help screen and for action=paraminfo
|
||||
* Generates the list of flags for the help screen and for action=paraminfo.
|
||||
*
|
||||
* Corresponding messages: api-help-flag-deprecated,
|
||||
* api-help-flag-internal, api-help-flag-readrights,
|
||||
|
|
@ -2057,10 +2101,10 @@ abstract class ApiBase extends ContextSource {
|
|||
* Returns information about the source of this module, if known
|
||||
*
|
||||
* Returned array is an array with the following keys:
|
||||
* - path: Install path
|
||||
* - name: Extension name, or "MediaWiki" for core
|
||||
* - namemsg: (optional) i18n message key for a display name
|
||||
* - license-name: (optional) Name of license
|
||||
* - path: Install path
|
||||
* - name: Extension name, or "MediaWiki" for core
|
||||
* - namemsg: (optional) i18n message key for a display name
|
||||
* - license-name: (optional) Name of license
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
|
|
@ -2079,7 +2123,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
$path = realpath( $path ) ?: $path;
|
||||
|
||||
// Build map of extension directories to extension info
|
||||
// Build a map of extension directories to extension info
|
||||
if ( self::$extensionInfo === null ) {
|
||||
$extDir = $this->getConfig()->get( MainConfigNames::ExtensionDirectory );
|
||||
$baseDir = $this->getConfig()->get( MainConfigNames::BaseDirectory );
|
||||
|
|
@ -2116,8 +2160,7 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
}
|
||||
|
||||
// Now traverse parent directories until we find a match or run out of
|
||||
// parents.
|
||||
// Now traverse parent directories until we find a match or run out of parents.
|
||||
do {
|
||||
if ( array_key_exists( $path, self::$extensionInfo ) ) {
|
||||
// Found it!
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
|
||||
/**
|
||||
* If $format ends with 'fm', pretty-print the output in HTML.
|
||||
*
|
||||
* @param ApiMain $main
|
||||
* @param string $format Format name
|
||||
*/
|
||||
|
|
@ -59,7 +60,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
* Overriding class returns the MIME type that should be sent to the client.
|
||||
*
|
||||
* When getIsHtml() returns true, the return value here is used for syntax
|
||||
* highlighting but the client sees text/html.
|
||||
* highlighting, but the client sees text/html.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
|
|
@ -67,26 +68,30 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
|
||||
/**
|
||||
* Return a filename for this module's output.
|
||||
*
|
||||
* @note If $this->getIsWrappedHtml() || $this->getIsHtml(), you'll very
|
||||
* likely want to fall back to this class's version.
|
||||
* @since 1.27
|
||||
* @return string Generally this should be "api-result.$ext"
|
||||
* @return string Generally, this should be "api-result.$ext"
|
||||
*/
|
||||
public function getFilename() {
|
||||
if ( $this->getIsWrappedHtml() ) {
|
||||
return 'api-result-wrapped.json';
|
||||
} elseif ( $this->getIsHtml() ) {
|
||||
return 'api-result.html';
|
||||
} else {
|
||||
$mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer();
|
||||
$ext = $mimeAnalyzer->getExtensionFromMimeTypeOrNull( $this->getMimeType() )
|
||||
?? strtolower( $this->mFormat );
|
||||
return "api-result.$ext";
|
||||
}
|
||||
|
||||
if ( $this->getIsHtml() ) {
|
||||
return 'api-result.html';
|
||||
}
|
||||
|
||||
$mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer();
|
||||
$ext = $mimeAnalyzer->getExtensionFromMimeTypeOrNull( $this->getMimeType() )
|
||||
?? strtolower( $this->mFormat );
|
||||
return "api-result.$ext";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internal format name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormat() {
|
||||
|
|
@ -95,8 +100,8 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
|
||||
/**
|
||||
* Returns true when the HTML pretty-printer should be used.
|
||||
* The default implementation assumes that formats ending with 'fm'
|
||||
* should be formatted in HTML.
|
||||
* The default implementation assumes that formats ending with 'fm' should be formatted in HTML.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsHtml() {
|
||||
|
|
@ -104,7 +109,8 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true when the special wrapped mode is enabled.
|
||||
* Returns true when the special-wrapped mode is enabled.
|
||||
*
|
||||
* @since 1.27
|
||||
* @return bool
|
||||
*/
|
||||
|
|
@ -122,7 +128,8 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether the printer is disabled
|
||||
* Whether the printer is disabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDisabled() {
|
||||
|
|
@ -132,8 +139,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
/**
|
||||
* Whether this formatter can handle printing API errors.
|
||||
*
|
||||
* If this returns false, then on API errors the default printer will be
|
||||
* instantiated.
|
||||
* If this returns false, then when API errors occur, the default printer will be instantiated.
|
||||
* @since 1.23
|
||||
* @return bool
|
||||
*/
|
||||
|
|
@ -145,6 +151,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
* Ignore request parameters, force a default.
|
||||
*
|
||||
* Used as a fallback if errors are being thrown.
|
||||
*
|
||||
* @since 1.26
|
||||
*/
|
||||
public function forceDefaultParams() {
|
||||
|
|
@ -320,7 +327,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
);
|
||||
} else {
|
||||
// API handles its own clickjacking protection.
|
||||
// Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
|
||||
// Note: $wgBreakFrames will still override $wgApiFrameOptions for format mode.
|
||||
$out->setPreventClickjacking( false );
|
||||
$out->output();
|
||||
}
|
||||
|
|
@ -335,6 +342,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
|
||||
/**
|
||||
* Append text to the output buffer.
|
||||
*
|
||||
* @param string $text
|
||||
*/
|
||||
public function printText( $text ) {
|
||||
|
|
@ -343,6 +351,7 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
|
||||
/**
|
||||
* Get the contents of the buffer.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBuffer() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue