<?php
/**
+ * @file
* Blocks and bans object
*/
{
/* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
$mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName,
- $mBlockEmail, $mByName;
+ $mBlockEmail, $mByName, $mAngryAutoblock;
/* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster;
const EB_KEEP_EXPIRED = 1;
$this->mForUpdate = false;
$this->mFromMaster = false;
$this->mByName = false;
+ $this->mAngryAutoblock = false;
$this->initialiseRange();
}
if ($this->mEnableAutoblock && $this->mUser) {
wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n");
+
+ $options = array( 'ORDER BY' => 'rc_timestamp DESC' );
+ $conds = array( 'rc_user_text' => $this->mAddress );
+
+ if ($this->mAngryAutoblock) {
+ // Block any IP used in the last 7 days. Up to five IPs.
+ $conds[] = 'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( time() - (7*86400) ) );
+ $options['LIMIT'] = 5;
+ } else {
+ // Just the last IP used.
+ $options['LIMIT'] = 1;
+ }
- $row = $dbr->selectRow( 'recentchanges', array( 'rc_ip' ), array( 'rc_user_text' => $this->mAddress ),
- __METHOD__ , array( 'ORDER BY' => 'rc_timestamp DESC' ) );
+ $res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
+ __METHOD__ , $options);
- if ( !$row || !$row->rc_ip ) {
+ if ( !$dbr->numRows( $res ) ) {
#No results, don't autoblock anything
wfDebug("No IP found to retroactively autoblock\n");
} else {
- #Limit is 1, so no loop needed.
- $retroblockip = $row->rc_ip;
- return $this->doAutoblock( $retroblockip, true );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( $row->rc_ip )
+ $this->doAutoblock( $row->rc_ip );
+ }
}
}
}
-
+
/**
- * Autoblocks the given IP, referring to this Block.
- * @param string $autoblockip The IP to autoblock.
- * @param bool $justInserted The main block was just inserted
- * @return bool Whether or not an autoblock was inserted.
- */
- function doAutoblock( $autoblockip, $justInserted = false ) {
- # If autoblocks are disabled, go away.
- if ( !$this->mEnableAutoblock ) {
- return;
- }
-
- # Check for presence on the autoblock whitelist
+ * Checks whether a given IP is on the autoblock whitelist.
+ * @param string $autoblockip The IP to check
+ */
+ function isWhitelistedFromAutoblocks( $ip ) {
# TODO cache this?
$lines = explode( "\n", wfMsgForContentNoTrans( 'autoblock_whitelist' ) );
- $ip = $autoblockip;
-
wfDebug("Checking the autoblock whitelist..\n");
foreach( $lines as $line ) {
# Is the IP in this range?
if (IP::isInRange( $ip, $wlEntry )) {
wfDebug(" IP $ip matches $wlEntry, not autoblocking\n");
- #$autoblockip = null; # Don't autoblock a whitelisted IP.
- return; #This /SHOULD/ introduce a dummy block - but
- # I don't know a safe way to do so. -werdna
+ return true;
} else {
wfDebug( " No match\n" );
}
}
+
+ return false;
+ }
+
+ /**
+ * Autoblocks the given IP, referring to this Block.
+ * @param string $autoblockip The IP to autoblock.
+ * @param bool $justInserted The main block was just inserted
+ * @return bool Whether or not an autoblock was inserted.
+ */
+ function doAutoblock( $autoblockip, $justInserted = false ) {
+ # If autoblocks are disabled, go away.
+ if ( !$this->mEnableAutoblock ) {
+ return;
+ }
+
+ # Check for presence on the autoblock whitelist
+ if (Block::isWhitelistedFromAutoblocks($autoblockip)) {
+ return;
+ }
+
+ ## Allow hooks to cancel the autoblock.
+ if (!wfRunHooks( 'AbortAutoblock', array( $autoblockip, &$this ) )) {
+ wfDebug( "Autoblock aborted by hook." );
+ return false;
+ }
# It's okay to autoblock. Go ahead and create/insert the block.
$ipblock->mAddress = $autoblockip;
$ipblock->mUser = 0;
$ipblock->mBy = $this->mBy;
+ $ipblock->mByName = $this->mByName;
$ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
$ipblock->mTimestamp = wfTimestampNow();
$ipblock->mAuto = 1;
return $infinity;
*/
}
+
+ /**
+ * Convert a DB-encoded expiry into a real string that humans can read.
+ */
+ static function formatExpiry( $encoded_expiry ) {
+
+ static $msg = null;
+
+ if( is_null( $msg ) ) {
+ $msg = array();
+ $keys = array( 'infiniteblock', 'expiringblock' );
+ foreach( $keys as $key ) {
+ $msg[$key] = wfMsgHtml( $key );
+ }
+ }
+
+ $expiry = Block::decodeExpiry( $encoded_expiry );
+ if ($expiry == 'infinity') {
+ $expirystr = $msg['infiniteblock'];
+ } else {
+ global $wgLang;
+ $expiretimestr = $wgLang->timeanddate( $expiry, true );
+ $expirystr = wfMsgReplaceArgs( $msg['expiringblock'], array($expiretimestr) );
+ }
+
+ return $expirystr;
+ }
+
+ /**
+ * Convert a typed-in expiry time into something we can put into the database.
+ */
+ static function parseExpiryInput( $expiry_input ) {
+ if ( $expiry_input == 'infinite' || $expiry_input == 'indefinite' ) {
+ $expiry = 'infinity';
+ } else {
+ $expiry = strtotime( $expiry_input );
+ if ($expiry < 0 || $expiry === false) {
+ return false;
+ }
+ }
+
+ return $expiry;
+ }
}