Merge "Make autoblocks update with the parent block"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 31 Jan 2014 18:59:09 +0000 (18:59 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 31 Jan 2014 18:59:09 +0000 (18:59 +0000)
1  2 
includes/Block.php
includes/specials/SpecialBlock.php

diff --combined includes/Block.php
@@@ -63,8 -63,8 +63,8 @@@ class Block 
         */
        function __construct( $address = '', $user = 0, $by = 0, $reason = '',
                $timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
 -              $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = '' )
 -      {
 +              $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = ''
 +      {
                if ( $timestamp === 0 ) {
                        $timestamp = wfTimestampNow();
                }
                $this->mFromMaster = false;
        }
  
 -      /**
 -       * Load a block from the database, using either the IP address or
 -       * user ID. Tries the user ID first, and if that doesn't work, tries
 -       * the address.
 -       *
 -       * @param string $address IP address of user/anon
 -       * @param $user Integer: user id of user
 -       * @return Block Object
 -       * @deprecated since 1.18
 -       */
 -      public static function newFromDB( $address, $user = 0 ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              return self::newFromTarget( User::whoIs( $user ), $address );
 -      }
 -
        /**
         * Load a blocked user from their block id.
         *
                );
        }
  
 -      /**
 -       * Clear all member variables in the current object. Does not clear
 -       * the block from the DB.
 -       * @deprecated since 1.18
 -       */
 -      public function clear() {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              # Noop
 -      }
 -
 -      /**
 -       * Get a block from the DB, with either the given address or the given username
 -       *
 -       * @param string $address The IP address of the user, or blank to skip IP blocks
 -       * @param int $user The user ID, or zero for anonymous users
 -       * @return Boolean: the user is blocked from editing
 -       * @deprecated since 1.18
 -       */
 -      public function load( $address = '', $user = 0 ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              if ( $user ) {
 -                      $username = User::whoIs( $user );
 -                      $block = self::newFromTarget( $username, $address );
 -              } else {
 -                      $block = self::newFromTarget( null, $address );
 -              }
 -
 -              if ( $block instanceof Block ) {
 -                      # This is mildly evil, but hey, it's B/C :D
 -                      foreach ( $block as $variable => $value ) {
 -                              $this->$variable = $value;
 -                      }
 -                      return true;
 -              } else {
 -                      return false;
 -              }
 -      }
 -
        /**
         * Load a block from the database which affects the already-set $this->target:
         *     1) A block directly on the given user or IP
         * Update a block in the DB with new parameters.
         * The ID field needs to be loaded first.
         *
-        * @return Int number of affected rows, which should probably be 1 or something has
-        *     gone slightly awry
+        * @return bool|array False on failure, array on success: ('id' => block ID, 'autoIds' => array of autoblock IDs)
         */
        public function update() {
                wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
                $dbw = wfGetDB( DB_MASTER );
  
+               $dbw->startAtomic( __METHOD__ );
                $dbw->update(
                        'ipblocks',
                        $this->getDatabaseArray( $dbw ),
                        __METHOD__
                );
  
-               return $dbw->affectedRows();
+               $affected = $dbw->affectedRows();
+               $dbw->update(
+                       'ipblocks',
+                       $this->getAutoblockUpdateArray(),
+                       array( 'ipb_parent_block_id' => $this->getId() ),
+                       __METHOD__
+               );
+               $dbw->endAtomic( __METHOD__ );
+               if ( $affected ) {
+                       $auto_ipd_ids = $this->doRetroactiveAutoblock();
+                       return array( 'id' => $this->mId, 'autoIds' => $auto_ipd_ids );
+               }
+               return false;
        }
  
        /**
                return $a;
        }
  
+       /**
+        * @return Array
+        */
+       protected function getAutoblockUpdateArray() {
+               return array(
+                       'ipb_by'               => $this->getBy(),
+                       'ipb_by_text'          => $this->getByName(),
+                       'ipb_reason'           => $this->mReason,
+                       'ipb_create_account'   => $this->prevents( 'createaccount' ),
+                       'ipb_deleted'          => (int)$this->mHideName, // typecast required for SQLite
+                       'ipb_allow_usertalk'   => !$this->prevents( 'editownusertalk' ),
+               );
+       }
        /**
         * Retroactively autoblocks the last IP used by the user (if it is a user)
         * blocked by this Block.
                return $this->mId;
        }
  
 -      /**
 -       * Get/set the SELECT ... FOR UPDATE flag
 -       * @deprecated since 1.18
 -       *
 -       * @param $x Bool
 -       */
 -      public function forUpdate( $x = null ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              # noop
 -      }
 -
        /**
         * Get/set a flag determining whether the master is used for reads
         *
                }
        }
  
 -      /**
 -       * Encode expiry for DB
 -       *
 -       * @param string $expiry timestamp for expiry, or
 -       * @param $db DatabaseBase object
 -       * @return String
 -       * @deprecated since 1.18; use $dbw->encodeExpiry() instead
 -       */
 -      public static function encodeExpiry( $expiry, $db ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              return $db->encodeExpiry( $expiry );
 -      }
 -
 -      /**
 -       * Decode expiry which has come from the DB
 -       *
 -       * @param string $expiry Database expiry format
 -       * @param int $timestampType Requested timestamp format
 -       * @return String
 -       * @deprecated since 1.18; use $wgLang->formatExpiry() instead
 -       */
 -      public static function decodeExpiry( $expiry, $timestampType = TS_MW ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              global $wgContLang;
 -              return $wgContLang->formatExpiry( $expiry, $timestampType );
 -      }
 -
        /**
         * Get a timestamp of the expiry for autoblocks
         *
                return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
        }
  
 -      /**
 -       * Gets rid of unneeded numbers in quad-dotted/octet IP strings
 -       * For example, 127.111.113.151/24 -> 127.111.113.0/24
 -       * @param string $range IP address to normalize
 -       * @return string
 -       * @deprecated since 1.18, call IP::sanitizeRange() directly
 -       */
 -      public static function normaliseRange( $range ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              return IP::sanitizeRange( $range );
 -      }
 -
        /**
         * Purge expired blocks from the ipblocks table
         */
                } );
        }
  
 -      /**
 -       * Get a value to insert into expiry field of the database when infinite expiry
 -       * is desired
 -       * @deprecated since 1.18, call $dbr->getInfinity() directly
 -       * @return String
 -       */
 -      public static function infinity() {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              return wfGetDB( DB_SLAVE )->getInfinity();
 -      }
 -
 -      /**
 -       * Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute
 -       * ("24 May 2034"), into an absolute timestamp we can put into the database.
 -       * @param string $expiry whatever was typed into the form
 -       * @return String: timestamp or "infinity" string for th DB implementation
 -       * @deprecated since 1.18 moved to SpecialBlock::parseExpiryInput()
 -       */
 -      public static function parseExpiryInput( $expiry ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              return SpecialBlock::parseExpiryInput( $expiry );
 -      }
 -
        /**
         * Given a target and the target's type, get an existing Block object if possible.
         * @param $specificTarget String|User|Int a block target, which may be one of several types:
                return null;
        }
  
 -
        /**
         * Get all blocks that match any IP from an array of IP addresses
         *
   * @ingroup SpecialPage
   */
  class SpecialBlock extends FormSpecialPage {
 -      /** The maximum number of edits a user can have and still be hidden
 -       * TODO: config setting? */
 -      const HIDEUSER_CONTRIBLIMIT = 1000;
 -
        /** @var User user to be blocked, as passed either by parameter (url?wpTarget=Foo)
         * or as subpage (Special:Block/Foo) */
        protected $target;
  
                $this->maybeAlterFormDefaults( $a );
  
 +              // Allow extensions to add more fields
 +              wfRunHooks( 'SpecialBlockModifyFormFields', array( $this, &$a ) );
 +
                return $a;
        }
  
                if ( $this->requestedHideUser ) {
                        $fields['Confirm']['type'] = 'check';
                        unset( $fields['Confirm']['default'] );
 -                      $this->preErrors[] = 'ipb-confirmhideuser';
 +                      $this->preErrors[] = array( 'ipb-confirmhideuser', 'ipb-confirmaction' );
                }
  
                # Or if the user is trying to block themselves
                if ( (string)$this->target === $this->getUser()->getName() ) {
                        $fields['Confirm']['type'] = 'check';
                        unset( $fields['Confirm']['default'] );
 -                      $this->preErrors[] = 'ipb-blockingself';
 +                      $this->preErrors[] = array( 'ipb-blockingself', 'ipb-confirmaction' );
                }
        }
  
         * @return Bool|String
         */
        public static function processForm( array $data, IContextSource $context ) {
 -              global $wgBlockAllowsUTEdit;
 +              global $wgBlockAllowsUTEdit, $wgHideUserContribLimit;
  
                $performer = $context->getUser();
  
                        if ( $target === $performer->getName() &&
                                ( $data['PreviousTarget'] !== $target || !$data['Confirm'] )
                        ) {
 -                              return array( 'ipb-blockingself' );
 +                              return array( 'ipb-blockingself', 'ipb-confirmaction' );
                        }
                } elseif ( $type == Block::TYPE_RANGE ) {
                        $userId = 0;
                        } elseif ( !in_array( $data['Expiry'], array( 'infinite', 'infinity', 'indefinite' ) ) ) {
                                # Bad expiry.
                                return array( 'ipb_expiry_temp' );
 -                      } elseif ( $user->getEditCount() > self::HIDEUSER_CONTRIBLIMIT ) {
 +                      } elseif ( $wgHideUserContribLimit !== false
 +                              && $user->getEditCount() > $wgHideUserContribLimit
 +                      ) {
                                # Typically, the user should have a handful of edits.
                                # Disallow hiding users with many edits for performance.
 -                              return array( 'ipb_hide_invalid' );
 +                              return array( array( 'ipb_hide_invalid',
 +                                      Message::numParam( $wgHideUserContribLimit ) ) );
                        } elseif ( !$data['Confirm'] ) {
 -                              return array( 'ipb-confirmhideuser' );
 +                              return array( 'ipb-confirmhideuser', 'ipb-confirmaction' );
                        }
                }
  
                $block->isAutoblocking( $data['AutoBlock'] );
                $block->mHideName = $data['HideUser'];
  
 -              if ( !wfRunHooks( 'BlockIp', array( &$block, &$performer ) ) ) {
 -                      return array( 'hookaborted' );
 +              $reason = array( 'hookaborted' );
 +              if ( !wfRunHooks( 'BlockIp', array( &$block, &$performer, &$reason ) ) ) {
 +                      return $reason;
                }
  
                # Try to insert block. Is there a conflicting block?
                                        return array( 'cant-see-hidden-user' );
                                }
  
-                               $currentBlock->delete();
-                               $status = $block->insert();
+                               $currentBlock->isHardblock( $block->isHardblock() );
+                               $currentBlock->prevents( 'createaccount', $block->prevents( 'createaccount' ) );
+                               $currentBlock->mExpiry = $block->mExpiry;
+                               $currentBlock->isAutoblocking( $block->isAutoblocking() );
+                               $currentBlock->mHideName = $block->mHideName;
+                               $currentBlock->prevents( 'sendemail', $block->prevents( 'sendemail' ) );
+                               $currentBlock->prevents( 'editownusertalk', $block->prevents( 'editownusertalk' ) );
+                               $currentBlock->mReason = $block->mReason;
+                               $status = $currentBlock->update();
                                $logaction = 'reblock';
  
                                # Unset _deleted fields if requested