MediaWiki 1.43.1
ApiBlock.php
Go to the documentation of this file.
1<?php
23namespace MediaWiki\Api;
24
46
53class ApiBlock extends ApiBase {
54
57
58 private BlockPermissionCheckerFactory $blockPermissionCheckerFactory;
59 private BlockUserFactory $blockUserFactory;
60 private TitleFactory $titleFactory;
61 private UserIdentityLookup $userIdentityLookup;
62 private WatchedItemStoreInterface $watchedItemStore;
63 private BlockUtils $blockUtils;
64 private BlockActionInfo $blockActionInfo;
65
66 public function __construct(
67 ApiMain $main,
68 string $action,
69 BlockPermissionCheckerFactory $blockPermissionCheckerFactory,
70 BlockUserFactory $blockUserFactory,
71 TitleFactory $titleFactory,
72 UserIdentityLookup $userIdentityLookup,
73 WatchedItemStoreInterface $watchedItemStore,
74 BlockUtils $blockUtils,
75 BlockActionInfo $blockActionInfo,
76 WatchlistManager $watchlistManager,
77 UserOptionsLookup $userOptionsLookup
78 ) {
79 parent::__construct( $main, $action );
80
81 $this->blockPermissionCheckerFactory = $blockPermissionCheckerFactory;
82 $this->blockUserFactory = $blockUserFactory;
83 $this->titleFactory = $titleFactory;
84 $this->userIdentityLookup = $userIdentityLookup;
85 $this->watchedItemStore = $watchedItemStore;
86 $this->blockUtils = $blockUtils;
87 $this->blockActionInfo = $blockActionInfo;
88
89 // Variables needed in ApiWatchlistTrait trait
90 $this->watchlistExpiryEnabled = $this->getConfig()->get( MainConfigNames::WatchlistExpiry );
91 $this->watchlistMaxDuration =
93 $this->watchlistManager = $watchlistManager;
94 $this->userOptionsLookup = $userOptionsLookup;
95 }
96
103 public function execute() {
104 $this->checkUserRightsAny( 'block' );
105 $params = $this->extractRequestParams();
106 $this->requireOnlyOneParameter( $params, 'user', 'userid' );
107
108 // Make sure $target contains a parsed target
109 if ( $params['user'] !== null ) {
110 $target = $params['user'];
111 } else {
112 $target = $this->userIdentityLookup->getUserIdentityByUserId( $params['userid'] );
113 if ( !$target ) {
114 $this->dieWithError( [ 'apierror-nosuchuserid', $params['userid'] ], 'nosuchuserid' );
115 }
116 }
117 [ $target, $targetType ] = $this->blockUtils->parseBlockTarget( $target );
118
119 if (
120 $params['noemail'] &&
121 !$this->blockPermissionCheckerFactory
122 ->newBlockPermissionChecker(
123 $target,
124 $this->getAuthority()
125 )
126 ->checkEmailPermissions()
127 ) {
128 $this->dieWithError( 'apierror-cantblock-email' );
129 }
130
131 $restrictions = [];
132 if ( $params['partial'] ) {
133 $pageRestrictions = array_map(
134 [ PageRestriction::class, 'newFromTitle' ],
135 (array)$params['pagerestrictions']
136 );
137
138 $namespaceRestrictions = array_map( static function ( $id ) {
139 return new NamespaceRestriction( 0, $id );
140 }, (array)$params['namespacerestrictions'] );
141 $restrictions = array_merge( $pageRestrictions, $namespaceRestrictions );
142
144 $actionRestrictions = array_map( function ( $action ) {
145 return new ActionRestriction( 0, $this->blockActionInfo->getIdFromAction( $action ) );
146 }, (array)$params['actionrestrictions'] );
147 $restrictions = array_merge( $restrictions, $actionRestrictions );
148 }
149 }
150
151 $status = $this->blockUserFactory->newBlockUser(
152 $target,
153 $this->getAuthority(),
154 $params['expiry'],
155 $params['reason'],
156 [
157 'isCreateAccountBlocked' => $params['nocreate'],
158 'isEmailBlocked' => $params['noemail'],
159 'isHardBlock' => !$params['anononly'],
160 'isAutoblocking' => $params['autoblock'],
161 'isUserTalkEditBlocked' => !$params['allowusertalk'],
162 'isHideUser' => $params['hidename'],
163 'isPartial' => $params['partial'],
164 ],
165 $restrictions,
166 $params['tags']
167 )->placeBlock( $params['reblock'] );
168
169 if ( !$status->isOK() ) {
170 $this->dieStatus( $status );
171 }
172
173 $block = $status->value;
174
175 $watchlistExpiry = $this->getExpiryFromParams( $params );
176 $userPage = Title::makeTitle( NS_USER, $block->getTargetName() );
177
178 if ( $params['watchuser'] && $targetType !== AbstractBlock::TYPE_RANGE ) {
179 $this->setWatch( 'watch', $userPage, $this->getUser(), null, $watchlistExpiry );
180 }
181
182 $res = [];
183
184 $res['user'] = $block->getTargetName();
185 $res['userID'] = $target instanceof UserIdentity ? $target->getId() : 0;
186
187 if ( $block instanceof DatabaseBlock ) {
188 $res['expiry'] = ApiResult::formatExpiry( $block->getExpiry(), 'infinite' );
189 $res['id'] = $block->getId();
190 } else {
191 # should be unreachable
192 $res['expiry'] = ''; // @codeCoverageIgnore
193 $res['id'] = ''; // @codeCoverageIgnore
194 }
195
196 $res['reason'] = $params['reason'];
197 $res['anononly'] = $params['anononly'];
198 $res['nocreate'] = $params['nocreate'];
199 $res['autoblock'] = $params['autoblock'];
200 $res['noemail'] = $params['noemail'];
201 $res['hidename'] = $block->getHideName();
202 $res['allowusertalk'] = $params['allowusertalk'];
203 $res['watchuser'] = $params['watchuser'];
204 if ( $watchlistExpiry ) {
205 $expiry = $this->getWatchlistExpiry(
206 $this->watchedItemStore,
207 $userPage,
208 $this->getUser()
209 );
210 $res['watchlistexpiry'] = $expiry;
211 }
212 $res['partial'] = $params['partial'];
213 $res['pagerestrictions'] = $params['pagerestrictions'];
214 $res['namespacerestrictions'] = $params['namespacerestrictions'];
216 $res['actionrestrictions'] = $params['actionrestrictions'];
217 }
218
219 $this->getResult()->addValue( null, $this->getModuleName(), $res );
220 }
221
222 public function mustBePosted() {
223 return true;
224 }
225
226 public function isWriteMode() {
227 return true;
228 }
229
230 public function getAllowedParams() {
231 $params = [
232 'user' => [
233 ParamValidator::PARAM_TYPE => 'user',
234 UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'ip', 'temp', 'cidr', 'id' ],
235 ],
236 'userid' => [
237 ParamValidator::PARAM_TYPE => 'integer',
238 ParamValidator::PARAM_DEPRECATED => true,
239 ],
240 'expiry' => 'never',
241 'reason' => '',
242 'anononly' => false,
243 'nocreate' => false,
244 'autoblock' => false,
245 'noemail' => false,
246 'hidename' => false,
247 'allowusertalk' => false,
248 'reblock' => false,
249 'watchuser' => false,
250 ];
251
252 // Params appear in the docs in the order they are defined,
253 // which is why this is here and not at the bottom.
254 // @todo Find better way to support insertion at arbitrary position
255 if ( $this->watchlistExpiryEnabled ) {
256 $params += [
257 'watchlistexpiry' => [
258 ParamValidator::PARAM_TYPE => 'expiry',
259 ExpiryDef::PARAM_MAX => $this->watchlistMaxDuration,
260 ExpiryDef::PARAM_USE_MAX => true,
261 ]
262 ];
263 }
264
265 $params += [
266 'tags' => [
267 ParamValidator::PARAM_TYPE => 'tags',
268 ParamValidator::PARAM_ISMULTI => true,
269 ],
270 'partial' => false,
271 'pagerestrictions' => [
272 ParamValidator::PARAM_TYPE => 'title',
273 TitleDef::PARAM_MUST_EXIST => true,
274
275 // TODO: TitleDef returns instances of TitleValue when PARAM_RETURN_OBJECT is
276 // truthy. At the time of writing,
277 // MediaWiki\Block\Restriction\PageRestriction::newFromTitle accepts either
278 // string or instance of Title.
279 //TitleDef::PARAM_RETURN_OBJECT => true,
280
281 ParamValidator::PARAM_ISMULTI => true,
282 ParamValidator::PARAM_ISMULTI_LIMIT1 => 10,
283 ParamValidator::PARAM_ISMULTI_LIMIT2 => 10,
284 ],
285 'namespacerestrictions' => [
286 ParamValidator::PARAM_ISMULTI => true,
287 ParamValidator::PARAM_TYPE => 'namespace',
288 ],
289 ];
290
292 $params += [
293 'actionrestrictions' => [
294 ParamValidator::PARAM_ISMULTI => true,
295 ParamValidator::PARAM_TYPE => array_keys(
296 $this->blockActionInfo->getAllBlockActions()
297 ),
298 ],
299 ];
300 }
301
302 return $params;
303 }
304
305 public function needsToken() {
306 return 'csrf';
307 }
308
309 protected function getExamplesMessages() {
310 // phpcs:disable Generic.Files.LineLength
311 return [
312 'action=block&user=192.0.2.5&expiry=3%20days&reason=First%20strike&token=123ABC'
313 => 'apihelp-block-example-ip-simple',
314 'action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate=&autoblock=&noemail=&token=123ABC'
315 => 'apihelp-block-example-user-complex',
316 ];
317 // phpcs:enable
318 }
319
320 public function getHelpUrls() {
321 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Block';
322 }
323}
324
326class_alias( ApiBlock::class, 'ApiBlock' );
const NS_USER
Definition Defines.php:67
array $params
The job parameters.
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:76
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1577
checkUserRightsAny( $rights)
Helper function for permission-denied errors.
Definition ApiBase.php:1692
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:571
getResult()
Get the result object.
Definition ApiBase.php:710
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1632
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:851
requireOnlyOneParameter( $params,... $required)
Die if 0 or more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:990
API module that facilitates the blocking of users.
Definition ApiBlock.php:53
__construct(ApiMain $main, string $action, BlockPermissionCheckerFactory $blockPermissionCheckerFactory, BlockUserFactory $blockUserFactory, TitleFactory $titleFactory, UserIdentityLookup $userIdentityLookup, WatchedItemStoreInterface $watchedItemStore, BlockUtils $blockUtils, BlockActionInfo $blockActionInfo, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup)
Definition ApiBlock.php:66
execute()
Blocks the user specified in the parameters for the given expiry, with the given reason,...
Definition ApiBlock.php:103
getHelpUrls()
Return links to more detailed help pages about the module.
Definition ApiBlock.php:320
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition ApiBlock.php:230
getExamplesMessages()
Returns usage examples for this module.
Definition ApiBlock.php:309
mustBePosted()
Indicates whether this module must be called with a POST request.
Definition ApiBlock.php:222
isWriteMode()
Indicates whether this module requires write access to the wiki.
Definition ApiBlock.php:226
needsToken()
Returns the token type this module requires in order to execute.
Definition ApiBlock.php:305
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:78
static formatExpiry( $expiry, $infinity='infinity')
Format an expiry timestamp for API output.
Defines the actions that can be blocked by a partial block.
Backend class for blocking utils.
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
Restriction for partial blocks of actions.
A class containing constants representing the names of configuration variables.
const WatchlistExpiry
Name constant for the WatchlistExpiry setting, for use with Config::get()
const WatchlistExpiryMaxDuration
Name constant for the WatchlistExpiryMaxDuration setting, for use with Config::get()
const EnablePartialActionBlocks
Name constant for the EnablePartialActionBlocks setting, for use with Config::get()
Type definition for page titles.
Definition TitleDef.php:22
Type definition for user types.
Definition UserDef.php:27
Creates Title objects.
Represents a title within MediaWiki.
Definition Title.php:78
Provides access to user options.
Service for formatting and validating API parameters.
Type definition for expiry timestamps.
Definition ExpiryDef.php:17
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Interface for objects representing user identity.
getId( $wikiId=self::LOCAL)
getExpiryFromParams(array $params)
Get formatted expiry from the given parameters, or null if no expiry was provided.
setWatch(string $watch, PageIdentity $page, User $user, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
getWatchlistExpiry(WatchedItemStoreInterface $store, PageIdentity $page, UserIdentity $user)
Get existing expiry from the database.