MediaWiki  master
AbstractBlock.php
Go to the documentation of this file.
1 <?php
21 namespace MediaWiki\Block;
22 
24 use IContextSource;
26 use IP;
28 use Message;
29 use RequestContext;
30 use Title;
31 use User;
32 
36 abstract class AbstractBlock {
41  protected $mReason;
42 
44  protected $reason;
45 
50  public $mTimestamp;
51 
56  public $mExpiry = '';
57 
59  protected $mBlockEmail = false;
60 
62  protected $allowUsertalk = false;
63 
65  protected $blockCreateAccount = false;
66 
71  public $mHideName = false;
72 
74  protected $target;
75 
80  protected $type;
81 
83  protected $blocker;
84 
86  protected $isSitewide = true;
87 
88  # TYPE constants
89  const TYPE_USER = 1;
90  const TYPE_IP = 2;
91  const TYPE_RANGE = 3;
92  const TYPE_AUTO = 4;
93  const TYPE_ID = 5;
94 
106  public function __construct( array $options = [] ) {
107  $defaults = [
108  'address' => '',
109  'by' => null,
110  'reason' => '',
111  'timestamp' => '',
112  'byText' => '',
113  'hideName' => false,
114  ];
115 
116  $options += $defaults;
117 
118  $this->setTarget( $options['address'] );
119 
120  if ( $options['by'] ) {
121  # Local user
122  $this->setBlocker( User::newFromId( $options['by'] ) );
123  } else {
124  # Foreign user
125  $this->setBlocker( $options['byText'] );
126  }
127 
128  $this->setReason( $options['reason'] );
129  $this->setTimestamp( wfTimestamp( TS_MW, $options['timestamp'] ) );
130  $this->setHideName( (bool)$options['hideName'] );
131  }
132 
138  public function getBy() {
139  return $this->getBlocker()->getId();
140  }
141 
147  public function getByName() {
148  return $this->getBlocker()->getName();
149  }
150 
155  public function getId() {
156  return null;
157  }
158 
166  abstract public function getIdentifier();
167 
178  public function getReason() {
179  $language = RequestContext::getMain()->getLanguage();
180  return $this->reason->message->inLanguage( $language )->plain();
181  }
182 
189  public function getReasonComment() {
190  return $this->reason;
191  }
192 
199  public function setReason( $reason ) {
201  }
202 
209  public function getHideName() {
210  return $this->mHideName;
211  }
212 
219  public function setHideName( $hideName ) {
220  $this->mHideName = $hideName;
221  }
222 
232  public function isSitewide( $x = null ) {
233  return wfSetVar( $this->isSitewide, $x );
234  }
235 
245  public function isCreateAccountBlocked( $x = null ) {
246  return wfSetVar( $this->blockCreateAccount, $x );
247  }
248 
258  public function isEmailBlocked( $x = null ) {
259  return wfSetVar( $this->mBlockEmail, $x );
260  }
261 
271  public function isUsertalkEditAllowed( $x = null ) {
272  return wfSetVar( $this->allowUsertalk, $x );
273  }
274 
286  public function appliesToRight( $right ) {
287  $config = RequestContext::getMain()->getConfig();
288  $blockDisablesLogin = $config->get( 'BlockDisablesLogin' );
289 
290  $res = null;
291  switch ( $right ) {
292  case 'edit':
293  // TODO: fix this case to return proper value
294  $res = true;
295  break;
296  case 'createaccount':
297  $res = $this->isCreateAccountBlocked();
298  break;
299  case 'sendemail':
300  $res = $this->isEmailBlocked();
301  break;
302  case 'upload':
303  // Until T6995 is completed
304  $res = $this->isSitewide();
305  break;
306  case 'read':
307  $res = false;
308  break;
309  case 'purge':
310  $res = false;
311  break;
312  }
313  if ( !$res && $blockDisablesLogin ) {
314  // If a block would disable login, then it should
315  // prevent any right that all users cannot do
316  $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
317  $anon = new User;
318  $res = $permissionManager->userHasRight( $anon, $right ) ? $res : true;
319  }
320 
321  return $res;
322  }
323 
333  public function prevents( $action, $x = null ) {
334  $config = RequestContext::getMain()->getConfig();
335  $blockDisablesLogin = $config->get( 'BlockDisablesLogin' );
336  $blockAllowsUTEdit = $config->get( 'BlockAllowsUTEdit' );
337 
338  $res = null;
339  switch ( $action ) {
340  case 'edit':
341  # For now... <evil laugh>
342  $res = true;
343  break;
344  case 'createaccount':
345  $res = wfSetVar( $this->blockCreateAccount, $x );
346  break;
347  case 'sendemail':
348  $res = wfSetVar( $this->mBlockEmail, $x );
349  break;
350  case 'upload':
351  // Until T6995 is completed
352  $res = $this->isSitewide();
353  break;
354  case 'editownusertalk':
355  // NOTE: this check is not reliable on partial blocks
356  // since partially blocked users are always allowed to edit
357  // their own talk page unless a restriction exists on the
358  // page or User_talk: namespace
359  wfSetVar( $this->allowUsertalk, $x === null ? null : !$x );
360  $res = !$this->isUsertalkEditAllowed();
361 
362  // edit own user talk can be disabled by config
363  if ( !$blockAllowsUTEdit ) {
364  $res = true;
365  }
366  break;
367  case 'read':
368  $res = false;
369  break;
370  case 'purge':
371  $res = false;
372  break;
373  }
374  if ( !$res && $blockDisablesLogin ) {
375  // If a block would disable login, then it should
376  // prevent any action that all users cannot do
377  $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
378  $anon = new User;
379  $res = $permissionManager->userHasRight( $anon, $action ) ? $res : true;
380  }
381 
382  return $res;
383  }
384 
396  public static function parseTarget( $target ) {
397  # We may have been through this before
398  if ( $target instanceof User ) {
399  if ( IP::isValid( $target->getName() ) ) {
400  return [ $target, self::TYPE_IP ];
401  } else {
402  return [ $target, self::TYPE_USER ];
403  }
404  } elseif ( $target === null ) {
405  return [ null, null ];
406  }
407 
408  $target = trim( $target );
409 
410  if ( IP::isValid( $target ) ) {
411  # We can still create a User if it's an IP address, but we need to turn
412  # off validation checking (which would exclude IP addresses)
413  return [
415  self::TYPE_IP
416  ];
417 
418  } elseif ( IP::isValidRange( $target ) ) {
419  # Can't create a User from an IP range
420  return [ IP::sanitizeRange( $target ), self::TYPE_RANGE ];
421  }
422 
423  # Consider the possibility that this is not a username at all
424  # but actually an old subpage (T31797)
425  if ( strpos( $target, '/' ) !== false ) {
426  # An old subpage, drill down to the user behind it
427  $target = explode( '/', $target )[0];
428  }
429 
430  $userObj = User::newFromName( $target );
431  if ( $userObj instanceof User ) {
432  # Note that since numbers are valid usernames, a $target of "12345" will be
433  # considered a User. If you want to pass a block ID, prepend a hash "#12345",
434  # since hash characters are not valid in usernames or titles generally.
435  return [ $userObj, self::TYPE_USER ];
436 
437  } elseif ( preg_match( '/^#\d+$/', $target ) ) {
438  # Autoblock reference in the form "#12345"
439  return [ substr( $target, 1 ), self::TYPE_AUTO ];
440 
441  } else {
442  return [ null, null ];
443  }
444  }
445 
450  public function getType() {
451  return $this->type;
452  }
453 
464  public function getTargetAndType() {
465  return [ $this->getTarget(), $this->getType() ];
466  }
467 
474  public function getTarget() {
475  return $this->target;
476  }
477 
484  public function getExpiry() {
485  return $this->mExpiry;
486  }
487 
494  public function setExpiry( $expiry ) {
495  $this->mExpiry = $expiry;
496  }
497 
504  public function getTimestamp() {
505  return $this->mTimestamp;
506  }
507 
514  public function setTimestamp( $timestamp ) {
515  $this->mTimestamp = $timestamp;
516  }
517 
522  public function setTarget( $target ) {
523  list( $this->target, $this->type ) = static::parseTarget( $target );
524  }
525 
530  public function getBlocker() {
531  return $this->blocker;
532  }
533 
538  public function setBlocker( $user ) {
539  if ( is_string( $user ) ) {
540  $user = User::newFromName( $user, false );
541  }
542 
543  if ( $user->isAnon() && User::isUsableName( $user->getName() ) ) {
544  throw new InvalidArgumentException(
545  'Blocker must be a local user or a name that cannot be a local user'
546  );
547  }
548 
549  $this->blocker = $user;
550  }
551 
562  $message = MediaWikiServices::getInstance()
563  ->getBlockErrorFormatter()->getMessage(
564  $this,
565  $context->getUser(),
566  $context->getLanguage(),
567  $context->getRequest()->getIP()
568  );
569  return array_merge( [ [ $message->getKey() ], $message->getParams() ] );
570  }
571 
583  ->getBlockErrorFormatter()->getMessage(
584  $this,
585  $context->getUser(),
586  $context->getLanguage(),
587  $context->getRequest()->getIp()
588  )->getParams();
589  }
590 
618  public function appliesToUsertalk( Title $usertalk = null ) {
619  if ( !$usertalk ) {
620  if ( $this->target instanceof User ) {
621  $usertalk = $this->target->getTalkPage();
622  } else {
623  throw new InvalidArgumentException(
624  '$usertalk must be provided if block target is not a user/IP'
625  );
626  }
627  }
628 
629  if ( $usertalk->getNamespace() !== NS_USER_TALK ) {
630  throw new InvalidArgumentException(
631  '$usertalk must be a user talk page'
632  );
633  }
634 
635  if ( !$this->isSitewide() ) {
636  if ( $this->appliesToPage( $usertalk->getArticleID() ) ) {
637  return true;
638  }
639  if ( !$this->appliesToNamespace( NS_USER_TALK ) ) {
640  return false;
641  }
642  }
643 
644  // This is a type of block which uses the ipb_allow_usertalk
645  // flag. The flag can still be overridden by global configs.
646  $config = RequestContext::getMain()->getConfig();
647  if ( !$config->get( 'BlockAllowsUTEdit' ) ) {
648  return true;
649  }
650  return !$this->isUsertalkEditAllowed();
651  }
652 
664  public function appliesToTitle( Title $title ) {
665  return $this->isSitewide();
666  }
667 
676  public function appliesToNamespace( $ns ) {
677  return $this->isSitewide();
678  }
679 
693  public function appliesToPage( $pageId ) {
694  return $this->isSitewide();
695  }
696 
706  public function shouldTrackWithCookie( $isAnon ) {
707  wfDeprecated( __METHOD__, '1.34' );
708  return false;
709  }
710 
717  public function appliesToPasswordReset() {
718  return $this->isCreateAccountBlocked();
719  }
720 
721 }
isUsertalkEditAllowed( $x=null)
Get or set the flag indicating whether this block blocks the target from editing their own user talk ...
Config $config
Definition: MediaWiki.php:39
static isValidRange( $ipRange)
Validate an IP range (valid address with a valid CIDR prefix).
Definition: IP.php:125
isCreateAccountBlocked( $x=null)
Get or set the flag indicating whether this block blocks the target from creating an account...
getBy()
Get the user id of the blocking sysop.
The Message class provides methods which fulfil two basic services:
Definition: Message.php:162
appliesToUsertalk(Title $usertalk=null)
Determine whether the block allows the user to edit their own user talk page.
string $action
Cache what action this request is.
Definition: MediaWiki.php:42
setBlocker( $user)
Set the user who implemented (or will implement) this block.
static getInstance()
Returns the global default instance of the top level service locator.
static newUnsavedComment( $comment, array $data=null)
Create a new, unsaved CommentStoreComment.
static sanitizeRange( $range)
Gets rid of unneeded numbers in quad-dotted/octet IP strings For example, 127.111.113.151/24 -> 127.111.113.0/24.
Definition: IP.php:712
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
getName()
Get the user name, or the IP of an anonymous user.
Definition: User.php:2230
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:51
getTargetAndType()
Get the target and target type for this particular block.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
static getMain()
Get the RequestContext object associated with the main request.
IContextSource $context
Definition: MediaWiki.php:37
shouldTrackWithCookie( $isAnon)
Check if the block should be tracked with a cookie.
getIdentifier()
Get the information that identifies this block, such that a user could look up everything that can be...
static sanitizeIP( $ip)
Convert an IP into a verbose, uppercase, normalized form.
Definition: IP.php:139
appliesToPasswordReset()
Check if the block prevents a user from resetting their password.
isSitewide( $x=null)
Indicates that the block is a sitewide block.
static isValid( $ip)
Validate an IP address.
Definition: IP.php:111
appliesToTitle(Title $title)
Checks if a block applies to a particular title.
getPermissionsError(IContextSource $context)
Get the key and parameters for the corresponding error message.
__construct(array $options=[])
Create a new block with specified parameters on a user, IP or IP range.
getBlockErrorParams(IContextSource $context)
Get block information used in different block error messages.
static isUsableName( $name)
Usernames which fail to pass this function will be blocked from user login and new account registrati...
Definition: User.php:970
isEmailBlocked( $x=null)
Get or set the flag indicating whether this block blocks the target from sending emails.
getReasonComment()
Get the reason for creating the block.
prevents( $action, $x=null)
Get/set whether the block prevents a given action.
getType()
Get the type of target for this particular block.
appliesToRight( $right)
Determine whether the block prevents a given right.
getTimestamp()
Get the timestamp indicating when the block was created.
wfSetVar(&$dest, $source, $force=false)
Sets dest to source and returns the original value of dest If source is NULL, it just returns the val...
setTimestamp( $timestamp)
Set the timestamp indicating when the block was created.
getBlocker()
Get the user who implemented this block.
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition: User.php:543
getHideName()
Get whether the block hides the target&#39;s username.
static parseTarget( $target)
From an existing block, get the target and the type of target.
appliesToPage( $pageId)
Checks if a block applies to a particular page.
int null $type
AbstractBlock::TYPE_ constant.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
setHideName( $hideName)
Set whether ths block hides the target&#39;s username.
setTarget( $target)
Set the target for this block, and update $this->type accordingly.
setExpiry( $expiry)
Set the block expiry time.
getExpiry()
Get the block expiry time.
getTarget()
Get the target for this particular block.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:519
setReason( $reason)
Set the reason for creating the block.
const NS_USER_TALK
Definition: Defines.php:63
CommentStoreComment $reason
getReason()
Get the reason given for creating the block, as a string.
appliesToNamespace( $ns)
Checks if a block applies to a particular namespace.
getByName()
Get the username of the blocking sysop.