summaryrefslogtreecommitdiff
path: root/includes/Block.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/Block.php')
-rw-r--r--includes/Block.php158
1 files changed, 92 insertions, 66 deletions
diff --git a/includes/Block.php b/includes/Block.php
index 873a26d8..c5a16fce 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -23,15 +23,16 @@ class Block {
/** @var string */
public $mReason;
- /** @var bool|string */
+ /** @var string */
public $mTimestamp;
- /** @var int */
+ /** @var bool */
public $mAuto;
- /** @var bool|string */
+ /** @var string */
public $mExpiry;
+ /** @var bool */
public $mHideName;
/** @var int */
@@ -65,10 +66,10 @@ class Block {
protected $blocker;
/** @var bool */
- protected $isHardblock = true;
+ protected $isHardblock;
/** @var bool */
- protected $isAutoblocking = true;
+ protected $isAutoblocking;
# TYPE constants
const TYPE_USER = 1;
@@ -78,59 +79,84 @@ class Block {
const TYPE_ID = 5;
/**
- * @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
+ * Create a new block with specified parameters on a user, IP or IP range.
+ *
+ * @param array $options Parameters of the block:
+ * address string|User Target user name, User object, IP address or IP range
+ * user int Override target user ID (for foreign users)
+ * by int User ID of the blocker
+ * reason string Reason of the block
+ * timestamp string The time at which the block comes into effect
+ * auto bool Is this an automatic block?
+ * expiry string Timestamp of expiration of the block or 'infinity'
+ * anonOnly bool Only disallow anonymous actions
+ * createAccount bool Disallow creation of new accounts
+ * enableAutoblock bool Enable automatic blocking
+ * hideName bool Hide the target user name
+ * blockEmail bool Disallow sending emails
+ * allowUsertalk bool Allow the target to edit its own talk page
+ * byText string Username of the blocker (for foreign users)
+ *
+ * @since 1.26 accepts $options array instead of individual parameters; order
+ * of parameters above reflects the original order
*/
- 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 = ''
- ) {
- if ( $timestamp === 0 ) {
- $timestamp = wfTimestampNow();
- }
+ function __construct( $options = array() ) {
+ $defaults = array(
+ 'address' => '',
+ 'user' => null,
+ 'by' => null,
+ 'reason' => '',
+ 'timestamp' => '',
+ 'auto' => false,
+ 'expiry' => '',
+ 'anonOnly' => false,
+ 'createAccount' => false,
+ 'enableAutoblock' => false,
+ 'hideName' => false,
+ 'blockEmail' => false,
+ 'allowUsertalk' => false,
+ 'byText' => '',
+ );
- if ( count( func_get_args() ) > 0 ) {
- # Soon... :D
- # wfDeprecated( __METHOD__ . " with arguments" );
+ if ( func_num_args() > 1 || !is_array( $options ) ) {
+ $options = array_combine(
+ array_slice( array_keys( $defaults ), 0, func_num_args() ),
+ func_get_args()
+ );
+ wfDeprecated( __METHOD__ . ' with multiple arguments', '1.26' );
}
- $this->setTarget( $address );
- if ( $this->target instanceof User && $user ) {
- $this->forcedTargetID = $user; // needed for foreign users
- }
- if ( $by ) { // local user
- $this->setBlocker( User::newFromId( $by ) );
- } else { // foreign user
- $this->setBlocker( $byText );
+ $options += $defaults;
+
+ $this->setTarget( $options['address'] );
+
+ if ( $this->target instanceof User && $options['user'] ) {
+ # Needed for foreign users
+ $this->forcedTargetID = $options['user'];
}
- $this->mReason = $reason;
- $this->mTimestamp = wfTimestamp( TS_MW, $timestamp );
- $this->mAuto = $auto;
- $this->isHardblock( !$anonOnly );
- $this->prevents( 'createaccount', $createAccount );
- if ( $expiry == 'infinity' || $expiry == wfGetDB( DB_SLAVE )->getInfinity() ) {
- $this->mExpiry = 'infinity';
+
+ if ( $options['by'] ) {
+ # Local user
+ $this->setBlocker( User::newFromID( $options['by'] ) );
} else {
- $this->mExpiry = wfTimestamp( TS_MW, $expiry );
+ # Foreign user
+ $this->setBlocker( $options['byText'] );
}
- $this->isAutoblocking( $enableAutoblock );
- $this->mHideName = $hideName;
- $this->prevents( 'sendemail', $blockEmail );
- $this->prevents( 'editownusertalk', !$allowUsertalk );
+
+ $this->mReason = $options['reason'];
+ $this->mTimestamp = wfTimestamp( TS_MW, $options['timestamp'] );
+ $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $options['expiry'] );
+
+ # Boolean settings
+ $this->mAuto = (bool)$options['auto'];
+ $this->mHideName = (bool)$options['hideName'];
+ $this->isHardblock( !$options['anonOnly'] );
+ $this->isAutoblocking( (bool)$options['enableAutoblock'] );
+
+ # Prevention measures
+ $this->prevents( 'sendemail', (bool)$options['blockEmail'] );
+ $this->prevents( 'editownusertalk', !$options['allowUsertalk'] );
+ $this->prevents( 'createaccount', (bool)$options['createAccount'] );
$this->mFromMaster = false;
}
@@ -375,16 +401,11 @@ class Block {
$this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
$this->mAuto = $row->ipb_auto;
$this->mHideName = $row->ipb_deleted;
- $this->mId = $row->ipb_id;
+ $this->mId = (int)$row->ipb_id;
$this->mParentBlockId = $row->ipb_parent_block_id;
// I wish I didn't have to do this
- $db = wfGetDB( DB_SLAVE );
- if ( $row->ipb_expiry == $db->getInfinity() ) {
- $this->mExpiry = 'infinity';
- } else {
- $this->mExpiry = wfTimestamp( TS_MW, $row->ipb_expiry );
- }
+ $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $row->ipb_expiry );
$this->isHardblock( !$row->ipb_anon_only );
$this->isAutoblocking( $row->ipb_enable_autoblock );
@@ -452,11 +473,15 @@ class Block {
$dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) );
$affected = $dbw->affectedRows();
+ $this->mId = $dbw->insertId();
# Don't collide with expired blocks.
- # Do this after trying to insert to avoid pointless gap locks.
+ # Do this after trying to insert to avoid locking.
if ( !$affected ) {
- $dbw->delete( 'ipblocks',
+ # T96428: The ipb_address index uses a prefix on a field, so
+ # use a standard SELECT + DELETE to avoid annoying gap locks.
+ $ids = $dbw->selectFieldValues( 'ipblocks',
+ 'ipb_id',
array(
'ipb_address' => $row['ipb_address'],
'ipb_user' => $row['ipb_user'],
@@ -464,13 +489,14 @@ class Block {
),
__METHOD__
);
-
- $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) );
- $affected = $dbw->affectedRows();
+ if ( $ids ) {
+ $dbw->delete( 'ipblocks', array( 'ipb_id' => $ids ), __METHOD__ );
+ $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) );
+ $affected = $dbw->affectedRows();
+ $this->mId = $dbw->insertId();
+ }
}
- $this->mId = $dbw->insertId();
-
if ( $affected ) {
$auto_ipd_ids = $this->doRetroactiveAutoblock();
return array( 'id' => $this->mId, 'autoIds' => $auto_ipd_ids );
@@ -1113,7 +1139,7 @@ class Block {
$blocks = array();
foreach ( $rows as $row ) {
$block = self::newFromRow( $row );
- if ( !$block->deleteIfExpired() ) {
+ if ( !$block->deleteIfExpired() ) {
$blocks[] = $block;
}
}