2004-02-18 02:15:00 +00:00
|
|
|
<?php
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @file
|
2004-09-02 23:28:24 +00:00
|
|
|
* Blocks and bans object
|
|
|
|
|
*/
|
2004-02-14 12:37:25 +00:00
|
|
|
|
2004-09-02 23:28:24 +00:00
|
|
|
/**
|
|
|
|
|
* The block class
|
2005-08-02 13:35:19 +00:00
|
|
|
* All the functions in this class assume the object is either explicitly
|
2004-09-02 23:28:24 +00:00
|
|
|
* loaded or filled. It is not load-on-demand. There are no accessors.
|
2005-08-02 13:35:19 +00:00
|
|
|
*
|
2005-12-01 10:37:47 +00:00
|
|
|
* Globals used: $wgAutoblockExpiry, $wgAntiLockFlags
|
2004-09-03 23:00:01 +00:00
|
|
|
*
|
2004-09-02 23:28:24 +00:00
|
|
|
* @todo This could be used everywhere, but it isn't.
|
|
|
|
|
*/
|
2008-09-22 04:52:51 +00:00
|
|
|
class Block {
|
2006-05-11 22:40:38 +00:00
|
|
|
/* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
|
2008-04-14 07:45:50 +00:00
|
|
|
$mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName,
|
2008-09-25 11:45:26 +00:00
|
|
|
$mBlockEmail, $mByName, $mAngryAutoblock, $mAllowUsertalk;
|
2008-02-18 12:16:23 +00:00
|
|
|
/* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster;
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-06-08 13:21:42 +00:00
|
|
|
const EB_KEEP_EXPIRED = 1;
|
|
|
|
|
const EB_FOR_UPDATE = 2;
|
|
|
|
|
const EB_RANGE_ONLY = 4;
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2007-01-20 13:34:31 +00:00
|
|
|
function __construct( $address = '', $user = 0, $by = 0, $reason = '',
|
2008-04-14 07:45:50 +00:00
|
|
|
$timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
|
2008-09-25 11:45:26 +00:00
|
|
|
$hideName = 0, $blockEmail = 0, $allowUsertalk = 0 )
|
2003-09-01 13:13:56 +00:00
|
|
|
{
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mId = 0;
|
2007-03-12 19:31:30 +00:00
|
|
|
# Expand valid IPv6 addresses
|
2007-03-12 21:37:46 +00:00
|
|
|
$address = IP::sanitizeIP( $address );
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->mAddress = $address;
|
|
|
|
|
$this->mUser = $user;
|
|
|
|
|
$this->mBy = $by;
|
|
|
|
|
$this->mReason = $reason;
|
2004-09-07 06:20:51 +00:00
|
|
|
$this->mTimestamp = wfTimestamp(TS_MW,$timestamp);
|
2003-09-07 13:56:25 +00:00
|
|
|
$this->mAuto = $auto;
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mAnonOnly = $anonOnly;
|
|
|
|
|
$this->mCreateAccount = $createAccount;
|
|
|
|
|
$this->mExpiry = self::decodeExpiry( $expiry );
|
2006-11-01 21:57:18 +00:00
|
|
|
$this->mEnableAutoblock = $enableAutoblock;
|
2007-03-14 05:24:06 +00:00
|
|
|
$this->mHideName = $hideName;
|
2007-06-07 17:31:08 +00:00
|
|
|
$this->mBlockEmail = $blockEmail;
|
2008-09-25 11:45:26 +00:00
|
|
|
$this->mAllowUsertalk = $allowUsertalk;
|
2004-08-15 07:23:39 +00:00
|
|
|
$this->mForUpdate = false;
|
2005-12-01 10:37:47 +00:00
|
|
|
$this->mFromMaster = false;
|
2005-08-23 16:52:42 +00:00
|
|
|
$this->mByName = false;
|
2008-06-27 06:24:42 +00:00
|
|
|
$this->mAngryAutoblock = false;
|
2004-02-14 12:37:25 +00:00
|
|
|
$this->initialiseRange();
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Load a block from the database, using either the IP address or
|
2008-09-22 04:52:51 +00:00
|
|
|
* user ID. Tries the user ID first, and if that doesn't work, tries
|
|
|
|
|
* the address.
|
2008-09-21 14:22:23 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $address String: IP address of user/anon
|
|
|
|
|
* @param $user Integer: user id of user
|
|
|
|
|
* @param $killExpired Boolean: delete expired blocks on load
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return Block Object
|
|
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public static function newFromDB( $address, $user = 0, $killExpired = true ) {
|
2008-09-24 08:46:18 +00:00
|
|
|
$block = new Block;
|
2006-07-10 06:30:03 +00:00
|
|
|
$block->load( $address, $user, $killExpired );
|
|
|
|
|
if ( $block->isValid() ) {
|
|
|
|
|
return $block;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Load a blocked user from their block id.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $id Integer: Block id to search for
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return Block object
|
|
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public static function newFromID( $id ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2008-04-14 07:45:50 +00:00
|
|
|
$res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
|
2006-07-10 06:30:03 +00:00
|
|
|
array( 'ipb_id' => $id ), __METHOD__ ) );
|
2008-09-24 08:46:18 +00:00
|
|
|
$block = new Block;
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $block->loadFromResult( $res ) ) {
|
|
|
|
|
return $block;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-11-23 09:52:29 +00:00
|
|
|
/**
|
|
|
|
|
* Check if two blocks are effectively equal
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-11-23 09:52:29 +00:00
|
|
|
*/
|
|
|
|
|
public function equals( Block $block ) {
|
2009-10-19 11:15:51 +00:00
|
|
|
return (
|
2008-11-23 09:52:29 +00:00
|
|
|
$this->mAddress == $block->mAddress
|
|
|
|
|
&& $this->mUser == $block->mUser
|
|
|
|
|
&& $this->mAuto == $block->mAuto
|
|
|
|
|
&& $this->mAnonOnly == $block->mAnonOnly
|
|
|
|
|
&& $this->mCreateAccount == $block->mCreateAccount
|
|
|
|
|
&& $this->mExpiry == $block->mExpiry
|
|
|
|
|
&& $this->mEnableAutoblock == $block->mEnableAutoblock
|
|
|
|
|
&& $this->mHideName == $block->mHideName
|
|
|
|
|
&& $this->mBlockEmail == $block->mBlockEmail
|
|
|
|
|
&& $this->mAllowUsertalk == $block->mAllowUsertalk
|
2009-02-21 10:15:10 +00:00
|
|
|
&& $this->mReason == $block->mReason
|
2008-11-23 09:52:29 +00:00
|
|
|
);
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Clear all member variables in the current object. Does not clear
|
|
|
|
|
* the block from the DB.
|
|
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public function clear() {
|
2005-08-23 16:52:42 +00:00
|
|
|
$this->mAddress = $this->mReason = $this->mTimestamp = '';
|
2008-04-14 07:45:50 +00:00
|
|
|
$this->mId = $this->mAnonOnly = $this->mCreateAccount =
|
|
|
|
|
$this->mEnableAutoblock = $this->mAuto = $this->mUser =
|
2008-09-25 11:45:26 +00:00
|
|
|
$this->mBy = $this->mHideName = $this->mBlockEmail = $this->mAllowUsertalk = 0;
|
2005-08-23 16:52:42 +00:00
|
|
|
$this->mByName = false;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-22 08:30:39 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Get the DB object and set the reference parameter to the select options.
|
|
|
|
|
* The options array will contain FOR UPDATE if appropriate.
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $options Array
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return Database
|
2005-01-22 08:30:39 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function &getDBOptions( &$options ) {
|
2005-08-26 23:02:54 +00:00
|
|
|
global $wgAntiLockFlags;
|
2005-12-01 10:37:47 +00:00
|
|
|
if ( $this->mForUpdate || $this->mFromMaster ) {
|
2007-01-22 23:50:42 +00:00
|
|
|
$db = wfGetDB( DB_MASTER );
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( !$this->mForUpdate || ( $wgAntiLockFlags & ALF_NO_BLOCK_LOCK ) ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
$options = array();
|
2005-07-25 06:57:12 +00:00
|
|
|
} else {
|
2006-07-10 06:30:03 +00:00
|
|
|
$options = array( 'FOR UPDATE' );
|
2005-07-25 06:57:12 +00:00
|
|
|
}
|
2004-08-15 07:23:39 +00:00
|
|
|
} else {
|
2007-01-22 23:50:42 +00:00
|
|
|
$db = wfGetDB( DB_SLAVE );
|
2006-07-10 06:30:03 +00:00
|
|
|
$options = array();
|
2004-08-15 07:23:39 +00:00
|
|
|
}
|
2005-12-01 10:37:47 +00:00
|
|
|
return $db;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Get a block from the DB, with either the given address or the given username
|
2006-07-10 06:30:03 +00:00
|
|
|
*
|
2008-09-21 14:22:23 +00:00
|
|
|
* @param $address string The IP address of the user, or blank to skip IP blocks
|
|
|
|
|
* @param $user int The user ID, or zero for anonymous users
|
|
|
|
|
* @param $killExpired bool Whether to delete expired rows while loading
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean: the user is blocked from editing
|
2006-07-10 06:30:03 +00:00
|
|
|
*
|
2005-12-01 10:37:47 +00:00
|
|
|
*/
|
2008-11-23 09:52:29 +00:00
|
|
|
public function load( $address = '', $user = 0, $killExpired = true ) {
|
2005-12-01 10:37:47 +00:00
|
|
|
wfDebug( "Block::load: '$address', '$user', $killExpired\n" );
|
|
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
$options = array();
|
2005-12-01 10:37:47 +00:00
|
|
|
$db =& $this->getDBOptions( $options );
|
|
|
|
|
|
|
|
|
|
if ( 0 == $user && $address == '' ) {
|
|
|
|
|
# Invalid user specification, not blocked
|
|
|
|
|
$this->clear();
|
|
|
|
|
return false;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
# Try user block
|
|
|
|
|
if ( $user ) {
|
2008-04-14 07:45:50 +00:00
|
|
|
$res = $db->resultObject( $db->select( 'ipblocks', '*', array( 'ipb_user' => $user ),
|
2006-07-10 06:30:03 +00:00
|
|
|
__METHOD__, $options ) );
|
|
|
|
|
if ( $this->loadFromResult( $res, $killExpired ) ) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Try IP block
|
2006-07-11 05:30:35 +00:00
|
|
|
# TODO: improve performance by merging this query with the autoblock one
|
|
|
|
|
# Slightly tricky while handling killExpired as well
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $address ) {
|
2006-07-11 05:30:35 +00:00
|
|
|
$conds = array( 'ipb_address' => $address, 'ipb_auto' => 0 );
|
2006-07-10 06:30:03 +00:00
|
|
|
$res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
|
|
|
|
|
if ( $this->loadFromResult( $res, $killExpired ) ) {
|
2006-07-11 05:30:35 +00:00
|
|
|
if ( $user && $this->mAnonOnly ) {
|
|
|
|
|
# Block is marked anon-only
|
|
|
|
|
# Whitelist this IP address against autoblocks and range blocks
|
2008-09-24 08:46:18 +00:00
|
|
|
# (but not account creation blocks -- bug 13611)
|
2008-09-22 13:21:53 +00:00
|
|
|
if( !$this->mCreateAccount ) {
|
2008-09-24 08:46:18 +00:00
|
|
|
$this->clear();
|
2008-09-22 13:21:53 +00:00
|
|
|
}
|
2006-07-11 05:30:35 +00:00
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Try range block
|
2007-04-20 04:17:15 +00:00
|
|
|
if ( $this->loadRange( $address, $killExpired, $user ) ) {
|
2006-07-11 05:30:35 +00:00
|
|
|
if ( $user && $this->mAnonOnly ) {
|
2008-09-24 08:46:18 +00:00
|
|
|
# Respect account creation blocks on logged-in users -- bug 13611
|
2008-09-22 13:21:53 +00:00
|
|
|
if( !$this->mCreateAccount ) {
|
2008-09-24 08:46:18 +00:00
|
|
|
$this->clear();
|
2008-09-22 13:21:53 +00:00
|
|
|
}
|
2006-07-11 05:30:35 +00:00
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
2006-07-11 05:30:35 +00:00
|
|
|
# Try autoblock
|
|
|
|
|
if ( $address ) {
|
|
|
|
|
$conds = array( 'ipb_address' => $address, 'ipb_auto' => 1 );
|
|
|
|
|
if ( $user ) {
|
|
|
|
|
$conds['ipb_anon_only'] = 0;
|
|
|
|
|
}
|
|
|
|
|
$res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
|
|
|
|
|
if ( $this->loadFromResult( $res, $killExpired ) ) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
# Give up
|
|
|
|
|
$this->clear();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fill in member variables from a result wrapper
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $res ResultWrapper: row from the ipblocks table
|
|
|
|
|
* @param $killExpired Boolean: whether to delete expired rows while loading
|
|
|
|
|
* @return Boolean
|
2006-07-10 06:30:03 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function loadFromResult( ResultWrapper $res, $killExpired = true ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
$ret = false;
|
|
|
|
|
if ( 0 != $res->numRows() ) {
|
2003-09-01 13:13:56 +00:00
|
|
|
# Get first block
|
2006-07-10 06:30:03 +00:00
|
|
|
$row = $res->fetchObject();
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->initFromRow( $row );
|
|
|
|
|
|
|
|
|
|
if ( $killExpired ) {
|
|
|
|
|
# If requested, delete expired rows
|
|
|
|
|
do {
|
|
|
|
|
$killed = $this->deleteIfExpired();
|
2003-09-07 13:56:25 +00:00
|
|
|
if ( $killed ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
$row = $res->fetchObject();
|
2003-09-07 13:56:25 +00:00
|
|
|
if ( $row ) {
|
|
|
|
|
$this->initFromRow( $row );
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
} while ( $killed && $row );
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2003-09-01 13:13:56 +00:00
|
|
|
# If there were any left after the killing finished, return true
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $row ) {
|
2003-09-01 13:13:56 +00:00
|
|
|
$ret = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$ret = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
$res->free();
|
2003-09-01 13:13:56 +00:00
|
|
|
return $ret;
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2005-12-01 10:37:47 +00:00
|
|
|
/**
|
2006-01-07 13:09:30 +00:00
|
|
|
* Search the database for any range blocks matching the given address, and
|
2005-12-01 10:37:47 +00:00
|
|
|
* load the row if one is found.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $address String: IP address range
|
|
|
|
|
* @param $killExpired Boolean: whether to delete expired rows while loading
|
|
|
|
|
* @param $userid Integer: if not 0, then sets ipb_anon_only
|
|
|
|
|
* @return Boolean
|
2005-12-01 10:37:47 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function loadRange( $address, $killExpired = true, $user = 0 ) {
|
2006-07-14 17:02:49 +00:00
|
|
|
$iaddr = IP::toHex( $address );
|
2005-12-01 10:37:47 +00:00
|
|
|
if ( $iaddr === false ) {
|
|
|
|
|
# Invalid address
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Only scan ranges which start in this /16, this improves search speed
|
|
|
|
|
# Blocks should not cross a /16 boundary.
|
|
|
|
|
$range = substr( $iaddr, 0, 4 );
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
$options = array();
|
2005-12-01 10:37:47 +00:00
|
|
|
$db =& $this->getDBOptions( $options );
|
2006-07-10 06:30:03 +00:00
|
|
|
$conds = array(
|
2009-10-21 19:53:03 +00:00
|
|
|
'ipb_range_start' . $db->buildLike( $range, $db->anyString() ),
|
2006-07-10 06:30:03 +00:00
|
|
|
"ipb_range_start <= '$iaddr'",
|
|
|
|
|
"ipb_range_end >= '$iaddr'"
|
|
|
|
|
);
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2007-03-12 21:56:31 +00:00
|
|
|
if ( $user ) {
|
|
|
|
|
$conds['ipb_anon_only'] = 0;
|
|
|
|
|
}
|
2006-01-07 13:31:29 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
$res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__, $options ) );
|
|
|
|
|
$success = $this->loadFromResult( $res, $killExpired );
|
2005-12-01 10:37:47 +00:00
|
|
|
return $success;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Given a database row from the ipblocks table, initialize
|
|
|
|
|
* member variables
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $row ResultWrapper: a row from the ipblocks table
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function initFromRow( $row ) {
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->mAddress = $row->ipb_address;
|
|
|
|
|
$this->mReason = $row->ipb_reason;
|
2004-09-07 06:20:51 +00:00
|
|
|
$this->mTimestamp = wfTimestamp(TS_MW,$row->ipb_timestamp);
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->mUser = $row->ipb_user;
|
|
|
|
|
$this->mBy = $row->ipb_by;
|
2003-09-07 13:56:25 +00:00
|
|
|
$this->mAuto = $row->ipb_auto;
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mAnonOnly = $row->ipb_anon_only;
|
|
|
|
|
$this->mCreateAccount = $row->ipb_create_account;
|
2006-11-01 21:57:18 +00:00
|
|
|
$this->mEnableAutoblock = $row->ipb_enable_autoblock;
|
2007-06-07 17:31:08 +00:00
|
|
|
$this->mBlockEmail = $row->ipb_block_email;
|
2008-09-25 11:45:26 +00:00
|
|
|
$this->mAllowUsertalk = $row->ipb_allow_usertalk;
|
2007-03-14 05:24:06 +00:00
|
|
|
$this->mHideName = $row->ipb_deleted;
|
2003-09-07 13:56:25 +00:00
|
|
|
$this->mId = $row->ipb_id;
|
2006-07-10 06:30:03 +00:00
|
|
|
$this->mExpiry = self::decodeExpiry( $row->ipb_expiry );
|
2005-08-23 16:52:42 +00:00
|
|
|
if ( isset( $row->user_name ) ) {
|
|
|
|
|
$this->mByName = $row->user_name;
|
|
|
|
|
} else {
|
2008-02-18 12:16:23 +00:00
|
|
|
$this->mByName = $row->ipb_by_text;
|
2005-08-23 16:52:42 +00:00
|
|
|
}
|
2005-12-01 10:37:47 +00:00
|
|
|
$this->mRangeStart = $row->ipb_range_start;
|
|
|
|
|
$this->mRangeEnd = $row->ipb_range_end;
|
2005-08-02 13:35:19 +00:00
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Once $mAddress has been set, get the range they came from.
|
|
|
|
|
* Wrapper for IP::parseRange
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function initialiseRange() {
|
2005-12-01 10:37:47 +00:00
|
|
|
$this->mRangeStart = '';
|
|
|
|
|
$this->mRangeEnd = '';
|
2006-11-22 11:51:49 +00:00
|
|
|
|
2004-02-14 12:37:25 +00:00
|
|
|
if ( $this->mUser == 0 ) {
|
2006-11-25 17:32:41 +00:00
|
|
|
list( $this->mRangeStart, $this->mRangeEnd ) = IP::parseRange( $this->mAddress );
|
2006-01-07 13:31:29 +00:00
|
|
|
}
|
2004-02-14 12:37:25 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Delete the row from the IP blocks table.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function delete() {
|
|
|
|
|
if ( wfReadOnly() ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
return false;
|
2005-03-08 02:45:25 +00:00
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( !$this->mId ) {
|
|
|
|
|
throw new MWException( "Block::delete() now requires that the mId member be filled\n" );
|
2003-09-07 13:56:25 +00:00
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2006-07-10 06:30:03 +00:00
|
|
|
$dbw->delete( 'ipblocks', array( 'ipb_id' => $this->mId ), __METHOD__ );
|
|
|
|
|
return $dbw->affectedRows() > 0;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Insert a block into the block table. Will fail if there is a conflicting
|
|
|
|
|
* block (same name and options) already in the database.
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean: whether or not the insertion was successful.
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function insert() {
|
2005-01-11 09:29:29 +00:00
|
|
|
wfDebug( "Block::insert; timestamp {$this->mTimestamp}\n" );
|
2008-04-16 21:07:39 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2008-09-21 15:16:32 +00:00
|
|
|
$this->validateBlockParams();
|
2008-12-15 12:10:41 +00:00
|
|
|
$this->initialiseRange();
|
2008-02-18 12:16:23 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
# Don't collide with expired blocks
|
|
|
|
|
Block::purgeExpired();
|
2006-11-22 11:51:49 +00:00
|
|
|
|
2009-10-28 16:17:16 +00:00
|
|
|
$ipb_id = $dbw->nextSequenceValue('ipblocks_ipb_id_seq');
|
2004-10-24 07:10:33 +00:00
|
|
|
$dbw->insert( 'ipblocks',
|
2004-07-10 03:09:26 +00:00
|
|
|
array(
|
2005-08-02 13:35:19 +00:00
|
|
|
'ipb_id' => $ipb_id,
|
2004-07-10 03:09:26 +00:00
|
|
|
'ipb_address' => $this->mAddress,
|
|
|
|
|
'ipb_user' => $this->mUser,
|
|
|
|
|
'ipb_by' => $this->mBy,
|
2008-02-18 12:16:23 +00:00
|
|
|
'ipb_by_text' => $this->mByName,
|
2004-07-10 03:09:26 +00:00
|
|
|
'ipb_reason' => $this->mReason,
|
2004-09-07 06:20:51 +00:00
|
|
|
'ipb_timestamp' => $dbw->timestamp($this->mTimestamp),
|
2004-07-10 03:09:26 +00:00
|
|
|
'ipb_auto' => $this->mAuto,
|
2006-07-10 06:30:03 +00:00
|
|
|
'ipb_anon_only' => $this->mAnonOnly,
|
|
|
|
|
'ipb_create_account' => $this->mCreateAccount,
|
2006-11-01 21:57:18 +00:00
|
|
|
'ipb_enable_autoblock' => $this->mEnableAutoblock,
|
2006-07-10 06:30:03 +00:00
|
|
|
'ipb_expiry' => self::encodeExpiry( $this->mExpiry, $dbw ),
|
2005-12-01 10:37:47 +00:00
|
|
|
'ipb_range_start' => $this->mRangeStart,
|
|
|
|
|
'ipb_range_end' => $this->mRangeEnd,
|
2007-06-07 17:31:08 +00:00
|
|
|
'ipb_deleted' => $this->mHideName,
|
2008-09-25 11:45:26 +00:00
|
|
|
'ipb_block_email' => $this->mBlockEmail,
|
|
|
|
|
'ipb_allow_usertalk' => $this->mAllowUsertalk
|
2006-07-10 06:30:03 +00:00
|
|
|
), 'Block::insert', array( 'IGNORE' )
|
2004-07-10 03:09:26 +00:00
|
|
|
);
|
2006-07-10 06:30:03 +00:00
|
|
|
$affected = $dbw->affectedRows();
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $affected )
|
2006-11-20 06:01:45 +00:00
|
|
|
$this->doRetroactiveAutoblock();
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
return (bool)$affected;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 15:16:32 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Update a block in the DB with new parameters.
|
|
|
|
|
* The ID field needs to be loaded first.
|
2008-09-21 15:16:32 +00:00
|
|
|
*/
|
|
|
|
|
public function update() {
|
|
|
|
|
wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
|
|
|
|
|
|
$this->validateBlockParams();
|
|
|
|
|
|
|
|
|
|
$dbw->update( 'ipblocks',
|
|
|
|
|
array(
|
|
|
|
|
'ipb_user' => $this->mUser,
|
|
|
|
|
'ipb_by' => $this->mBy,
|
|
|
|
|
'ipb_by_text' => $this->mByName,
|
|
|
|
|
'ipb_reason' => $this->mReason,
|
|
|
|
|
'ipb_timestamp' => $dbw->timestamp($this->mTimestamp),
|
|
|
|
|
'ipb_auto' => $this->mAuto,
|
|
|
|
|
'ipb_anon_only' => $this->mAnonOnly,
|
|
|
|
|
'ipb_create_account' => $this->mCreateAccount,
|
|
|
|
|
'ipb_enable_autoblock' => $this->mEnableAutoblock,
|
|
|
|
|
'ipb_expiry' => self::encodeExpiry( $this->mExpiry, $dbw ),
|
|
|
|
|
'ipb_range_start' => $this->mRangeStart,
|
|
|
|
|
'ipb_range_end' => $this->mRangeEnd,
|
|
|
|
|
'ipb_deleted' => $this->mHideName,
|
2008-09-25 11:45:26 +00:00
|
|
|
'ipb_block_email' => $this->mBlockEmail,
|
|
|
|
|
'ipb_allow_usertalk' => $this->mAllowUsertalk ),
|
2008-09-21 15:16:32 +00:00
|
|
|
array( 'ipb_id' => $this->mId ),
|
|
|
|
|
'Block::update' );
|
|
|
|
|
|
|
|
|
|
return $dbw->affectedRows();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make sure all the proper members are set to sane values
|
|
|
|
|
* before adding/updating a block
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
protected function validateBlockParams() {
|
2008-09-21 15:16:32 +00:00
|
|
|
# Unset ipb_anon_only for user blocks, makes no sense
|
|
|
|
|
if ( $this->mUser ) {
|
|
|
|
|
$this->mAnonOnly = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Unset ipb_enable_autoblock for IP blocks, makes no sense
|
|
|
|
|
if ( !$this->mUser ) {
|
|
|
|
|
$this->mEnableAutoblock = 0;
|
2009-05-21 20:32:28 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2009-05-21 20:32:28 +00:00
|
|
|
# bug 18860: non-anon-only IP blocks should be allowed to block email
|
|
|
|
|
if ( !$this->mUser && $this->mAnonOnly ) {
|
|
|
|
|
$this->mBlockEmail = 0;
|
2008-09-21 15:16:32 +00:00
|
|
|
}
|
|
|
|
|
if( !$this->mByName ) {
|
|
|
|
|
if( $this->mBy ) {
|
|
|
|
|
$this->mByName = User::whoIs( $this->mBy );
|
|
|
|
|
} else {
|
|
|
|
|
global $wgUser;
|
|
|
|
|
$this->mByName = $wgUser->getName();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
/**
|
2009-10-19 11:15:51 +00:00
|
|
|
* Retroactively autoblocks the last IP used by the user (if it is a user)
|
|
|
|
|
* blocked by this Block.
|
|
|
|
|
*
|
|
|
|
|
* @return Boolean: whether or not a retroactive autoblock was made.
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function doRetroactiveAutoblock() {
|
2006-11-25 16:24:44 +00:00
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2009-10-19 11:15:51 +00:00
|
|
|
# If autoblock is enabled, autoblock the LAST IP used
|
2006-11-08 09:54:06 +00:00
|
|
|
# - stolen shamelessly from CheckUser_body.php
|
|
|
|
|
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $this->mEnableAutoblock && $this->mUser ) {
|
2006-11-08 09:54:06 +00:00
|
|
|
wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n");
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-06-27 06:24:42 +00:00
|
|
|
$options = array( 'ORDER BY' => 'rc_timestamp DESC' );
|
|
|
|
|
$conds = array( 'rc_user_text' => $this->mAddress );
|
2009-10-19 11:15:51 +00:00
|
|
|
|
|
|
|
|
if ( $this->mAngryAutoblock ) {
|
2008-06-27 06:24:42 +00:00
|
|
|
// Block any IP used in the last 7 days. Up to five IPs.
|
2009-10-19 11:15:51 +00:00
|
|
|
$conds[] = 'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( time() - ( 7 * 86400 ) ) );
|
2008-06-27 06:24:42 +00:00
|
|
|
$options['LIMIT'] = 5;
|
|
|
|
|
} else {
|
|
|
|
|
// Just the last IP used.
|
|
|
|
|
$options['LIMIT'] = 1;
|
|
|
|
|
}
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2008-06-27 06:24:42 +00:00
|
|
|
$res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
|
2009-10-19 11:15:51 +00:00
|
|
|
__METHOD__ , $options );
|
2006-11-08 09:54:06 +00:00
|
|
|
|
2008-06-27 06:24:42 +00:00
|
|
|
if ( !$dbr->numRows( $res ) ) {
|
2009-10-19 11:15:51 +00:00
|
|
|
# No results, don't autoblock anything
|
2006-11-08 09:54:06 +00:00
|
|
|
wfDebug("No IP found to retroactively autoblock\n");
|
|
|
|
|
} else {
|
2008-06-27 06:24:42 +00:00
|
|
|
while ( $row = $dbr->fetchObject( $res ) ) {
|
|
|
|
|
if ( $row->rc_ip )
|
|
|
|
|
$this->doAutoblock( $row->rc_ip );
|
|
|
|
|
}
|
2006-11-08 09:54:06 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2006-11-08 09:54:06 +00:00
|
|
|
/**
|
2008-08-08 05:56:43 +00:00
|
|
|
* Checks whether a given IP is on the autoblock whitelist.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $ip String: The IP to check
|
|
|
|
|
* @return Boolean
|
2008-08-08 05:56:43 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function isWhitelistedFromAutoblocks( $ip ) {
|
2008-09-21 14:22:23 +00:00
|
|
|
global $wgMemc;
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
// Try to get the autoblock_whitelist from the cache, as it's faster
|
|
|
|
|
// than getting the msg raw and explode()'ing it.
|
2008-09-21 20:25:21 +00:00
|
|
|
$key = wfMemcKey( 'ipb', 'autoblock', 'whitelist' );
|
2008-09-21 14:22:23 +00:00
|
|
|
$lines = $wgMemc->get( $key );
|
|
|
|
|
if ( !$lines ) {
|
|
|
|
|
$lines = explode( "\n", wfMsgForContentNoTrans( 'autoblock_whitelist' ) );
|
2008-09-21 14:25:46 +00:00
|
|
|
$wgMemc->set( $key, $lines, 3600 * 24 );
|
2008-09-21 14:22:23 +00:00
|
|
|
}
|
2006-11-22 23:42:39 +00:00
|
|
|
|
|
|
|
|
wfDebug("Checking the autoblock whitelist..\n");
|
|
|
|
|
|
|
|
|
|
foreach( $lines as $line ) {
|
|
|
|
|
# List items only
|
|
|
|
|
if ( substr( $line, 0, 1 ) !== '*' ) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-19 11:15:51 +00:00
|
|
|
$wlEntry = substr( $line, 1 );
|
|
|
|
|
$wlEntry = trim( $wlEntry );
|
2006-11-22 23:42:39 +00:00
|
|
|
|
2006-12-08 10:30:50 +00:00
|
|
|
wfDebug("Checking $ip against $wlEntry...");
|
2006-11-22 23:42:39 +00:00
|
|
|
|
|
|
|
|
# Is the IP in this range?
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( IP::isInRange( $ip, $wlEntry ) ) {
|
2006-12-08 10:30:50 +00:00
|
|
|
wfDebug(" IP $ip matches $wlEntry, not autoblocking\n");
|
2008-08-08 05:56:43 +00:00
|
|
|
return true;
|
2006-12-08 10:30:50 +00:00
|
|
|
} else {
|
|
|
|
|
wfDebug( " No match\n" );
|
2006-11-22 23:42:39 +00:00
|
|
|
}
|
2006-11-22 11:51:49 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-08-08 05:56:43 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Autoblocks the given IP, referring to this Block.
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $autoblockIP String: the IP to autoblock.
|
|
|
|
|
* @param $justInserted Boolean: the main block was just inserted
|
|
|
|
|
* @return Boolean: whether or not an autoblock was inserted.
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function doAutoblock( $autoblockIP, $justInserted = false ) {
|
2008-08-08 05:56:43 +00:00
|
|
|
# If autoblocks are disabled, go away.
|
|
|
|
|
if ( !$this->mEnableAutoblock ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Check for presence on the autoblock whitelist
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( Block::isWhitelistedFromAutoblocks( $autoblockIP ) ) {
|
2008-08-08 05:56:43 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
## Allow hooks to cancel the autoblock.
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( !wfRunHooks( 'AbortAutoblock', array( $autoblockIP, &$this ) ) ) {
|
2009-01-13 20:28:54 +00:00
|
|
|
wfDebug( "Autoblock aborted by hook.\n" );
|
2008-05-23 10:34:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2006-11-22 11:51:49 +00:00
|
|
|
|
|
|
|
|
# It's okay to autoblock. Go ahead and create/insert the block.
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
$ipblock = Block::newFromDB( $autoblockIP );
|
2006-11-08 09:54:06 +00:00
|
|
|
if ( $ipblock ) {
|
|
|
|
|
# If the user is already blocked. Then check if the autoblock would
|
|
|
|
|
# exceed the user block. If it would exceed, then do nothing, else
|
|
|
|
|
# prolong block time
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $this->mExpiry &&
|
|
|
|
|
( $this->mExpiry < Block::getAutoblockExpiry( $ipblock->mTimestamp ) ) ) {
|
2006-11-22 23:42:39 +00:00
|
|
|
return;
|
2006-11-08 09:54:06 +00:00
|
|
|
}
|
|
|
|
|
# Just update the timestamp
|
2007-03-31 17:23:10 +00:00
|
|
|
if ( !$justInserted ) {
|
|
|
|
|
$ipblock->updateTimestamp();
|
|
|
|
|
}
|
2006-11-22 23:42:39 +00:00
|
|
|
return;
|
2006-11-08 09:54:06 +00:00
|
|
|
} else {
|
|
|
|
|
$ipblock = new Block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Make a new block object with the desired properties
|
2008-09-22 04:52:51 +00:00
|
|
|
wfDebug( "Autoblocking {$this->mAddress}@" . $autoblockIP . "\n" );
|
|
|
|
|
$ipblock->mAddress = $autoblockIP;
|
2006-11-08 09:54:06 +00:00
|
|
|
$ipblock->mUser = 0;
|
|
|
|
|
$ipblock->mBy = $this->mBy;
|
2008-06-27 09:22:12 +00:00
|
|
|
$ipblock->mByName = $this->mByName;
|
2006-11-08 09:54:06 +00:00
|
|
|
$ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
|
|
|
|
|
$ipblock->mTimestamp = wfTimestampNow();
|
|
|
|
|
$ipblock->mAuto = 1;
|
2006-11-13 06:44:37 +00:00
|
|
|
$ipblock->mCreateAccount = $this->mCreateAccount;
|
2007-03-14 05:24:06 +00:00
|
|
|
# Continue suppressing the name if needed
|
|
|
|
|
$ipblock->mHideName = $this->mHideName;
|
2008-09-30 19:57:00 +00:00
|
|
|
$ipblock->mAllowUsertalk = $this->mAllowUsertalk;
|
2006-11-08 09:54:06 +00:00
|
|
|
# If the user is already blocked with an expiry date, we don't
|
|
|
|
|
# want to pile on top of that!
|
2009-10-19 11:15:51 +00:00
|
|
|
if( $this->mExpiry ) {
|
|
|
|
|
$ipblock->mExpiry = min( $this->mExpiry, Block::getAutoblockExpiry( $this->mTimestamp ) );
|
2006-11-08 09:54:06 +00:00
|
|
|
} else {
|
|
|
|
|
$ipblock->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
|
|
|
|
|
}
|
|
|
|
|
# Insert it
|
|
|
|
|
return $ipblock->insert();
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Check if a block has expired. Delete it if it is.
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function deleteIfExpired() {
|
2009-10-19 11:15:51 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2003-09-01 13:13:56 +00:00
|
|
|
if ( $this->isExpired() ) {
|
2005-01-11 08:05:22 +00:00
|
|
|
wfDebug( "Block::deleteIfExpired() -- deleting\n" );
|
2003-09-01 13:13:56 +00:00
|
|
|
$this->delete();
|
2005-10-22 20:52:30 +00:00
|
|
|
$retVal = true;
|
2003-09-01 13:13:56 +00:00
|
|
|
} else {
|
2005-01-11 08:05:22 +00:00
|
|
|
wfDebug( "Block::deleteIfExpired() -- not expired\n" );
|
2005-10-22 20:52:30 +00:00
|
|
|
$retVal = false;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2005-10-22 20:52:30 +00:00
|
|
|
return $retVal;
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Has the block expired?
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function isExpired() {
|
2005-01-11 08:05:22 +00:00
|
|
|
wfDebug( "Block::isExpired() checking current " . wfTimestampNow() . " vs $this->mExpiry\n" );
|
2004-02-16 00:05:25 +00:00
|
|
|
if ( !$this->mExpiry ) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
2005-01-11 08:05:22 +00:00
|
|
|
return wfTimestampNow() > $this->mExpiry;
|
2004-02-16 00:05:25 +00:00
|
|
|
}
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Is the block address valid (i.e. not a null string?)
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Boolean
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function isValid() {
|
2004-06-08 23:56:09 +00:00
|
|
|
return $this->mAddress != '';
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Update the timestamp on autoblocks.
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function updateTimestamp() {
|
2004-02-27 08:25:56 +00:00
|
|
|
if ( $this->mAuto ) {
|
2004-09-07 06:20:51 +00:00
|
|
|
$this->mTimestamp = wfTimestamp();
|
2004-02-27 08:25:56 +00:00
|
|
|
$this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
|
|
|
|
|
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2005-08-02 13:35:19 +00:00
|
|
|
$dbw->update( 'ipblocks',
|
|
|
|
|
array( /* SET */
|
2009-10-19 11:15:51 +00:00
|
|
|
'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
|
|
|
|
|
'ipb_expiry' => $dbw->timestamp( $this->mExpiry ),
|
2004-07-10 03:09:26 +00:00
|
|
|
), array( /* WHERE */
|
|
|
|
|
'ipb_address' => $this->mAddress
|
2005-08-02 13:35:19 +00:00
|
|
|
), 'Block::updateTimestamp'
|
2004-07-10 03:09:26 +00:00
|
|
|
);
|
2004-02-14 12:37:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
2005-08-02 13:35:19 +00:00
|
|
|
|
2006-11-21 18:26:55 +00:00
|
|
|
/**
|
2008-09-21 14:22:23 +00:00
|
|
|
* Get the user id of the blocking sysop
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return Integer
|
2006-11-21 18:26:55 +00:00
|
|
|
*/
|
|
|
|
|
public function getBy() {
|
|
|
|
|
return $this->mBy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2008-09-21 14:22:23 +00:00
|
|
|
* Get the username of the blocking sysop
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2006-11-21 18:26:55 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function getByName() {
|
2005-08-23 16:52:42 +00:00
|
|
|
return $this->mByName;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
/**
|
|
|
|
|
* Get/set the SELECT ... FOR UPDATE flag
|
|
|
|
|
*/
|
2009-10-19 11:15:51 +00:00
|
|
|
public function forUpdate( $x = null ) {
|
2004-08-15 07:23:39 +00:00
|
|
|
return wfSetVar( $this->mForUpdate, $x );
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
/**
|
|
|
|
|
* Get/set a flag determining whether the master is used for reads
|
|
|
|
|
*/
|
2009-10-19 11:15:51 +00:00
|
|
|
public function fromMaster( $x = null ) {
|
2005-12-01 10:37:47 +00:00
|
|
|
return wfSetVar( $this->mFromMaster, $x );
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-22 04:52:51 +00:00
|
|
|
/**
|
|
|
|
|
* Get the block name, but with autoblocked IPs hidden as per standard privacy policy
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2008-09-22 04:52:51 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public function getRedactedName() {
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $this->mAuto ) {
|
|
|
|
|
return '#' . $this->mId;
|
|
|
|
|
} else {
|
|
|
|
|
return $this->mAddress;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-07-10 06:30:03 +00:00
|
|
|
/**
|
|
|
|
|
* Encode expiry for DB
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $expiry String: timestamp for expiry, or
|
2008-09-21 14:22:23 +00:00
|
|
|
* @param $db Database object
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2006-07-10 06:30:03 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function encodeExpiry( $expiry, $db ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $expiry == '' || $expiry == Block::infinity() ) {
|
|
|
|
|
return Block::infinity();
|
|
|
|
|
} else {
|
|
|
|
|
return $db->timestamp( $expiry );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
/**
|
2006-07-10 06:30:03 +00:00
|
|
|
* Decode expiry which has come from the DB
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $expiry String: Database expiry format
|
2008-09-21 14:22:23 +00:00
|
|
|
* @param $timestampType Requested timestamp format
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2006-07-10 06:30:03 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function decodeExpiry( $expiry, $timestampType = TS_MW ) {
|
2006-07-10 06:30:03 +00:00
|
|
|
if ( $expiry == '' || $expiry == Block::infinity() ) {
|
|
|
|
|
return Block::infinity();
|
|
|
|
|
} else {
|
2007-06-18 02:00:23 +00:00
|
|
|
return wfTimestamp( $timestampType, $expiry );
|
2006-07-10 06:30:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
|
|
|
|
* Get a timestamp of the expiry for autoblocks
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function getAutoblockExpiry( $timestamp ) {
|
2004-02-14 12:37:25 +00:00
|
|
|
global $wgAutoblockExpiry;
|
2004-09-07 06:26:15 +00:00
|
|
|
return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
|
2004-02-14 12:37:25 +00:00
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
|
|
|
|
/**
|
2007-03-28 05:39:06 +00:00
|
|
|
* Gets rid of uneeded numbers in quad-dotted/octet IP strings
|
2007-03-14 05:24:06 +00:00
|
|
|
* For example, 127.111.113.151/24 -> 127.111.113.0/24
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $range String: IP address to normalize
|
2008-09-21 14:22:23 +00:00
|
|
|
* @return string
|
2007-03-14 05:24:06 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function normaliseRange( $range ) {
|
2004-06-08 23:56:09 +00:00
|
|
|
$parts = explode( '/', $range );
|
2004-02-14 12:37:25 +00:00
|
|
|
if ( count( $parts ) == 2 ) {
|
2007-03-28 05:39:06 +00:00
|
|
|
// IPv6
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( IP::isIPv6( $range ) && $parts[1] >= 64 && $parts[1] <= 128 ) {
|
2007-03-28 05:39:06 +00:00
|
|
|
$bits = $parts[1];
|
|
|
|
|
$ipint = IP::toUnsigned6( $parts[0] );
|
2009-10-19 11:15:51 +00:00
|
|
|
# Native 32 bit functions WON'T work here!!!
|
2007-03-28 05:39:06 +00:00
|
|
|
# Convert to a padded binary number
|
|
|
|
|
$network = wfBaseConvert( $ipint, 10, 2, 128 );
|
|
|
|
|
# Truncate the last (128-$bits) bits and replace them with zeros
|
|
|
|
|
$network = str_pad( substr( $network, 0, $bits ), 128, 0, STR_PAD_RIGHT );
|
|
|
|
|
# Convert back to an integer
|
|
|
|
|
$network = wfBaseConvert( $network, 2, 10 );
|
|
|
|
|
# Reform octet address
|
|
|
|
|
$newip = IP::toOctet( $network );
|
|
|
|
|
$range = "$newip/{$parts[1]}";
|
|
|
|
|
} // IPv4
|
2009-10-19 11:15:51 +00:00
|
|
|
elseif ( IP::isIPv4( $range ) && $parts[1] >= 16 && $parts[1] <= 32 ) {
|
2007-03-28 05:39:06 +00:00
|
|
|
$shift = 32 - $parts[1];
|
|
|
|
|
$ipint = IP::toUnsigned( $parts[0] );
|
|
|
|
|
$ipint = $ipint >> $shift << $shift;
|
|
|
|
|
$newip = long2ip( $ipint );
|
|
|
|
|
$range = "$newip/{$parts[1]}";
|
|
|
|
|
}
|
2007-03-12 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
return $range;
|
|
|
|
|
}
|
2003-09-07 13:56:25 +00:00
|
|
|
|
2008-04-14 07:45:50 +00:00
|
|
|
/**
|
2006-07-10 06:30:03 +00:00
|
|
|
* Purge expired blocks from the ipblocks table
|
|
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function purgeExpired() {
|
2007-01-22 23:50:42 +00:00
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
2006-07-10 06:30:03 +00:00
|
|
|
$dbw->delete( 'ipblocks', array( 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), __METHOD__ );
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 14:22:23 +00:00
|
|
|
/**
|
2008-09-22 04:52:51 +00:00
|
|
|
* Get a value to insert into expiry field of the database when infinite expiry
|
|
|
|
|
* is desired. In principle this could be DBMS-dependant, but currently all
|
|
|
|
|
* supported DBMS's support the string "infinity", so we just use that.
|
|
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @return String
|
2008-09-21 14:22:23 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function infinity() {
|
2008-09-22 04:52:51 +00:00
|
|
|
# This is a special keyword for timestamps in PostgreSQL, and
|
|
|
|
|
# works with CHAR(14) as well because "i" sorts after all numbers.
|
2006-07-10 06:30:03 +00:00
|
|
|
return 'infinity';
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
/**
|
|
|
|
|
* Convert a DB-encoded expiry into a real string that humans can read.
|
2008-09-22 04:52:51 +00:00
|
|
|
*
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $encoded_expiry String: Database encoded expiry time
|
2009-05-22 09:35:48 +00:00
|
|
|
* @return Html-escaped String
|
2008-05-23 10:34:11 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function formatExpiry( $encoded_expiry ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
static $msg = null;
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
if( is_null( $msg ) ) {
|
|
|
|
|
$msg = array();
|
|
|
|
|
$keys = array( 'infiniteblock', 'expiringblock' );
|
|
|
|
|
foreach( $keys as $key ) {
|
|
|
|
|
$msg[$key] = wfMsgHtml( $key );
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
$expiry = Block::decodeExpiry( $encoded_expiry );
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $expiry == 'infinity' ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
$expirystr = $msg['infiniteblock'];
|
|
|
|
|
} else {
|
|
|
|
|
global $wgLang;
|
2009-10-19 11:15:51 +00:00
|
|
|
$expiredatestr = htmlspecialchars( $wgLang->date( $expiry, true ) );
|
|
|
|
|
$expiretimestr = htmlspecialchars( $wgLang->time( $expiry, true ) );
|
2009-05-25 18:02:58 +00:00
|
|
|
$expirystr = wfMsgReplaceArgs( $msg['expiringblock'], array( $expiredatestr, $expiretimestr ) );
|
2008-05-23 10:34:11 +00:00
|
|
|
}
|
|
|
|
|
return $expirystr;
|
|
|
|
|
}
|
2009-10-19 11:15:51 +00:00
|
|
|
|
2008-05-23 10:34:11 +00:00
|
|
|
/**
|
|
|
|
|
* Convert a typed-in expiry time into something we can put into the database.
|
2008-12-09 19:54:30 +00:00
|
|
|
* @param $expiry_input String: whatever was typed into the form
|
|
|
|
|
* @return String: more database friendly
|
2008-05-23 10:34:11 +00:00
|
|
|
*/
|
2008-11-30 13:09:19 +00:00
|
|
|
public static function parseExpiryInput( $expiry_input ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
if ( $expiry_input == 'infinite' || $expiry_input == 'indefinite' ) {
|
|
|
|
|
$expiry = 'infinity';
|
|
|
|
|
} else {
|
|
|
|
|
$expiry = strtotime( $expiry_input );
|
2009-10-19 11:15:51 +00:00
|
|
|
if ( $expiry < 0 || $expiry === false ) {
|
2008-05-23 10:34:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $expiry;
|
|
|
|
|
}
|
2006-07-10 06:30:03 +00:00
|
|
|
|
2003-09-01 13:13:56 +00:00
|
|
|
}
|