diff options
Diffstat (limited to 'includes/Block.php')
-rw-r--r-- | includes/Block.php | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/includes/Block.php b/includes/Block.php index 6a29a056..873a26d8 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -113,7 +113,7 @@ class Block { $this->forcedTargetID = $user; // needed for foreign users } if ( $by ) { // local user - $this->setBlocker( User::newFromID( $by ) ); + $this->setBlocker( User::newFromId( $by ) ); } else { // foreign user $this->setBlocker( $byText ); } @@ -366,7 +366,7 @@ class Block { protected function initFromRow( $row ) { $this->setTarget( $row->ipb_address ); if ( $row->ipb_by ) { // local user - $this->setBlocker( User::newFromID( $row->ipb_by ) ); + $this->setBlocker( User::newFromId( $row->ipb_by ) ); } else { // foreign user $this->setBlocker( $row->ipb_by_text ); } @@ -442,19 +442,33 @@ class Block { $dbw = wfGetDB( DB_MASTER ); } - # Don't collide with expired blocks - Block::purgeExpired(); + # Periodic purge via commit hooks + if ( mt_rand( 0, 9 ) == 0 ) { + Block::purgeExpired(); + } $row = $this->getDatabaseArray(); $row['ipb_id'] = $dbw->nextSequenceValue( "ipblocks_ipb_id_seq" ); - $dbw->insert( - 'ipblocks', - $row, - __METHOD__, - array( 'IGNORE' ) - ); + $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) ); $affected = $dbw->affectedRows(); + + # Don't collide with expired blocks. + # Do this after trying to insert to avoid pointless gap locks. + if ( !$affected ) { + $dbw->delete( 'ipblocks', + array( + 'ipb_address' => $row['ipb_address'], + 'ipb_user' => $row['ipb_user'], + 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) + ), + __METHOD__ + ); + + $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) ); + $affected = $dbw->affectedRows(); + } + $this->mId = $dbw->insertId(); if ( $affected ) { @@ -580,7 +594,7 @@ class Block { if ( $this->isAutoblocking() && $this->getType() == self::TYPE_USER ) { wfDebug( "Doing retroactive autoblocks for " . $this->getTarget() . "\n" ); - $continue = wfRunHooks( + $continue = Hooks::run( 'PerformRetroactiveAutoblock', array( $this, &$blockIds ) ); if ( $continue ) { @@ -693,7 +707,7 @@ class Block { } # Allow hooks to cancel the autoblock. - if ( !wfRunHooks( 'AbortAutoblock', array( $autoblockIP, &$this ) ) ) { + if ( !Hooks::run( 'AbortAutoblock', array( $autoblockIP, &$this ) ) ) { wfDebug( "Autoblock aborted by hook.\n" ); return false; } @@ -752,7 +766,6 @@ class Block { * @return bool */ public function deleteIfExpired() { - wfProfileIn( __METHOD__ ); if ( $this->isExpired() ) { wfDebug( "Block::deleteIfExpired() -- deleting\n" ); @@ -763,7 +776,6 @@ class Block { $retVal = false; } - wfProfileOut( __METHOD__ ); return $retVal; } @@ -885,7 +897,7 @@ class Block { /** * Get/set a flag determining whether the master is used for reads * - * @param bool $x + * @param bool|null $x * @return bool */ public function fromMaster( $x = null ) { @@ -893,8 +905,8 @@ class Block { } /** - * Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range - * @param bool $x + * Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range) + * @param bool|null $x * @return bool */ public function isHardblock( $x = null ) { @@ -906,6 +918,10 @@ class Block { : $this->isHardblock; } + /** + * @param null|bool $x + * @return bool + */ public function isAutoblocking( $x = null ) { wfSetVar( $this->isAutoblocking, $x ); @@ -919,7 +935,7 @@ class Block { /** * Get/set whether the Block prevents a given action * @param string $action - * @param bool $x + * @param bool|null $x * @return bool */ public function prevents( $action, $x = null ) { @@ -1051,7 +1067,6 @@ class Block { return array(); } - wfProfileIn( __METHOD__ ); $conds = array(); foreach ( array_unique( $ipChain ) as $ipaddr ) { # Discard invalid IP addresses. Since XFF can be spoofed and we do not @@ -1073,7 +1088,6 @@ class Block { } if ( !count( $conds ) ) { - wfProfileOut( __METHOD__ ); return array(); } @@ -1104,12 +1118,12 @@ class Block { } } - wfProfileOut( __METHOD__ ); return $blocks; } /** * From a list of multiple blocks, find the most exact and strongest Block. + * * The logic for finding the "best" block is: * - Blocks that match the block's target IP are preferred over ones in a range * - Hardblocks are chosen over softblocks that prevent account creation @@ -1117,12 +1131,15 @@ 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 + * This should be used when $blocks where retrieved from the user's IP address + * and $ipChain is populated from the same IP address information. * - * @param array $blocks Array of blocks + * @param array $blocks Array of Block objects * @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, ...) + * @throws MWException * @return Block|null The "best" block from the list */ public static function chooseBlock( array $blocks, array $ipChain ) { @@ -1132,8 +1149,6 @@ class Block { return $blocks[0]; } - wfProfileIn( __METHOD__ ); - // 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 ) { @@ -1156,6 +1171,7 @@ class Block { ); $ipChain = array_reverse( $ipChain ); + /** @var Block $block */ foreach ( $blocks as $block ) { // Stop searching if we have already have a "better" block. This // is why the order of the blocks matters @@ -1213,11 +1229,9 @@ class Block { } elseif ( $blocksList['auto'] ) { $chosenBlock = $blocksList['auto']; } else { - wfProfileOut( __METHOD__ ); throw new MWException( "Proxy block found, but couldn't be classified." ); } - wfProfileOut( __METHOD__ ); return $chosenBlock; } |