/** @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 */
}
}
} else {
- $value = intval( $value );
+ $value = (int)$value;
if ( !is_null( $min ) || !is_null( $max ) ) {
$this->validateLimit( $paramName, $value, $min, $max, null, $enforceLimits );
}
: $paramSettings[self::PARAM_MAX];
$this->getResult()->addParsedLimit( $this->getModuleName(), $value );
} else {
- $value = intval( $value );
+ $value = (int)$value;
$this->validateLimit(
$paramName,
$value,
$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 ) ) {
+ $error = [ $error ];
+ }
+ if ( is_string( $error[0] ) && 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 {
- $status->fatal( ...(array)$error );
+ $status->fatal( ...$error );
}
}
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
$status = $newStatus;
}
+ $this->addBlockInfoToStatus( $status );
throw new ApiUsageException( $this, $status );
}
/**
* 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 ) {
$this->trackBlockNotices( $errors );
}
+ if ( !empty( $options['autoblock'] ) ) {
+ $user->spreadAnyEditBlock();
+ }
+
$this->dieStatus( $this->errorArrayToStatus( $errors, $user ) );
}
}
* @param string $feature Feature being used.
*/
public function logFeatureUsage( $feature ) {
+ static $loggedFeatures = [];
+
+ // Only log each feature once per request. We can get multiple calls from calls to
+ // extractRequestParams() with different values for 'parseLimit', for example.
+ if ( isset( $loggedFeatures[$feature] ) ) {
+ return;
+ }
+ $loggedFeatures[$feature] = true;
+
$request = $this->getRequest();
- $s = '"' . addslashes( $feature ) . '"' .
- ' "' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) . '"' .
- ' "' . $request->getIP() . '"' .
- ' "' . addslashes( $request->getHeader( 'Referer' ) ) . '"' .
- ' "' . addslashes( $this->getMain()->getUserAgent() ) . '"';
- wfDebugLog( 'api-feature-usage', $s, 'private' );
+ $ctx = [
+ 'feature' => $feature,
+ // Spaces to underscores in 'username' for historical reasons.
+ 'username' => str_replace( ' ', '_', $this->getUser()->getName() ),
+ 'ip' => $request->getIP(),
+ 'referer' => (string)$request->getHeader( 'Referer' ),
+ 'agent' => $this->getMain()->getUserAgent(),
+ ];
+
+ // Text string is deprecated. Remove (or replace with just $feature) in MW 1.34.
+ $s = '"' . addslashes( $ctx['feature'] ) . '"' .
+ ' "' . wfUrlencode( $ctx['username'] ) . '"' .
+ ' "' . $ctx['ip'] . '"' .
+ ' "' . addslashes( $ctx['referer'] ) . '"' .
+ ' "' . addslashes( $ctx['agent'] ) . '"';
+
+ wfDebugLog( 'api-feature-usage', $s, 'private', $ctx );
}
/**@}*/