X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiBase.php;h=b8dd4641d900ac1831db8cfcb120e40fe048a993;hb=e5e91cb0fa2c9d96c6ccac00d3d0c4760b2bccb1;hp=a40593f6bd5ab8dc99d2954e30a5647fbf854487;hpb=1676448145f28cdf5bf399b13a39d909d7e0bb77;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index a40593f6bd..b8dd4641d9 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -180,6 +180,12 @@ abstract class ApiBase extends ContextSource { */ const PARAM_ALL = 17; + /** + * (int[]) When PARAM_TYPE is 'namespace', include these as additional possible values. + * @since 1.29 + */ + const PARAM_EXTRA_NAMESPACES = 18; + /**@}*/ const ALL_DEFAULT_STRING = '*'; @@ -899,6 +905,34 @@ abstract class ApiBase extends ContextSource { return $pageObj; } + /** + * 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. + * + * @since 1.29 + * @param array $params + * @return Title + */ + public function getTitleFromTitleOrPageId( $params ) { + $this->requireOnlyOneParameter( $params, 'title', 'pageid' ); + + $titleObj = null; + if ( isset( $params['title'] ) ) { + $titleObj = Title::newFromText( $params['title'] ); + if ( !$titleObj || $titleObj->isExternal() ) { + $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] ); + } + return $titleObj; + } elseif ( isset( $params['pageid'] ) ) { + $titleObj = Title::newFromID( $params['pageid'] ); + if ( !$titleObj ) { + $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] ); + } + } + + return $titleObj; + } + /** * Return true if we're to watch the page, false if not, null if no change. * @param string $watchlist Valid values: 'watch', 'unwatch', 'preferences', 'nochange' @@ -953,44 +987,41 @@ abstract class ApiBase extends ContextSource { // Some classes may decide to change parameter names $encParamName = $this->encodeParamName( $paramName ); + // Shorthand if ( !is_array( $paramSettings ) ) { - $default = $paramSettings; - $multi = false; - $type = gettype( $paramSettings ); - $dupes = false; - $deprecated = false; - $required = false; - $allowAll = false; - } else { - $default = isset( $paramSettings[self::PARAM_DFLT] ) - ? $paramSettings[self::PARAM_DFLT] - : null; - $multi = isset( $paramSettings[self::PARAM_ISMULTI] ) - ? $paramSettings[self::PARAM_ISMULTI] - : false; - $type = isset( $paramSettings[self::PARAM_TYPE] ) - ? $paramSettings[self::PARAM_TYPE] - : null; - $dupes = isset( $paramSettings[self::PARAM_ALLOW_DUPLICATES] ) - ? $paramSettings[self::PARAM_ALLOW_DUPLICATES] - : false; - $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] ) - ? $paramSettings[self::PARAM_DEPRECATED] - : false; - $required = isset( $paramSettings[self::PARAM_REQUIRED] ) - ? $paramSettings[self::PARAM_REQUIRED] - : false; - $allowAll = isset( $paramSettings[self::PARAM_ALL] ) - ? $paramSettings[self::PARAM_ALL] - : false; - - // When type is not given, and no choices, the type is the same as $default - if ( !isset( $type ) ) { - if ( isset( $default ) ) { - $type = gettype( $default ); - } else { - $type = 'NULL'; // allow everything - } + $paramSettings = [ + self::PARAM_DFLT => $paramSettings, + ]; + } + + $default = isset( $paramSettings[self::PARAM_DFLT] ) + ? $paramSettings[self::PARAM_DFLT] + : null; + $multi = isset( $paramSettings[self::PARAM_ISMULTI] ) + ? $paramSettings[self::PARAM_ISMULTI] + : false; + $type = isset( $paramSettings[self::PARAM_TYPE] ) + ? $paramSettings[self::PARAM_TYPE] + : null; + $dupes = isset( $paramSettings[self::PARAM_ALLOW_DUPLICATES] ) + ? $paramSettings[self::PARAM_ALLOW_DUPLICATES] + : false; + $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] ) + ? $paramSettings[self::PARAM_DEPRECATED] + : false; + $required = isset( $paramSettings[self::PARAM_REQUIRED] ) + ? $paramSettings[self::PARAM_REQUIRED] + : false; + $allowAll = isset( $paramSettings[self::PARAM_ALL] ) + ? $paramSettings[self::PARAM_ALL] + : false; + + // When type is not given, and no choices, the type is the same as $default + if ( !isset( $type ) ) { + if ( isset( $default ) ) { + $type = gettype( $default ); + } else { + $type = 'NULL'; // allow everything } } @@ -1034,6 +1065,11 @@ abstract class ApiBase extends ContextSource { if ( isset( $value ) && $type == 'namespace' ) { $type = MWNamespace::getValidNamespaces(); + if ( isset( $paramSettings[self::PARAM_EXTRA_NAMESPACES] ) && + is_array( $paramSettings[self::PARAM_EXTRA_NAMESPACES] ) + ) { + $type = array_merge( $type, $paramSettings[self::PARAM_EXTRA_NAMESPACES] ); + } // By default, namespace parameters allow ALL_DEFAULT_STRING to be used to specify // all namespaces. $allowAll = true; @@ -1627,6 +1663,12 @@ abstract class ApiBase extends ContextSource { 'autoblocked', [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] ) ); + } elseif ( is_array( $error ) && $error[0] === 'systemblockedtext' && $user->getBlock() ) { + $status->fatal( ApiMessage::create( + 'apierror-systemblocked', + 'blocked', + [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] + ) ); } else { call_user_func_array( [ $status, 'fatal' ], (array)$error ); } @@ -1723,6 +1765,20 @@ abstract class ApiBase extends ContextSource { throw ApiUsageException::newWithMessage( $this, $msg, $code, $data, $httpCode ); } + /** + * Abort execution with an error derived from an exception + * + * @since 1.29 + * @param Exception|Throwable $exception See ApiErrorFormatter::getMessageFromException() + * @param array $options See ApiErrorFormatter::getMessageFromException() + * @throws ApiUsageException always + */ + public function dieWithException( $exception, array $options = [] ) { + $this->dieWithError( + $this->getErrorFormatter()->getMessageFromException( $exception, $options ) + ); + } + /** * Adds a warning to the output, else dies * @@ -1916,7 +1972,10 @@ abstract class ApiBase extends ContextSource { */ public function getFinalDescription() { $desc = $this->getDescription(); - Hooks::run( 'APIGetDescription', [ &$this, &$desc ] ); + + // Avoid PHP 7.1 warning of passing $this by reference + $apiModule = $this; + Hooks::run( 'APIGetDescription', [ &$apiModule, &$desc ] ); $desc = self::escapeWikiText( $desc ); if ( is_array( $desc ) ) { $desc = implode( "\n", $desc ); @@ -1964,7 +2023,9 @@ abstract class ApiBase extends ContextSource { ] + ( isset( $params['token'] ) ? $params['token'] : [] ); } - Hooks::run( 'APIGetAllowedParams', [ &$this, &$params, $flags ] ); + // Avoid PHP 7.1 warning of passing $this by reference + $apiModule = $this; + Hooks::run( 'APIGetAllowedParams', [ &$apiModule, &$params, $flags ] ); return $params; } @@ -1982,7 +2043,10 @@ abstract class ApiBase extends ContextSource { $path = $this->getModulePath(); $desc = $this->getParamDescription(); - Hooks::run( 'APIGetParamDescription', [ &$this, &$desc ] ); + + // Avoid PHP 7.1 warning of passing $this by reference + $apiModule = $this; + Hooks::run( 'APIGetParamDescription', [ &$apiModule, &$desc ] ); if ( !$desc ) { $desc = []; @@ -2229,7 +2293,7 @@ abstract class ApiBase extends ContextSource { * "apihelp-{$this->getModulePath()}-description". * * @deprecated since 1.25 - * @return Message|string|array + * @return Message|string|array|false */ protected function getDescription() { return false; @@ -2450,6 +2514,7 @@ abstract class ApiBase extends ContextSource { 'confirmedittext' => 'confirmedittext', 'blockedtext' => 'apierror-blocked', 'autoblockedtext' => 'apierror-autoblocked', + 'systemblockedtext' => 'apierror-systemblocked', 'actionthrottledtext' => 'apierror-ratelimited', 'alreadyrolled' => 'alreadyrolled', 'cantrollback' => 'cantrollback',