ResourceLoader::filter: use APC when running under HHVM
[lhc/web/wiklou.git] / includes / Block.php
index 4698f45..d582201 100644 (file)
@@ -122,11 +122,7 @@ class Block {
                $this->mAuto = $auto;
                $this->isHardblock( !$anonOnly );
                $this->prevents( 'createaccount', $createAccount );
-               if ( $expiry == 'infinity' || $expiry == wfGetDB( DB_SLAVE )->getInfinity() ) {
-                       $this->mExpiry = 'infinity';
-               } else {
-                       $this->mExpiry = wfTimestamp( TS_MW, $expiry );
-               }
+               $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $expiry );
                $this->isAutoblocking( $enableAutoblock );
                $this->mHideName = $hideName;
                $this->prevents( 'sendemail', $blockEmail );
@@ -375,16 +371,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 );
@@ -442,21 +433,40 @@ 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();
                $this->mId = $dbw->insertId();
 
+               # Don't collide with expired blocks.
+               # Do this after trying to insert to avoid locking.
+               if ( !$affected ) {
+                       # 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'],
+                                       'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() )
+                               ),
+                               __METHOD__
+                       );
+                       if ( $ids ) {
+                               $dbw->delete( 'ipblocks', array( 'ipb_id' => $ids ), __METHOD__ );
+                               $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) );
+                               $affected = $dbw->affectedRows();
+                               $this->mId = $dbw->insertId();
+                       }
+               }
+
                if ( $affected ) {
                        $auto_ipd_ids = $this->doRetroactiveAutoblock();
                        return array( 'id' => $this->mId, 'autoIds' => $auto_ipd_ids );