+ /**
+ * Retroactively autoblocks the last IP used by the user (if it is a user)
+ * blocked by this Block.
+ *@return Whether or not a retroactive autoblock was made.
+ */
+ function doRetroactiveAutoblock() {
+ $dbr = wfGetDB( DB_SLAVE );
+ #If autoblock is enabled, autoblock the LAST IP used
+ # - stolen shamelessly from CheckUser_body.php
+
+ 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;
+ }
+
+ $res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
+ __METHOD__ , $options);
+
+ if ( !$dbr->numRows( $res ) ) {
+ #No results, don't autoblock anything
+ wfDebug("No IP found to retroactively autoblock\n");
+ } else {
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( $row->rc_ip )
+ $this->doAutoblock( $row->rc_ip );
+ }
+ }
+ }
+ }
+
+ /**
+ * 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' ) );
+
+ wfDebug("Checking the autoblock whitelist..\n");
+
+ foreach( $lines as $line ) {
+ # List items only
+ if ( substr( $line, 0, 1 ) !== '*' ) {
+ continue;
+ }
+
+ $wlEntry = substr($line, 1);
+ $wlEntry = trim($wlEntry);
+
+ wfDebug("Checking $ip against $wlEntry...");
+
+ # Is the IP in this range?
+ if (IP::isInRange( $ip, $wlEntry )) {
+ wfDebug(" IP $ip matches $wlEntry, not autoblocking\n");
+ 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 = Block::newFromDB( $autoblockip );
+ 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
+ if ($this->mExpiry &&
+ ($this->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp))) {
+ return;
+ }
+ # Just update the timestamp
+ if ( !$justInserted ) {
+ $ipblock->updateTimestamp();
+ }
+ return;
+ } else {
+ $ipblock = new Block;
+ }
+
+ # Make a new block object with the desired properties
+ wfDebug( "Autoblocking {$this->mAddress}@" . $autoblockip . "\n" );
+ $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;
+ $ipblock->mCreateAccount = $this->mCreateAccount;
+ # Continue suppressing the name if needed
+ $ipblock->mHideName = $this->mHideName;
+
+ # If the user is already blocked with an expiry date, we don't
+ # want to pile on top of that!
+ if($this->mExpiry) {
+ $ipblock->mExpiry = min ( $this->mExpiry, Block::getAutoblockExpiry( $this->mTimestamp ));
+ } else {
+ $ipblock->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
+ }
+ # Insert it
+ return $ipblock->insert();
+ }
+