summaryrefslogtreecommitdiff
path: root/includes/Block.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/Block.php')
-rw-r--r--includes/Block.php370
1 files changed, 161 insertions, 209 deletions
diff --git a/includes/Block.php b/includes/Block.php
index 34b89e73..6a29a056 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -20,33 +20,54 @@
* @file
*/
class Block {
- /* public*/ var $mReason, $mTimestamp, $mAuto, $mExpiry, $mHideName;
+ /** @var string */
+ public $mReason;
- protected
- $mId,
- $mFromMaster,
+ /** @var bool|string */
+ public $mTimestamp;
- $mBlockEmail,
- $mDisableUsertalk,
- $mCreateAccount,
- $mParentBlockId;
+ /** @var int */
+ public $mAuto;
- /// @var User|String
+ /** @var bool|string */
+ public $mExpiry;
+
+ public $mHideName;
+
+ /** @var int */
+ public $mParentBlockId;
+
+ /** @var int */
+ protected $mId;
+
+ /** @var bool */
+ protected $mFromMaster;
+
+ /** @var bool */
+ protected $mBlockEmail;
+
+ /** @var bool */
+ protected $mDisableUsertalk;
+
+ /** @var bool */
+ protected $mCreateAccount;
+
+ /** @var User|string */
protected $target;
- // @var Integer Hack for foreign blocking (CentralAuth)
+ /** @var int Hack for foreign blocking (CentralAuth) */
protected $forcedTargetID;
- /// @var Block::TYPE_ constant. Can only be USER, IP or RANGE internally
+ /** @var int Block::TYPE_ constant. Can only be USER, IP or RANGE internally */
protected $type;
- /// @var User
+ /** @var User */
protected $blocker;
- /// @var Bool
+ /** @var bool */
protected $isHardblock = true;
- /// @var Bool
+ /** @var bool */
protected $isAutoblocking = true;
# TYPE constants
@@ -57,14 +78,27 @@ class Block {
const TYPE_ID = 5;
/**
- * Constructor
- * @todo FIXME: Don't know what the best format to have for this constructor is, but fourteen
- * optional parameters certainly isn't it.
+ * @todo FIXME: Don't know what the best format to have for this constructor
+ * is, but fourteen optional parameters certainly isn't it.
+ * @param string $address
+ * @param int $user
+ * @param int $by
+ * @param string $reason
+ * @param mixed $timestamp
+ * @param int $auto
+ * @param string $expiry
+ * @param int $anonOnly
+ * @param int $createAccount
+ * @param int $enableAutoblock
+ * @param int $hideName
+ * @param int $blockEmail
+ * @param int $allowUsertalk
+ * @param string $byText
*/
function __construct( $address = '', $user = 0, $by = 0, $reason = '',
$timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
- $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = '' )
- {
+ $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = ''
+ ) {
if ( $timestamp === 0 ) {
$timestamp = wfTimestampNow();
}
@@ -102,25 +136,10 @@ class Block {
}
/**
- * Load a block from the database, using either the IP address or
- * user ID. Tries the user ID first, and if that doesn't work, tries
- * the address.
- *
- * @param string $address IP address of user/anon
- * @param $user Integer: user id of user
- * @return Block Object
- * @deprecated since 1.18
- */
- public static function newFromDB( $address, $user = 0 ) {
- wfDeprecated( __METHOD__, '1.18' );
- return self::newFromTarget( User::whoIs( $user ), $address );
- }
-
- /**
* Load a blocked user from their block id.
*
- * @param $id Integer: Block id to search for
- * @return Block object or null
+ * @param int $id Block id to search for
+ * @return Block|null
*/
public static function newFromID( $id ) {
$dbr = wfGetDB( DB_SLAVE );
@@ -166,7 +185,7 @@ class Block {
* Check if two blocks are effectively equal. Doesn't check irrelevant things like
* the blocking user or the block timestamp, only things which affect the blocked user
*
- * @param $block Block
+ * @param Block $block
*
* @return bool
*/
@@ -187,52 +206,14 @@ class Block {
}
/**
- * Clear all member variables in the current object. Does not clear
- * the block from the DB.
- * @deprecated since 1.18
- */
- public function clear() {
- wfDeprecated( __METHOD__, '1.18' );
- # Noop
- }
-
- /**
- * Get a block from the DB, with either the given address or the given username
- *
- * @param string $address The IP address of the user, or blank to skip IP blocks
- * @param int $user The user ID, or zero for anonymous users
- * @return Boolean: the user is blocked from editing
- * @deprecated since 1.18
- */
- public function load( $address = '', $user = 0 ) {
- wfDeprecated( __METHOD__, '1.18' );
- if ( $user ) {
- $username = User::whoIs( $user );
- $block = self::newFromTarget( $username, $address );
- } else {
- $block = self::newFromTarget( null, $address );
- }
-
- if ( $block instanceof Block ) {
- # This is mildly evil, but hey, it's B/C :D
- foreach ( $block as $variable => $value ) {
- $this->$variable = $value;
- }
- return true;
- } else {
- return false;
- }
- }
-
- /**
* Load a block from the database which affects the already-set $this->target:
* 1) A block directly on the given user or IP
* 2) A rangeblock encompassing the given IP (smallest first)
* 3) An autoblock on the given IP
- * @param $vagueTarget User|String also search for blocks affecting this target. Doesn't
+ * @param User|string $vagueTarget Also search for blocks affecting this target. Doesn't
* make any sense to use TYPE_AUTO / TYPE_ID here. Leave blank to skip IP lookups.
* @throws MWException
- * @return Bool whether a relevant block was found
+ * @return bool Whether a relevant block was found
*/
protected function newLoad( $vagueTarget = null ) {
$db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
@@ -333,7 +314,7 @@ class Block {
* Get a set of SQL conditions which will select rangeblocks encompassing a given range
* @param string $start Hexadecimal IP representation
* @param string $end Hexadecimal IP representation, or null to use $start = $end
- * @return String
+ * @return string
*/
public static function getRangeCond( $start, $end = null ) {
if ( $end === null ) {
@@ -365,8 +346,8 @@ class Block {
/**
* Get the component of an IP address which is certain to be the same between an IP
* address and a rangeblock containing that IP address.
- * @param $hex String Hexadecimal IP representation
- * @return String
+ * @param string $hex Hexadecimal IP representation
+ * @return string
*/
protected static function getIpFragment( $hex ) {
global $wgBlockCIDRLimit;
@@ -380,7 +361,7 @@ class Block {
/**
* Given a database row from the ipblocks table, initialize
* member variables
- * @param $row ResultWrapper: a row from the ipblocks table
+ * @param stdClass $row A row from the ipblocks table
*/
protected function initFromRow( $row ) {
$this->setTarget( $row->ipb_address );
@@ -415,7 +396,7 @@ class Block {
/**
* Create a new Block object from a database row
- * @param $row ResultWrapper row from the ipblocks table
+ * @param stdClass $row Row from the ipblocks table
* @return Block
*/
public static function newFromRow( $row ) {
@@ -428,7 +409,7 @@ class Block {
* Delete the row from the IP blocks table.
*
* @throws MWException
- * @return Boolean
+ * @return bool
*/
public function delete() {
if ( wfReadOnly() ) {
@@ -450,8 +431,8 @@ class Block {
* Insert a block into the block table. Will fail if there is a conflicting
* block (same name and options) already in the database.
*
- * @param $dbw DatabaseBase if you have one available
- * @return mixed: false on failure, assoc array on success:
+ * @param DatabaseBase $dbw If you have one available
+ * @return bool|array False on failure, assoc array on success:
* ('id' => block ID, 'autoIds' => array of autoblock IDs)
*/
public function insert( $dbw = null ) {
@@ -488,13 +469,15 @@ class Block {
* Update a block in the DB with new parameters.
* The ID field needs to be loaded first.
*
- * @return Int number of affected rows, which should probably be 1 or something has
- * gone slightly awry
+ * @return bool|array False on failure, array on success:
+ * ('id' => block ID, 'autoIds' => array of autoblock IDs)
*/
public function update() {
wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
$dbw = wfGetDB( DB_MASTER );
+ $dbw->startAtomic( __METHOD__ );
+
$dbw->update(
'ipblocks',
$this->getDatabaseArray( $dbw ),
@@ -502,13 +485,39 @@ class Block {
__METHOD__
);
- return $dbw->affectedRows();
+ $affected = $dbw->affectedRows();
+
+ if ( $this->isAutoblocking() ) {
+ // update corresponding autoblock(s) (bug 48813)
+ $dbw->update(
+ 'ipblocks',
+ $this->getAutoblockUpdateArray(),
+ array( 'ipb_parent_block_id' => $this->getId() ),
+ __METHOD__
+ );
+ } else {
+ // autoblock no longer required, delete corresponding autoblock(s)
+ $dbw->delete(
+ 'ipblocks',
+ array( 'ipb_parent_block_id' => $this->getId() ),
+ __METHOD__
+ );
+ }
+
+ $dbw->endAtomic( __METHOD__ );
+
+ if ( $affected ) {
+ $auto_ipd_ids = $this->doRetroactiveAutoblock();
+ return array( 'id' => $this->mId, 'autoIds' => $auto_ipd_ids );
+ }
+
+ return false;
}
/**
* Get an array suitable for passing to $dbw->insert() or $dbw->update()
- * @param $db DatabaseBase
- * @return Array
+ * @param DatabaseBase $db
+ * @return array
*/
protected function getDatabaseArray( $db = null ) {
if ( !$db ) {
@@ -546,10 +555,24 @@ class Block {
}
/**
+ * @return array
+ */
+ protected function getAutoblockUpdateArray() {
+ return array(
+ 'ipb_by' => $this->getBy(),
+ 'ipb_by_text' => $this->getByName(),
+ 'ipb_reason' => $this->mReason,
+ 'ipb_create_account' => $this->prevents( 'createaccount' ),
+ 'ipb_deleted' => (int)$this->mHideName, // typecast required for SQLite
+ 'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' ),
+ );
+ }
+
+ /**
* Retroactively autoblocks the last IP used by the user (if it is a user)
* blocked by this Block.
*
- * @return Array: block IDs of retroactive autoblocks made
+ * @return array Block IDs of retroactive autoblocks made
*/
protected function doRetroactiveAutoblock() {
$blockIds = array();
@@ -573,7 +596,6 @@ class Block {
*
* @param Block $block
* @param array &$blockIds
- * @return Array: block IDs of retroactive autoblocks made
*/
protected static function defaultRetroactiveAutoblock( Block $block, array &$blockIds ) {
global $wgPutIPinRC;
@@ -614,7 +636,7 @@ class Block {
* TODO: this probably belongs somewhere else, but not sure where...
*
* @param string $ip The IP to check
- * @return Boolean
+ * @return bool
*/
public static function isWhitelistedFromAutoblocks( $ip ) {
global $wgMemc;
@@ -656,8 +678,8 @@ class Block {
/**
* Autoblocks the given IP, referring to this Block.
*
- * @param string $autoblockIP the IP to autoblock.
- * @return mixed: block ID if an autoblock was inserted, false if not.
+ * @param string $autoblockIP The IP to autoblock.
+ * @return int|bool Block ID if an autoblock was inserted, false if not.
*/
public function doAutoblock( $autoblockIP ) {
# If autoblocks are disabled, go away.
@@ -698,7 +720,8 @@ class Block {
wfDebug( "Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n" );
$autoblock->setTarget( $autoblockIP );
$autoblock->setBlocker( $this->getBlocker() );
- $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )->inContentLanguage()->plain();
+ $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )
+ ->inContentLanguage()->plain();
$timestamp = wfTimestampNow();
$autoblock->mTimestamp = $timestamp;
$autoblock->mAuto = 1;
@@ -726,7 +749,7 @@ class Block {
/**
* Check if a block has expired. Delete it if it is.
- * @return Boolean
+ * @return bool
*/
public function deleteIfExpired() {
wfProfileIn( __METHOD__ );
@@ -746,7 +769,7 @@ class Block {
/**
* Has the block expired?
- * @return Boolean
+ * @return bool
*/
public function isExpired() {
$timestamp = wfTimestampNow();
@@ -761,7 +784,7 @@ class Block {
/**
* Is the block address valid (i.e. not a null string?)
- * @return Boolean
+ * @return bool
*/
public function isValid() {
return $this->getTarget() != null;
@@ -792,7 +815,7 @@ class Block {
/**
* Get the IP address at the start of the range in Hex form
* @throws MWException
- * @return String IP in Hex form
+ * @return string IP in Hex form
*/
public function getRangeStart() {
switch ( $this->type ) {
@@ -811,7 +834,7 @@ class Block {
/**
* Get the IP address at the end of the range in Hex form
* @throws MWException
- * @return String IP in Hex form
+ * @return string IP in Hex form
*/
public function getRangeEnd() {
switch ( $this->type ) {
@@ -830,7 +853,7 @@ class Block {
/**
* Get the user id of the blocking sysop
*
- * @return Integer (0 for foreign users)
+ * @return int (0 for foreign users)
*/
public function getBy() {
$blocker = $this->getBlocker();
@@ -842,7 +865,7 @@ class Block {
/**
* Get the username of the blocking sysop
*
- * @return String
+ * @return string
*/
public function getByName() {
$blocker = $this->getBlocker();
@@ -860,21 +883,10 @@ class Block {
}
/**
- * Get/set the SELECT ... FOR UPDATE flag
- * @deprecated since 1.18
- *
- * @param $x Bool
- */
- public function forUpdate( $x = null ) {
- wfDeprecated( __METHOD__, '1.18' );
- # noop
- }
-
- /**
* Get/set a flag determining whether the master is used for reads
*
- * @param $x Bool
- * @return Bool
+ * @param bool $x
+ * @return bool
*/
public function fromMaster( $x = null ) {
return wfSetVar( $this->mFromMaster, $x );
@@ -882,8 +894,8 @@ class Block {
/**
* Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range
- * @param $x Bool
- * @return Bool
+ * @param bool $x
+ * @return bool
*/
public function isHardblock( $x = null ) {
wfSetVar( $this->isHardblock, $x );
@@ -906,9 +918,9 @@ class Block {
/**
* Get/set whether the Block prevents a given action
- * @param $action String
- * @param $x Bool
- * @return Bool
+ * @param string $action
+ * @param bool $x
+ * @return bool
*/
public function prevents( $action, $x = null ) {
switch ( $action ) {
@@ -932,7 +944,7 @@ class Block {
/**
* Get the block name, but with autoblocked IPs hidden as per standard privacy policy
- * @return String, text is escaped
+ * @return string Text is escaped
*/
public function getRedactedName() {
if ( $this->mAuto ) {
@@ -947,37 +959,10 @@ class Block {
}
/**
- * Encode expiry for DB
- *
- * @param string $expiry timestamp for expiry, or
- * @param $db DatabaseBase object
- * @return String
- * @deprecated since 1.18; use $dbw->encodeExpiry() instead
- */
- public static function encodeExpiry( $expiry, $db ) {
- wfDeprecated( __METHOD__, '1.18' );
- return $db->encodeExpiry( $expiry );
- }
-
- /**
- * Decode expiry which has come from the DB
- *
- * @param string $expiry Database expiry format
- * @param int $timestampType Requested timestamp format
- * @return String
- * @deprecated since 1.18; use $wgLang->formatExpiry() instead
- */
- public static function decodeExpiry( $expiry, $timestampType = TS_MW ) {
- wfDeprecated( __METHOD__, '1.18' );
- global $wgContLang;
- return $wgContLang->formatExpiry( $expiry, $timestampType );
- }
-
- /**
* Get a timestamp of the expiry for autoblocks
*
- * @param $timestamp String|Int
- * @return String
+ * @param string|int $timestamp
+ * @return string
*/
public static function getAutoblockExpiry( $timestamp ) {
global $wgAutoblockExpiry;
@@ -986,18 +971,6 @@ class Block {
}
/**
- * Gets rid of unneeded numbers in quad-dotted/octet IP strings
- * For example, 127.111.113.151/24 -> 127.111.113.0/24
- * @param string $range IP address to normalize
- * @return string
- * @deprecated since 1.18, call IP::sanitizeRange() directly
- */
- public static function normaliseRange( $range ) {
- wfDeprecated( __METHOD__, '1.18' );
- return IP::sanitizeRange( $range );
- }
-
- /**
* Purge expired blocks from the ipblocks table
*/
public static function purgeExpired() {
@@ -1007,38 +980,15 @@ class Block {
$method = __METHOD__;
$dbw = wfGetDB( DB_MASTER );
- $dbw->onTransactionIdle( function() use ( $dbw, $method ) {
+ $dbw->onTransactionIdle( function () use ( $dbw, $method ) {
$dbw->delete( 'ipblocks',
array( 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), $method );
} );
}
/**
- * Get a value to insert into expiry field of the database when infinite expiry
- * is desired
- * @deprecated since 1.18, call $dbr->getInfinity() directly
- * @return String
- */
- public static function infinity() {
- wfDeprecated( __METHOD__, '1.18' );
- return wfGetDB( DB_SLAVE )->getInfinity();
- }
-
- /**
- * Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute
- * ("24 May 2034"), into an absolute timestamp we can put into the database.
- * @param string $expiry whatever was typed into the form
- * @return String: timestamp or "infinity" string for th DB implementation
- * @deprecated since 1.18 moved to SpecialBlock::parseExpiryInput()
- */
- public static function parseExpiryInput( $expiry ) {
- wfDeprecated( __METHOD__, '1.18' );
- return SpecialBlock::parseExpiryInput( $expiry );
- }
-
- /**
* Given a target and the target's type, get an existing Block object if possible.
- * @param $specificTarget String|User|Int a block target, which may be one of several types:
+ * @param string|User|int $specificTarget A block target, which may be one of several types:
* * A user to block, in which case $target will be a User
* * An IP to block, in which case $target will be a User generated by using
* User::newFromName( $ip, false ) to turn off name validation
@@ -1048,10 +998,10 @@ class Block {
* Calling this with a user, IP address or range will not select autoblocks, and will
* only select a block where the targets match exactly (so looking for blocks on
* 1.2.3.4 will not select 1.2.0.0/16 or even 1.2.3.4/32)
- * @param $vagueTarget String|User|Int as above, but we will search for *any* block which
+ * @param string|User|int $vagueTarget As above, but we will search for *any* block which
* affects that target (so for an IP address, get ranges containing that IP; and also
* get any relevant autoblocks). Leave empty or blank to skip IP-based lookups.
- * @param bool $fromMaster whether to use the DB_MASTER database
+ * @param bool $fromMaster Whether to use the DB_MASTER database
* @return Block|null (null if no relevant block could be found). The target and type
* of the returned Block will refer to the actual block which was found, which might
* not be the same as the target you gave if you used $vagueTarget!
@@ -1068,7 +1018,10 @@ class Block {
# passed by some callers (bug 29116)
return null;
- } elseif ( in_array( $type, array( Block::TYPE_USER, Block::TYPE_IP, Block::TYPE_RANGE, null ) ) ) {
+ } elseif ( in_array(
+ $type,
+ array( Block::TYPE_USER, Block::TYPE_IP, Block::TYPE_RANGE, null ) )
+ ) {
$block = new Block();
$block->fromMaster( $fromMaster );
@@ -1083,15 +1036,14 @@ class Block {
return null;
}
-
/**
* Get all blocks that match any IP from an array of IP addresses
*
- * @param Array $ipChain list of IPs (strings), usually retrieved from the
+ * @param array $ipChain List of IPs (strings), usually retrieved from the
* X-Forwarded-For header of the request
- * @param Bool $isAnon Exclude anonymous-only blocks if false
- * @param Bool $fromMaster Whether to query the master or slave database
- * @return Array of Blocks
+ * @param bool $isAnon Exclude anonymous-only blocks if false
+ * @param bool $fromMaster Whether to query the master or slave database
+ * @return array Array of Blocks
* @since 1.22
*/
public static function getBlocksForIPList( array $ipChain, $isAnon, $fromMaster = false ) {
@@ -1111,7 +1063,7 @@ class Block {
continue;
}
# Don't check trusted IPs (includes local squids which will be in every request)
- if ( wfIsTrustedProxy( $ipaddr ) ) {
+ if ( IP::isTrustedProxy( $ipaddr ) ) {
continue;
}
# Check both the original IP (to check against single blocks), as well as build
@@ -1165,13 +1117,13 @@ class Block {
* - Other softblocks are chosen over autoblocks
* - If there are multiple exact or range blocks at the same level, the one chosen
* is random
-
- * @param Array $ipChain list of IPs (strings). This is used to determine how "close"
+ *
+ * @param array $blocks Array of blocks
+ * @param array $ipChain List of IPs (strings). This is used to determine how "close"
* a block is to the server, and if a block matches exactly, or is in a range.
* The order is furthest from the server to nearest e.g., (Browser, proxy1, proxy2,
* local-squid, ...)
- * @param Array $block Array of blocks
- * @return Block|null the "best" block from the list
+ * @return Block|null The "best" block from the list
*/
public static function chooseBlock( array $blocks, array $ipChain ) {
if ( !count( $blocks ) ) {
@@ -1184,7 +1136,7 @@ class Block {
// Sort hard blocks before soft ones and secondarily sort blocks
// that disable account creation before those that don't.
- usort( $blocks, function( Block $a, Block $b ) {
+ usort( $blocks, function ( Block $a, Block $b ) {
$aWeight = (int)$a->isHardblock() . (int)$a->prevents( 'createaccount' );
$bWeight = (int)$b->isHardblock() . (int)$b->prevents( 'createaccount' );
return strcmp( $bWeight, $aWeight ); // highest weight first
@@ -1275,7 +1227,7 @@ class Block {
* as a string; for User objects this will return User::__toString()
* which in turn gives User::getName().
*
- * @param $target String|Int|User|null
+ * @param string|int|User|null $target
* @return array( User|String|null, Block::TYPE_ constant|null )
*/
public static function parseTarget( $target ) {
@@ -1332,7 +1284,7 @@ class Block {
/**
* Get the type of target for this particular block
- * @return Block::TYPE_ constant, will never be TYPE_ID
+ * @return int Block::TYPE_ constant, will never be TYPE_ID
*/
public function getType() {
return $this->mAuto
@@ -1355,7 +1307,7 @@ class Block {
* Get the target for this particular Block. Note that for autoblocks,
* this returns the unredacted name; frontend functions need to call $block->getRedactedName()
* in this situation.
- * @return User|String
+ * @return User|string
*/
public function getTarget() {
return $this->target;
@@ -1364,7 +1316,7 @@ class Block {
/**
* @since 1.19
*
- * @return Mixed|string
+ * @return mixed|string
*/
public function getExpiry() {
return $this->mExpiry;
@@ -1372,7 +1324,7 @@ class Block {
/**
* Set the target for this block, and update $this->type accordingly
- * @param $target Mixed
+ * @param mixed $target
*/
public function setTarget( $target ) {
list( $this->target, $this->type ) = self::parseTarget( $target );
@@ -1388,7 +1340,7 @@ class Block {
/**
* Set the user who implemented (or will implement) this block
- * @param $user User|string Local User object or username string for foreign users
+ * @param User|string $user Local User object or username string for foreign users
*/
public function setBlocker( $user ) {
$this->blocker = $user;
@@ -1429,7 +1381,7 @@ class Block {
$this->getId(),
$lang->formatExpiry( $this->mExpiry ),
(string)$intended,
- $lang->timeanddate( wfTimestamp( TS_MW, $this->mTimestamp ), true ),
+ $lang->userTimeAndDate( $this->mTimestamp, $context->getUser() ),
);
}
}