X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fapi%2FApiBase.php;h=4898385cfc12e7db63294d9f558f274db99d25fb;hp=32156d8b92c5bd2045c844b7666d7dc4e4b3f48e;hb=4691389fa46f79cbeaf2daffda407cf7daa66fd4;hpb=36de1c7c818b696b06e7f170a1d9d0b943441d05 diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index 32156d8b92..4898385cfc 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -268,6 +268,17 @@ abstract class ApiBase extends ContextSource { /** @var array Maps extension paths to info arrays */ private static $extensionInfo = null; + /** @var int[][][] Cache for self::filterIDs() */ + private static $filterIDsCache = []; + + /** $var array Map of web UI block messages to corresponding API messages and codes */ + private static $blockMsgMap = [ + 'blockedtext' => [ 'apierror-blocked', 'blocked' ], + 'blockedtext-partial' => [ 'apierror-blocked', 'blocked' ], + 'autoblockedtext' => [ 'apierror-autoblocked', 'autoblocked' ], + 'systemblockedtext' => [ 'apierror-systemblocked', 'blocked' ], + ]; + /** @var ApiMain */ private $mMainModule; /** @var string */ @@ -1154,6 +1165,7 @@ abstract class ApiBase extends ContextSource { } $value = $this->getMain()->getCheck( $encParamName ); + $provided = $value; } elseif ( $type == 'upload' ) { if ( isset( $default ) ) { // Having a default value is not allowed @@ -1166,6 +1178,7 @@ abstract class ApiBase extends ContextSource { self::dieDebug( __METHOD__, "Multi-values not supported for $encParamName" ); } $value = $this->getMain()->getUpload( $encParamName ); + $provided = $value->exists(); if ( !$value->exists() ) { // This will get the value without trying to normalize it // (because trying to normalize a large binary file @@ -1180,6 +1193,7 @@ abstract class ApiBase extends ContextSource { } } else { $value = $this->getMain()->getVal( $encParamName, $default ); + $provided = $this->getMain()->getCheck( $encParamName ); if ( isset( $value ) && $type == 'namespace' ) { $type = MWNamespace::getValidNamespaces(); @@ -1268,7 +1282,7 @@ abstract class ApiBase extends ContextSource { } } } else { - $value = intval( $value ); + $value = (int)$value; if ( !is_null( $min ) || !is_null( $max ) ) { $this->validateLimit( $paramName, $value, $min, $max, null, $enforceLimits ); } @@ -1297,7 +1311,7 @@ abstract class ApiBase extends ContextSource { : $paramSettings[self::PARAM_MAX]; $this->getResult()->addParsedLimit( $this->getModuleName(), $value ); } else { - $value = intval( $value ); + $value = (int)$value; $this->validateLimit( $paramName, $value, @@ -1370,7 +1384,7 @@ abstract class ApiBase extends ContextSource { } // Set a warning if a deprecated parameter has been passed - if ( $deprecated && $value !== false ) { + if ( $deprecated && $provided ) { $feature = $encParamName; $m = $this; while ( !$m->isMain() ) { @@ -1384,7 +1398,7 @@ abstract class ApiBase extends ContextSource { } // Set a warning if a deprecated parameter value has been passed - $usedDeprecatedValues = $deprecatedValues && $value !== false + $usedDeprecatedValues = $deprecatedValues && $provided ? array_intersect( array_keys( $deprecatedValues ), (array)$value ) : []; if ( $usedDeprecatedValues ) { @@ -1791,28 +1805,9 @@ abstract class ApiBase extends ContextSource { $status = Status::newGood(); foreach ( $errors as $error ) { - if ( is_array( $error ) && $error[0] === 'blockedtext' && $user->getBlock() ) { - $status->fatal( ApiMessage::create( - 'apierror-blocked', - 'blocked', - [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] - ) ); - } elseif ( is_array( $error ) && $error[0] === 'blockedtext-partial' && $user->getBlock() ) { - $status->fatal( ApiMessage::create( - 'apierror-blocked-partial', - 'blocked', - [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] - ) ); - } elseif ( is_array( $error ) && $error[0] === 'autoblockedtext' && $user->getBlock() ) { - $status->fatal( ApiMessage::create( - 'apierror-autoblocked', - 'autoblocked', - [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] - ) ); - } elseif ( is_array( $error ) && $error[0] === 'systemblockedtext' && $user->getBlock() ) { - $status->fatal( ApiMessage::create( - 'apierror-systemblocked', - 'blocked', + if ( is_array( $error ) && isset( self::$blockMsgMap[$error[0]] ) && $user->getBlock() ) { + list( $msg, $code ) = self::$blockMsgMap[$error[0]]; + $status->fatal( ApiMessage::create( $msg, $code, [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] ) ); } else { @@ -1822,6 +1817,26 @@ abstract class ApiBase extends ContextSource { return $status; } + /** + * Add block info to block messages in a Status + * @since 1.33 + * @param StatusValue $status + * @param User|null $user + */ + public function addBlockInfoToStatus( StatusValue $status, User $user = null ) { + if ( $user === null ) { + $user = $this->getUser(); + } + + foreach ( self::$blockMsgMap as $msg => list( $apiMsg, $code ) ) { + if ( $status->hasMessage( $msg ) && $user->getBlock() ) { + $status->replaceMessage( $msg, ApiMessage::create( $apiMsg, $code, + [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ] + ) ); + } + } + } + /** * Call wfTransactionalTimeLimit() if this request was POSTed * @since 1.26 @@ -1832,6 +1847,41 @@ abstract class ApiBase extends ContextSource { } } + /** + * Filter out-of-range values from a list of positive integer IDs + * @since 1.33 + * @param array $fields Array of pairs of table and field to check + * @param (string|int)[] $ids IDs to filter. Strings in the array are + * expected to be stringified ints. + * @return (string|int)[] Filtered IDs. + */ + protected function filterIDs( $fields, array $ids ) { + $min = INF; + $max = 0; + foreach ( $fields as list( $table, $field ) ) { + if ( isset( self::$filterIDsCache[$table][$field] ) ) { + $row = self::$filterIDsCache[$table][$field]; + } else { + $row = $this->getDB()->selectRow( + $table, + [ + 'min_id' => "MIN($field)", + 'max_id' => "MAX($field)", + ], + '', + __METHOD__ + ); + self::$filterIDsCache[$table][$field] = $row; + } + $min = min( $min, $row->min_id ); + $max = max( $max, $row->max_id ); + } + return array_filter( $ids, function ( $id ) use ( $min, $max ) { + return ( is_int( $id ) && $id >= 0 || ctype_digit( $id ) ) + && $id >= $min && $id <= $max; + } ); + } + /**@}*/ /************************************************************************//** @@ -1911,9 +1961,14 @@ abstract class ApiBase extends ContextSource { * @since 1.29 * @param StatusValue $status * @param string[] $types 'warning' and/or 'error' + * @param string[] $filter Message keys to filter out (since 1.33) */ - public function addMessagesFromStatus( StatusValue $status, $types = [ 'warning', 'error' ] ) { - $this->getErrorFormatter()->addMessagesFromStatus( $this->getModulePath(), $status, $types ); + public function addMessagesFromStatus( + StatusValue $status, $types = [ 'warning', 'error' ], array $filter = [] + ) { + $this->getErrorFormatter()->addMessagesFromStatus( + $this->getModulePath(), $status, $types, $filter + ); } /** @@ -2019,6 +2074,7 @@ abstract class ApiBase extends ContextSource { $status = $newStatus; } + $this->addBlockInfoToStatus( $status ); throw new ApiUsageException( $this, $status ); } @@ -2056,15 +2112,21 @@ abstract class ApiBase extends ContextSource { /** * Helper function for permission-denied errors * @since 1.29 + * @since 1.33 Changed the third parameter from $user to $options. * @param Title $title * @param string|string[] $actions - * @param User|null $user + * @param array $options Additional options + * - user: (User) User to use rather than $this->getUser() + * - autoblock: (bool, default false) Whether to spread autoblocks + * For compatibility, passing a User object is treated as the value for the 'user' option. * @throws ApiUsageException if the user doesn't have all of the rights. */ - public function checkTitleUserPermissions( Title $title, $actions, $user = null ) { - if ( !$user ) { - $user = $this->getUser(); + public function checkTitleUserPermissions( Title $title, $actions, $options = [] ) { + if ( !is_array( $options ) ) { + wfDeprecated( '$user as the third parameter to ' . __METHOD__, '1.33' ); + $options = [ 'user' => $options ]; } + $user = $options['user'] ?? $this->getUser(); $errors = []; foreach ( (array)$actions as $action ) { @@ -2077,6 +2139,10 @@ abstract class ApiBase extends ContextSource { $this->trackBlockNotices( $errors ); } + if ( !empty( $options['autoblock'] ) ) { + $user->spreadAnyEditBlock(); + } + $this->dieStatus( $this->errorArrayToStatus( $errors, $user ) ); } }