MediaWiki  master
AbstractBlock.php
Go to the documentation of this file.
1 <?php
21 namespace MediaWiki\Block;
22 
25 use IP;
27 use Title;
28 use User;
29 
33 abstract class AbstractBlock {
35  public $mReason;
36 
38  public $mTimestamp;
39 
41  public $mExpiry = '';
42 
44  protected $mBlockEmail = false;
45 
47  protected $allowUsertalk = false;
48 
50  protected $blockCreateAccount = false;
51 
53  public $mHideName = false;
54 
56  protected $target;
57 
62  protected $type;
63 
65  protected $blocker;
66 
68  protected $isSitewide = true;
69 
70  # TYPE constants
71  const TYPE_USER = 1;
72  const TYPE_IP = 2;
73  const TYPE_RANGE = 3;
74  const TYPE_AUTO = 4;
75  const TYPE_ID = 5;
76 
87  function __construct( $options = [] ) {
88  $defaults = [
89  'address' => '',
90  'by' => null,
91  'reason' => '',
92  'timestamp' => '',
93  'byText' => '',
94  ];
95 
96  $options += $defaults;
97 
98  $this->setTarget( $options['address'] );
99 
100  if ( $options['by'] ) {
101  # Local user
102  $this->setBlocker( User::newFromId( $options['by'] ) );
103  } else {
104  # Foreign user
105  $this->setBlocker( $options['byText'] );
106  }
107 
108  $this->setReason( $options['reason'] );
109  $this->setTimestamp( wfTimestamp( TS_MW, $options['timestamp'] ) );
110  }
111 
117  public function getBy() {
118  return $this->getBlocker()->getId();
119  }
120 
126  public function getByName() {
127  return $this->getBlocker()->getName();
128  }
129 
134  public function getId() {
135  return null;
136  }
137 
144  public function getReason() {
145  return $this->mReason;
146  }
147 
154  public function setReason( $reason ) {
155  $this->mReason = $reason;
156  }
157 
164  public function getHideName() {
165  return $this->mHideName;
166  }
167 
174  public function setHideName( $hideName ) {
175  $this->mHideName = $hideName;
176  }
177 
187  public function isSitewide( $x = null ) {
188  return wfSetVar( $this->isSitewide, $x );
189  }
190 
200  public function isCreateAccountBlocked( $x = null ) {
201  return wfSetVar( $this->blockCreateAccount, $x );
202  }
203 
213  public function isEmailBlocked( $x = null ) {
214  return wfSetVar( $this->mBlockEmail, $x );
215  }
216 
226  public function isUsertalkEditAllowed( $x = null ) {
227  return wfSetVar( $this->allowUsertalk, $x );
228  }
229 
240  public function appliesToRight( $right ) {
241  $config = RequestContext::getMain()->getConfig();
242  $blockDisablesLogin = $config->get( 'BlockDisablesLogin' );
243 
244  $res = null;
245  switch ( $right ) {
246  case 'edit':
247  // TODO: fix this case to return proper value
248  $res = true;
249  break;
250  case 'createaccount':
251  $res = $this->isCreateAccountBlocked();
252  break;
253  case 'sendemail':
254  $res = $this->isEmailBlocked();
255  break;
256  case 'upload':
257  // Until T6995 is completed
258  $res = $this->isSitewide();
259  break;
260  case 'read':
261  $res = false;
262  break;
263  case 'purge':
264  $res = false;
265  break;
266  }
267  if ( !$res && $blockDisablesLogin ) {
268  // If a block would disable login, then it should
269  // prevent any right that all users cannot do
270  $anon = new User;
271  $res = $anon->isAllowed( $right ) ? $res : true;
272  }
273 
274  return $res;
275  }
276 
286  public function prevents( $action, $x = null ) {
287  $config = RequestContext::getMain()->getConfig();
288  $blockDisablesLogin = $config->get( 'BlockDisablesLogin' );
289  $blockAllowsUTEdit = $config->get( 'BlockAllowsUTEdit' );
290 
291  $res = null;
292  switch ( $action ) {
293  case 'edit':
294  # For now... <evil laugh>
295  $res = true;
296  break;
297  case 'createaccount':
298  $res = wfSetVar( $this->blockCreateAccount, $x );
299  break;
300  case 'sendemail':
301  $res = wfSetVar( $this->mBlockEmail, $x );
302  break;
303  case 'upload':
304  // Until T6995 is completed
305  $res = $this->isSitewide();
306  break;
307  case 'editownusertalk':
308  // NOTE: this check is not reliable on partial blocks
309  // since partially blocked users are always allowed to edit
310  // their own talk page unless a restriction exists on the
311  // page or User_talk: namespace
312  wfSetVar( $this->allowUsertalk, $x === null ? null : !$x );
313  $res = !$this->isUsertalkEditAllowed();
314 
315  // edit own user talk can be disabled by config
316  if ( !$blockAllowsUTEdit ) {
317  $res = true;
318  }
319  break;
320  case 'read':
321  $res = false;
322  break;
323  case 'purge':
324  $res = false;
325  break;
326  }
327  if ( !$res && $blockDisablesLogin ) {
328  // If a block would disable login, then it should
329  // prevent any action that all users cannot do
330  $anon = new User;
331  $res = $anon->isAllowed( $action ) ? $res : true;
332  }
333 
334  return $res;
335  }
336 
346  public static function parseTarget( $target ) {
347  # We may have been through this before
348  if ( $target instanceof User ) {
349  if ( IP::isValid( $target->getName() ) ) {
350  return [ $target, self::TYPE_IP ];
351  } else {
352  return [ $target, self::TYPE_USER ];
353  }
354  } elseif ( $target === null ) {
355  return [ null, null ];
356  }
357 
358  $target = trim( $target );
359 
360  if ( IP::isValid( $target ) ) {
361  # We can still create a User if it's an IP address, but we need to turn
362  # off validation checking (which would exclude IP addresses)
363  return [
365  self::TYPE_IP
366  ];
367 
368  } elseif ( IP::isValidRange( $target ) ) {
369  # Can't create a User from an IP range
370  return [ IP::sanitizeRange( $target ), self::TYPE_RANGE ];
371  }
372 
373  # Consider the possibility that this is not a username at all
374  # but actually an old subpage (T31797)
375  if ( strpos( $target, '/' ) !== false ) {
376  # An old subpage, drill down to the user behind it
377  $target = explode( '/', $target )[0];
378  }
379 
380  $userObj = User::newFromName( $target );
381  if ( $userObj instanceof User ) {
382  # Note that since numbers are valid usernames, a $target of "12345" will be
383  # considered a User. If you want to pass a block ID, prepend a hash "#12345",
384  # since hash characters are not valid in usernames or titles generally.
385  return [ $userObj, self::TYPE_USER ];
386 
387  } elseif ( preg_match( '/^#\d+$/', $target ) ) {
388  # Autoblock reference in the form "#12345"
389  return [ substr( $target, 1 ), self::TYPE_AUTO ];
390 
391  } else {
392  return [ null, null ];
393  }
394  }
395 
400  public function getType() {
401  return $this->type;
402  }
403 
411  public function getTargetAndType() {
412  return [ $this->getTarget(), $this->getType() ];
413  }
414 
421  public function getTarget() {
422  return $this->target;
423  }
424 
431  public function getExpiry() {
432  return $this->mExpiry;
433  }
434 
441  public function setExpiry( $expiry ) {
442  $this->mExpiry = $expiry;
443  }
444 
451  public function getTimestamp() {
452  return $this->mTimestamp;
453  }
454 
461  public function setTimestamp( $timestamp ) {
462  $this->mTimestamp = $timestamp;
463  }
464 
469  public function setTarget( $target ) {
470  list( $this->target, $this->type ) = static::parseTarget( $target );
471  }
472 
477  public function getBlocker() {
478  return $this->blocker;
479  }
480 
485  public function setBlocker( $user ) {
486  if ( is_string( $user ) ) {
487  $user = User::newFromName( $user, false );
488  }
489 
490  if ( $user->isAnon() && User::isUsableName( $user->getName() ) ) {
491  throw new InvalidArgumentException(
492  'Blocker must be a local user or a name that cannot be a local user'
493  );
494  }
495 
496  $this->blocker = $user;
497  }
498 
506  abstract public function getPermissionsError( IContextSource $context );
507 
515  public function getBlockErrorParams( IContextSource $context ) {
516  $blocker = $this->getBlocker();
517  if ( $blocker instanceof User ) { // local user
518  $blockerUserpage = $blocker->getUserPage();
519  $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]";
520  } else { // foreign user
521  $link = $blocker;
522  }
523 
524  $reason = $this->getReason();
525  if ( $reason == '' ) {
526  $reason = $context->msg( 'blockednoreason' )->text();
527  }
528 
529  /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
530  * This could be a username, an IP range, or a single IP. */
531  $intended = $this->getTarget();
532  $lang = $context->getLanguage();
533 
534  return [
535  $link,
536  $reason,
537  $context->getRequest()->getIP(),
538  $this->getByName(),
539  // TODO: SystemBlock replaces this with the system block type. Clean up
540  // error params so that this is not necessary.
541  $this->getId(),
542  $lang->formatExpiry( $this->getExpiry() ),
543  (string)$intended,
544  $lang->userTimeAndDate( $this->getTimestamp(), $context->getUser() ),
545  ];
546  }
547 
575  public function appliesToUsertalk( Title $usertalk = null ) {
576  if ( !$usertalk ) {
577  if ( $this->target instanceof User ) {
578  $usertalk = $this->target->getTalkPage();
579  } else {
580  throw new InvalidArgumentException(
581  '$usertalk must be provided if block target is not a user/IP'
582  );
583  }
584  }
585 
586  if ( $usertalk->getNamespace() !== NS_USER_TALK ) {
587  throw new InvalidArgumentException(
588  '$usertalk must be a user talk page'
589  );
590  }
591 
592  if ( !$this->isSitewide() ) {
593  if ( $this->appliesToPage( $usertalk->getArticleID() ) ) {
594  return true;
595  }
596  if ( !$this->appliesToNamespace( NS_USER_TALK ) ) {
597  return false;
598  }
599  }
600 
601  // This is a type of block which uses the ipb_allow_usertalk
602  // flag. The flag can still be overridden by global configs.
603  $config = RequestContext::getMain()->getConfig();
604  if ( !$config->get( 'BlockAllowsUTEdit' ) ) {
605  return true;
606  }
607  return !$this->isUsertalkEditAllowed();
608  }
609 
621  public function appliesToTitle( Title $title ) {
622  return $this->isSitewide();
623  }
624 
633  public function appliesToNamespace( $ns ) {
634  return $this->isSitewide();
635  }
636 
650  public function appliesToPage( $pageId ) {
651  return $this->isSitewide();
652  }
653 
663  public function shouldTrackWithCookie( $isAnon ) {
664  wfDeprecated( __METHOD__, '1.34' );
665  return false;
666  }
667 
674  public function appliesToPasswordReset() {
675  return $this->isCreateAccountBlocked();
676  }
677 
678 }
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:43
static isValidRange( $ipRange)
Validate an IP range (valid address with a valid CIDR prefix).
Definition: IP.php:125
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
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.
int $type
AbstractBlock::TYPE_ constant.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
if(!isset( $args[0])) $lang
appliesToUsertalk(Title $usertalk=null)
Determine whether the block allows the user to edit their own user talk page.
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:175
string $action
Cache what action this request is.
Definition: MediaWiki.php:48
setBlocker( $user)
Set the user who implemented (or will implement) this block.
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:2304
usually copyright or history_copyright This message must be in HTML not wikitext & $link
Definition: hooks.txt:3051
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:38
shouldTrackWithCookie( $isAnon)
Check if the block should be tracked with a cookie.
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.
$res
Definition: database.txt:21
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.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1982
getBlockErrorParams(IContextSource $context)
Get block information used in different block error messages.
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
static isUsableName( $name)
Usernames which fail to pass this function will be blocked from user login and new account registrati...
Definition: User.php:1060
isEmailBlocked( $x=null)
Get or set the flag indicating whether this block blocks the target from sending emails.
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:925
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.
msg( $key)
This is the method for getting translated interface messages.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
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:618
This document describes the state of Postgres support in and is fairly well maintained The main code is very well while extensions are very hit and miss it is probably the most supported database after MySQL Much of the work in making MediaWiki database agnostic came about through the work of creating Postgres as and are nearing end of but without copying over all the usage comments General notes on the but these can almost always be programmed around *Although Postgres has a true BOOLEAN type
Definition: postgres.txt:22
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.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
getUserPage()
Get this user&#39;s personal page title.
Definition: User.php:4416
__construct( $options=[])
Create a new block with specified parameters on a user, IP or IP range.
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:594
setReason( $reason)
Set the reason for creating the block.
const NS_USER_TALK
Definition: Defines.php:63
getReason()
Get the reason given for creating the block.
appliesToNamespace( $ns)
Checks if a block applies to a particular namespace.
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1473
getByName()
Get the username of the blocking sysop.