api: Minor cleanup of some Api Base classes

Change-Id: Ieff6b5be8340571fe0f45a9213813b69869c9f36
This commit is contained in:
Reedy 2023-07-25 19:54:30 +01:00
parent 3107279180
commit 49a2f5cd12
2 changed files with 175 additions and 123 deletions

View file

@ -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!

View file

@ -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() {