Divert a river through the Augean Stables that is SpecialBlockip.php.
authorHappy-melon <happy-melon@users.mediawiki.org>
Sat, 12 Mar 2011 21:54:35 +0000 (21:54 +0000)
committerHappy-melon <happy-melon@users.mediawiki.org>
Sat, 12 Mar 2011 21:54:35 +0000 (21:54 +0000)
* Move to SpecialBlock.php, and rename class appropriately
* Complete refactor
* Use HTMLForm in block form.  This changes most of the ids and field names on the form, but allows proper validation, nicer formatting, clears up several fixmes, and is generally Better(TM).
* Spin various parts out into static functions, several of which properly belong in the backend (but Block.php is a worse mess still)
* Invert some of the block options so that every checkbox makes the block more severe (so "check to disable email" is fine, but "check to allow usertalk edit" (default true) is inverted to "check to disable usertalk edit" (default false).
* revert r40359 (move doMassUserBlock() to core).  No one seems to be using this function, which has nothing to do with the frontend UI in SpecialBlock (it might perhaps belong in Block.php); it is pretty bespoke for CheckUser, doesn't seem to have very much utility elsewhere.

12 files changed:
RELEASE-NOTES
includes/AutoLoader.php
includes/Block.php
includes/SpecialPage.php
includes/api/ApiBlock.php
includes/api/ApiUnblock.php
includes/specials/SpecialBlock.php [new file with mode: 0644]
includes/specials/SpecialBlockip.php [deleted file]
includes/specials/SpecialIpblocklist.php
languages/messages/MessagesEn.php
maintenance/language/messages.inc
resources/mediawiki.special/mediawiki.special.block.js

index 4671c9e..99301a9 100644 (file)
@@ -55,6 +55,13 @@ PHP if you have not done so prior to upgrading MediaWiki.
   Use $wgBlockCIDRLimit = array( 'IPv4' => 43, 'IPv6' => 128 ) to achieve the same
   functionality as $wgSysopRangeBans; you can use the BlockIp hook to replicate
   $wgSysopUserBans functionality.
+* The options on the block form have been standardised such that checking a box
+  makes the block 'more serious'; so while "check to prevent account creation" and
+  "check to enable autoblock" remain the same, "check to allow user-talk edit" is
+  reversed to "check to *disable* user-talk edit", and "check to block anon-only"
+  becomes "check to block logged-in users too".  The default settings remain the same.
+* Most of the field names on the Special:Block form have been changed, which will
+  probably break screen-scraping bots.
 
 === New features in 1.18 ===
 * Added a special page, disabled by default, that allows users with the
index 74212ad..1e09d10 100644 (file)
@@ -601,7 +601,7 @@ $wgAutoloadLocalClasses = array(
        'SpecialEmailUser' => 'includes/specials/SpecialEmailuser.php',
        'FewestrevisionsPage' => 'includes/specials/SpecialFewestrevisions.php',
        'FileDuplicateSearchPage' => 'includes/specials/SpecialFileDuplicateSearch.php',
-       'IPBlockForm' => 'includes/specials/SpecialBlockip.php',
+       'IPBlockForm' => 'includes/specials/SpecialBlock.php',
        'IPBlocklistPager' => 'includes/specials/SpecialIpblocklist.php',
        'IPUnblockForm' => 'includes/specials/SpecialIpblocklist.php',
        'ImportReporter' => 'includes/specials/SpecialImport.php',
index 162188c..9667056 100644 (file)
@@ -12,6 +12,7 @@
  * Globals used: $wgAutoblockExpiry, $wgAntiLockFlags
  *
  * @todo This could be used everywhere, but it isn't.
+ * FIXME: this whole class is a cesspit, needs a complete rewrite
  */
 class Block {
        /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
@@ -23,6 +24,10 @@ class Block {
        const EB_FOR_UPDATE = 2;
        const EB_RANGE_ONLY = 4;
 
+       const TYPE_USER = 1;
+       const TYPE_IP = 2;
+       const TYPE_RANGE = 3;
+
        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, $byName = false )
@@ -63,7 +68,6 @@ class Block {
        public static function newFromDB( $address, $user = 0, $killExpired = true ) {
                $block = new Block;
                $block->load( $address, $user, $killExpired );
-
                if ( $block->isValid() ) {
                        return $block;
                } else {
index 48e7f02..043f72a 100644 (file)
@@ -136,7 +136,7 @@ class SpecialPage {
                'CreateAccount'             => array( 'SpecialRedirectToSpecial', 'CreateAccount', 'Userlogin', 'signup', array( 'uselang' ) ),
 
                # Users and rights
-               'Blockip'                   => 'IPBlockForm',
+               'Block'                     => 'SpecialBlock',
                'Ipblocklist'               => 'IPUnblockForm',
                'Unblock'                   => array( 'SpecialRedirectToSpecial', 'Unblock', 'Ipblocklist', false, array( 'uselang', 'ip', 'id' ), array( 'action' => 'unblock' ) ),
                'Resetpass'                 => 'SpecialResetpass',
index 37c6057..a719732 100644 (file)
@@ -62,7 +62,7 @@ class ApiBlock extends ApiBase {
                }
                # bug 15810: blocked admins should have limited access here
                if ( $wgUser->isBlocked() ) {
-                       $status = IPBlockForm::checkUnblockSelf( $params['user'] );
+                       $status = SpecialBlock::checkUnblockSelf( $params['user'] );
                        if ( $status !== true ) {
                                $this->dieUsageMsg( array( $status ) );
                        }
@@ -70,35 +70,48 @@ class ApiBlock extends ApiBase {
                if ( $params['hidename'] && !$wgUser->isAllowed( 'hideuser' ) ) {
                        $this->dieUsageMsg( array( 'canthide' ) );
                }
-               if ( $params['noemail'] && !IPBlockForm::canBlockEmail( $wgUser ) ) {
+               if ( $params['noemail'] && !SpecialBlock::canBlockEmail( $wgUser ) ) {
                        $this->dieUsageMsg( array( 'cantblock-email' ) );
                }
 
-               $form = new IPBlockForm( '' );
-               $form->BlockAddress = $params['user'];
-               $form->BlockReason = ( is_null( $params['reason'] ) ? '' : $params['reason'] );
-               $form->BlockReasonList = 'other';
-               $form->BlockExpiry = ( $params['expiry'] == 'never' ? 'infinite' : $params['expiry'] );
-               $form->BlockOther = '';
-               $form->BlockAnonOnly = $params['anononly'];
-               $form->BlockCreateAccount = $params['nocreate'];
-               $form->BlockEnableAutoblock = $params['autoblock'];
-               $form->BlockEmail = $params['noemail'];
-               $form->BlockHideName = $params['hidename'];
-               $form->BlockAllowUsertalk = $params['allowusertalk'] && $wgBlockAllowsUTEdit;
-               $form->BlockReblock = $params['reblock'];
-               $form->BlockWatchUser = $params['watchuser'];
-
-               $userID = $expiry = null;
-               $retval = $form->doBlock( $userID, $expiry );
-               if ( count( $retval ) ) {
+               $data = array(
+                       'Target' => $params['user'],
+                       'Reason' => array(
+                               is_null( $params['reason'] ) ? '' : $params['reason'],
+                               'other',
+                               is_null( $params['reason'] ) ? '' : $params['reason']
+                       ),
+                       'Expiry' => $params['expiry'] == 'never' ? 'infinite' : $params['expiry'],
+                       'HardBlock' => !$params['anononly'],
+                       'CreateAccount' => $params['nocreate'],
+                       'AutoBlock' => $params['autoblock'],
+                       'DisableEmail' => $params['noemail'],
+                       'HideUser' => $params['hidename'],
+                       'DisableUTEdit' => $params['allowusertalk'],
+                       'AlreadyBlocked' => $params['reblock'],
+                       'Watch' => $params['watchuser'],
+               );
+
+               $retval = SpecialBlock::processForm( $data );
+               if ( $retval !== true ) {
                        // We don't care about multiple errors, just report one of them
                        $this->dieUsageMsg( $retval );
                }
 
+               list( $target, $type ) = SpecialBlock::getTargetAndType( $params['user'] );
                $res['user'] = $params['user'];
-               $res['userID'] = intval( $userID );
-               $res['expiry'] = ( $expiry == Block::infinity() ? 'infinite' : wfTimestamp( TS_ISO_8601, $expiry ) );
+               $res['userID'] = $target instanceof User ? $target->getId() : 0;
+
+               $block = SpecialBlock::getBlockFromTargetAndType( $target, $type );
+               if( $block instanceof Block ){
+                       $res['expiry'] = $block->mExpiry == Block::infinity()
+                               ? 'infinite'
+                               : wfTimestamp( TS_ISO_8601, $block->mExpiry );
+               } else {
+                       # should be unreachable
+                       $res['expiry'] = '';
+               }
+
                $res['reason'] = $params['reason'];
                if ( $params['anononly'] ) {
                        $res['anononly'] = '';
index d55fe4c..b0ce803 100644 (file)
@@ -66,7 +66,7 @@ class ApiUnblock extends ApiBase {
                }
                # bug 15810: blocked admins should have limited access here
                if ( $wgUser->isBlocked() ) {
-                       $status = IPBlockForm::checkUnblockSelf( $params['user'] );
+                       $status = SpecialBlock::checkUnblockSelf( $params['user'] );
                        if ( $status !== true ) {
                                $this->dieUsageMsg( array( $status ) );
                        }
diff --git a/includes/specials/SpecialBlock.php b/includes/specials/SpecialBlock.php
new file mode 100644 (file)
index 0000000..f173954
--- /dev/null
@@ -0,0 +1,749 @@
+<?php
+/**
+ * Implements Special:Block
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * A special page that allows users with 'block' right to block users from
+ * editing pages and other actions
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialBlock extends SpecialPage {
+
+       # 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;
+
+       # @var Block::TYPE_ constant
+       protected $type;
+
+       # @var Bool
+       protected $alreadyBlocked;
+
+       public function __construct() {
+               parent::__construct( 'Block', 'block' );
+       }
+
+       public function execute( $par ) {
+               global $wgUser, $wgOut, $wgRequest;
+
+               # Can't block when the database is locked
+               if( wfReadOnly() ) {
+                       $wgOut->readOnlyPage();
+                       return;
+               }
+               # Permission check
+               if( !$this->userCanExecute( $wgUser ) ) {
+                       $wgOut->permissionRequired( 'block' );
+                       return;
+               }
+
+               # Extract variables from the request.  Try not to get into a situation where we
+               # need to extract *every* variable from the form just for processing here, but
+               # there are legitimate uses for some variables
+               list( $this->target, $this->type ) = self::getTargetAndType( $par, $wgRequest );
+               if ( $this->target instanceof User ) {
+                       # Set the 'relevant user' in the skin, so it displays links like Contributions,
+                       # User logs, UserRights, etc.
+                       $wgUser->getSkin()->setRelevantUser( $this->target );
+               }
+       
+               # bug 15810: blocked admins should have limited access here
+               $status = self::checkUnblockSelf( $this->target );
+               if ( $status !== true ) {
+                       throw new ErrorPageError( 'badaccess', $status );
+               }
+
+               $wgOut->setPageTitle( wfMsg( 'blockip-title' ) );
+               $wgOut->addModules( 'mediawiki.special.block' );
+
+               $fields = self::getFormFields();
+               $this->alreadyBlocked = $this->maybeAlterFormDefaults( $fields );
+
+               $form = new HTMLForm( $fields );
+               $form->setTitle( $this->getTitle() );
+               $form->setWrapperLegend( wfMsg( 'blockip-legend' ) );
+               $form->setSubmitCallback( array( __CLASS__, 'processForm' ) );
+
+               $t = $this->alreadyBlocked
+                       ? wfMsg( 'ipb-change-block' )
+                       : wfMsg( 'ipbsubmit' );
+               $form->setSubmitText( $t );
+
+               $this->doPreText( $form );
+               $this->doPostText( $form );
+
+               if( $form->show() ){
+                       $wgOut->setPageTitle( wfMsg( 'blockipsuccesssub' ) );
+                       $wgOut->addHTML( wfMsgExt( 'blockipsuccesstext', array( 'parse' ),  $this->target ) );
+               }
+       }
+
+       /**
+        * Get the HTMLForm descriptor array for the block form
+        * @return Array
+        */
+       protected static function getFormFields(){
+               global $wgUser, $wgBlockAllowsUTEdit;
+
+               $a = array(
+                       'Target' => array(
+                               'type' => 'text',
+                               'label-message' => 'ipadressorusername',
+                               'tabindex' => '1',
+                               'id' => 'mw-bi-target',
+                               'size' => '45',
+                               'required' => true,
+                       ),
+                       'Expiry' => array(
+                               'type' => 'selectorother',
+                               'label-message' => 'ipbexpiry',
+                               'required' => true,
+                               'tabindex' => '2',
+                               'options' => self::getSuggestedDurations(),
+                               'other' => wfMsg( 'ipbother' ),
+                       ),
+                       'Reason' => array(
+                               'type' => 'selectandother',
+                               'label-message' => 'ipbreason',
+                               'options-message' => 'ipbreason-dropdown',
+                       ),
+                       'CreateAccount' => array(
+                               'type' => 'check',
+                               'label-message' => 'ipbcreateaccount',
+                               'default' => true,
+                       ),
+               );
+
+               if( wfMsgForContent( 'ipboptions' ) == '-' ){
+                       $a['Expiry']['type'] = 'text';
+               }
+
+               if( self::canBlockEmail( $wgUser ) ) {
+                       $a['DisableEmail'] = array(
+                               'type' => 'check',
+                               'label-message' => 'ipbemailban',
+                       );
+               }
+
+               if( $wgBlockAllowsUTEdit ){
+                       $a['DisableUTEdit'] = array(
+                               'type' => 'check',
+                               'label-message' => 'ipb-disableusertalk',
+                               'default' => false,
+                       );
+               }
+
+               $a['AutoBlock'] = array(
+                       'type' => 'check',
+                       'label-message' => 'ipbenableautoblock',
+                       'default' => true,
+               );
+
+               # Allow some users to hide name from block log, blocklist and listusers
+               if( $wgUser->isAllowed( 'hideuser' ) ) {
+                       $a['HideUser'] = array(
+                               'type' => 'check',
+                               'label-message' => 'ipbhidename',
+                               'cssclass' => 'mw-block-hideuser',
+                       );
+               }
+
+               # Watchlist their user page? (Only if user is logged in)
+               if( $wgUser->isLoggedIn() ) {
+                       $a['Watch'] = array(
+                               'type' => 'check',
+                               'label-message' => 'ipbwatchuser',
+                       );
+               }
+
+               $a['HardBlock'] = array(
+                       'type' => 'check',
+                       'label-message' => 'ipb-hardblock',
+                       'default' => false,
+               );
+
+               $a['AlreadyBlocked'] = array(
+                       'type' => 'hidden',
+                       'default' => false,
+               );
+
+               return $a;
+       }
+
+       /**
+        * If the user has already been blocked with similar settings, load that block
+        * and change the defaults for the form fields to match the existing settings.
+        * @param &$fields Array HTMLForm descriptor array
+        * @return Bool whether fields were altered (that is, whether the target is
+        *     already blocked)
+        */
+       protected function maybeAlterFormDefaults( &$fields ){
+               $fields['Target']['default'] = $this->target;
+
+               $block = self::getBlockFromTargetAndType( $this->target, $this->type );
+
+               if( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
+                       && ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
+                         || $block->mAddress == $this->target ) # or if it is, the range is what we're about to block
+                       )
+               {
+                       $fields['HardBlock']['default'] = !$block->mAnonOnly;
+                       $fields['CreateAccount']['default'] = $block->mCreateAccount;
+                       $fields['AutoBlock']['default'] = $block->mEnableAutoblock;
+                       $fields['DisableEmail']['default'] = $block->mBlockEmail;
+                       $fields['HideUser']['default'] = $block->mHideName;
+                       $fields['DisableUTEdit']['default'] = !$block->mAllowUsertalk;
+                       $fields['Reason']['default'] = $block->mReason;
+                       $fields['AlreadyBlocked']['default'] = true;
+
+                       if( $block->mExpiry == 'infinity' ) {
+                               $fields['Expiry']['default'] = 'indefinite';
+                       } else {
+                               $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->mExpiry );
+                       }
+
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Add header elements like block log entries, etc.
+        * @param  $form HTMLForm
+        * @return void
+        */
+       protected function doPreText( HTMLForm &$form ){
+               $form->addPreText( wfMsgExt( 'blockiptext', 'parse' ) );
+
+               $otherBlockMessages = array();
+               if( $this->target !== null ) {
+                       # Get other blocks, i.e. from GlobalBlocking or TorBlock extension
+                       wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockMessages, $this->target ) );
+
+                       if( count( $otherBlockMessages ) ) {
+                               $s = Html::rawElement(
+                                       'h2',
+                                       array(),
+                                       wfMsgExt( 'ipb-otherblocks-header', 'parseinline', count( $otherBlockMessages ) )
+                               ) . "\n";
+                               $list = '';
+                               foreach( $otherBlockMessages as $link ) {
+                                       $list .= Html::rawElement( 'li', array(), $link ) . "\n";
+                               }
+                               $s .= Html::rawElement(
+                                       'ul',
+                                       array( 'class' => 'mw-blockip-alreadyblocked' ),
+                                       $list
+                               ) . "\n";
+                               $form->addPreText( $s );
+                       }
+               }
+
+               # Username/IP is blocked already locally
+               if( $this->alreadyBlocked ) {
+                       $form->addPreText( Html::rawElement(
+                               'div',
+                               array( 'class' => 'mw-ipb-needreblock', ),
+                               wfMsgExt(
+                                       'ipb-needreblock',
+                                       array( 'parseinline' ),
+                                       $this->target
+                       ) ) );
+               }
+       }
+
+       /**
+        * Add footer elements to the form
+        * @param  $form HTMLForm
+        * @return void
+        */
+       protected function doPostText( HTMLForm &$form ){
+               global $wgUser, $wgLang;
+
+               $skin = $wgUser->getSkin();
+
+               # Link to the user's contributions, if applicable
+               if( $this->target instanceof User ){
+                       $contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->target->getName() );
+                       $links[] = $skin->link(
+                               $contribsPage,
+                               wfMsgExt( 'ipb-blocklist-contribs', 'escape', $this->target->getName() )
+                       );
+               }
+
+               # Link to unblock the specified user, or to a blank unblock form
+               $list = SpecialPage::getTitleFor( 'Ipblocklist' );
+               $query = array( 'action' => 'unblock' );
+               if( $this->target instanceof User ) {
+                       $message = wfMsgExt( 'ipb-unblock-addr', array( 'parseinline' ), $this->target->getName() );
+                       $query['ip'] = $this->target->getName();
+               } else {
+                       $message = wfMsgExt( 'ipb-unblock', array( 'parseinline' ) );
+               }
+               $links[] = $skin->linkKnown( $list, $message, array(), $query );
+
+               # Link to the block list
+               $links[] = $skin->linkKnown(
+                       SpecialPage::getTitleFor( 'Ipblocklist' ),
+                       wfMsg( 'ipb-blocklist' )
+               );
+
+               # Link to edit the block dropdown reasons, if applicable
+               if ( $wgUser->isAllowed( 'editinterface' ) ) {
+                       $links[] = $skin->link(
+                               Title::makeTitle( NS_MEDIAWIKI, 'Ipbreason-dropdown' ),
+                               wfMsgHtml( 'ipb-edit-dropdown' ),
+                               array(),
+                               array( 'action' => 'edit' )
+                       );
+               }
+
+               $form->addPostText( Html::rawElement(
+                       'p',
+                       array( 'class' => 'mw-ipb-conveniencelinks' ),
+                       $wgLang->pipeList( $links )
+               ) );
+
+               if( $this->target instanceof User ){
+                       # Get relevant extracts from the block and suppression logs, if possible
+                       $userpage = $this->target->getUserPage();
+                       $out = '';
+
+                       LogEventsList::showLogExtract(
+                               $out,
+                               'block',
+                               $userpage->getPrefixedText(),
+                               '',
+                               array(
+                                       'lim' => 10,
+                                       'msgKey' => array( 'blocklog-showlog', $userpage->getText() ),
+                                       'showIfEmpty' => false
+                               )
+                       );
+                       $form->addPostText( $out );
+
+                       # Add suppression block entries if allowed
+                       if( $wgUser->isAllowed( 'suppressionlog' ) ) {
+                               LogEventsList::showLogExtract(
+                                       $out,
+                                       'suppress',
+                                       $userpage->getPrefixedText(),
+                                       '',
+                                       array(
+                                               'lim' => 10,
+                                               'conds' => array( 'log_action' => array( 'block', 'reblock', 'unblock' ) ),
+                                               'msgKey' => array( 'blocklog-showsuppresslog', $userpage->getText() ),
+                                               'showIfEmpty' => false
+                                       )
+                               );
+                               $form->addPostText( $out );
+                       }
+               }
+       }
+
+       /**
+        * Determine the target of the block, and the type of target
+        * TODO: should be in Block.php?
+        * @param $par String subpage parameter passed to setup, or data value from
+        *     the HTMLForm
+        * @param $request WebRequest optionally try and get data from a request too
+        * @return void
+        */
+       public static function getTargetAndType( $par, WebRequest $request = null ){
+               $i = 0;
+               $target = null;
+               while( true ){
+                       switch( $i++ ){
+                               case 0:
+                                       # The HTMLForm will check wpTarget first and only if it doesn't get
+                                       # a value use the default, which will be generated from the options
+                                       # below; so this has to have a higher precedence here than $par, or
+                                       # we could end up with different values in $this->target and the HTMLForm!
+                                       if( $request instanceof WebRequest ){
+                                               $target = $request->getText( 'wpTarget', null );
+                                       }
+                               break;
+                               case 1:
+                                       $target = $par;
+                                       break;
+                               case 2:
+                                       if( $request instanceof WebRequest ){
+                                               $target = $request->getText( 'ip', null );
+                                       }
+                               break;
+                               case 3:
+                                       # B/C @since 1.18
+                                       if( $request instanceof WebRequest ){
+                                               $target = $request->getText( 'wpBlockAddress', null );
+                                       }
+                               break;
+                               case 4:
+                                       break 2;
+                       }
+
+                       $userObj = User::newFromName( $target );
+                       if( $userObj instanceof User ){
+                               return array( $userObj, Block::TYPE_USER );
+                       } elseif( IP::isValid( $target ) ){
+                               # We can still create a User if it's an IP address, but we need to turn
+                               # off validation checking (which would exclude IP addresses)
+                               return array(
+                                       User::newFromName( IP::sanitizeIP( $target ), false ),
+                                       Block::TYPE_IP
+                               );
+                               break;
+                       } elseif( IP::isValidBlock( $target ) ){
+                               # Can't create a User from an IP range
+                               return array( Block::normaliseRange( $target ), Block::TYPE_RANGE );
+                       }
+               }
+               return array( null, null );
+       }
+
+       /**
+        * Given a target and the target's type, get a block object if possible
+        * @param $target String|User
+        * @param $type Block::TYPE_ constant
+        * @return Block|null
+        * TODO: this probably belongs in Block.php when that mess is cleared up
+        */
+       public static function getBlockFromTargetAndType( $target, $type ){
+               if( $target instanceof User ){
+                       if( $type == Block::TYPE_IP ){
+                               return Block::newFromDB( $target->getName(), 0 );
+                       } elseif( $type == Block::TYPE_USER ) {
+                               return Block::newFromDB( '', $target->getId() );
+                       } else {
+                               # Should be unreachable;
+                               return null;
+                       }
+               } elseif( $type == Block::TYPE_RANGE ){
+                       return Block::newFromDB( '', $target );
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Given the form data, actually implement a block
+        * @param  $data Array
+        * @return Bool|String
+        */
+       public static function processForm( array $data ){
+               global $wgUser, $wgBlockAllowsUTEdit, $wgBlockCIDRLimit;
+
+               list( $target, $type ) = self::getTargetAndType( $data['Target'] );
+
+               if( $type == Block::TYPE_USER ){
+                       # TODO: why do we not have a User->exists() method?
+                       if( !$target->getId() ){
+                               return array( array( 'nosuchusershort', $target->getName() ) );
+                       }
+
+                       $status = self::checkUnblockSelf( $target );
+                       if ( $status !== true ) {
+                               return array( array( 'badaccess', $status ) );
+                       }
+
+                       $user = $target;
+                       $target = $user->getName();
+                       $userId = $user->getId();
+
+               } elseif( $type == Block::TYPE_RANGE ){
+                       list( $ip, $range ) = explode( '/', $target, 2 );
+
+                       if( ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 )
+                               || ( IP::isIPv6( $ip ) && $wgBlockCIDRLimit['IPV6'] == 128 ) )
+                       {
+                               # Range block effectively disabled
+                               return array( 'range_block_disabled' );
+                       }
+
+                       if( ( IP::isIPv4( $ip ) && $range > 32 )
+                               || ( IP::isIPv6( $ip ) && $range > 128 ) )
+                       {
+                               # Dodgy range
+                               return array( 'ip_range_invalid' );
+                       }
+
+                       if( IP::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
+                               return array( array( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] ) );
+                       }
+
+                       if( IP::isIPv6( $ip ) && $range < $wgBlockCIDRLimit['IPv6'] ) {
+                               return array( array( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] ) );
+                       }
+
+                       $userId = 0;
+
+               } elseif( $type == Block::TYPE_IP ){
+                       # All is well
+                       $target = $target->getName();
+                       $userId = 0;
+
+               } else {
+                       return array( 'badipaddress' );
+               }
+
+               if( ( strlen( $data['Expiry'] ) == 0) || ( strlen( $data['Expiry'] ) > 50 )
+                       || !Block::parseExpiryInput( $data['Expiry'] ) )
+               {
+                       return array( 'ipb_expiry_invalid' );
+               }
+
+               if( !$wgBlockAllowsUTEdit ){
+                       $data['PreventUTEdit'] = true;
+               }
+
+               # If the user has done the form 'properly', they won't even have been given the
+               # option to suppress-block unless they have the 'hideuser' permission
+               if( !isset( $data['HideUser'] ) ){
+                       $data['HideUser'] = false;
+               }
+               if( $data['HideUser'] ) {
+                       if( !$wgUser->isAllowed('hideuser') ){
+                               # this codepath is unreachable except by a malicious user spoofing forms,
+                               # or by race conditions (user has oversight and sysop, loads block form,
+                               # and is de-oversighted before submission); so need to fail completely
+                               # rather than just silently disable hiding
+                               return array( 'badaccess-group0' );
+                       }
+
+                       # Recheck params here...
+                       if( $type != Block::TYPE_USER ) {
+                               $data['HideUser'] = false; # IP users should not be hidden
+
+                       } elseif( !in_array( $data['Expiry'], array( 'inifinite', 'infinity', 'indefinite' ) ) ) {
+                               # Bad expiry.
+                               return array( 'ipb_expiry_temp' );
+
+                       } elseif( $user->getEditCount() > self::HIDEUSER_CONTRIBLIMIT ) {
+                               # Typically, the user should have a handful of edits.
+                               # Disallow hiding users with many edits for performance.
+                               return array( 'ipb_hide_invalid' );
+                       }
+               }
+
+               # Create block object.  Note that for a user block, ipb_address is only for display purposes
+               # FIXME: Why do we need to pass fourteen optional parameters to do this!?!
+               $block = new Block(
+                       $target,                                    # IP address or User name
+                       $userId,                                    # User id
+                       $wgUser->getId(),                           # Blocker id
+                       $data['Reason'][0],                         # Reason string
+                       wfTimestampNow(),                           # Block Timestamp
+                       0,                                          # Is this an autoblock (no)
+                       Block::parseExpiryInput( $data['Expiry'] ), # Expiry time
+                       !$data['HardBlock'],                        # Block anon only
+                       $data['CreateAccount'],
+                       $data['AutoBlock'],
+                       $data['HideUser'],
+                       $data['DisableEmail'],
+                       !$data['DisableUTEdit']                     # *Allow* UTEdit
+               );
+
+               if( !wfRunHooks( 'BlockIp', array( &$block, &$wgUser ) ) ) {
+                       return array( 'hookaborted' );
+               }
+
+               # Try to insert block. Is there a conflicting block?
+               if( !$block->insert() ) {
+
+                       # Show form unless the user is already aware of this...
+                       if( !$data['AlreadyBlocked'] ) {
+                               return array( array( 'ipb_already_blocked', $data['Target'] ) );
+
+                       # Otherwise, try to update the block...
+                       } else {
+
+                               # This returns direct blocks before autoblocks/rangeblocks, since we should
+                               # be sure the user is blocked by now it should work for our purposes
+                               $currentBlock = Block::newFromDB( $target, $userId );
+
+                               if( $block->equals( $currentBlock ) ) {
+                                       return array( 'ipb_already_blocked' );
+                               }
+
+                               # If the name was hidden and the blocking user cannot hide
+                               # names, then don't allow any block changes...
+                               if( $currentBlock->mHideName && !$wgUser->isAllowed( 'hideuser' ) ) {
+                                       return array( 'cant-see-hidden-user' );
+                               }
+
+                               $currentBlock->delete();
+                               $block->insert();
+                               $logaction = 'reblock';
+
+                               # Unset _deleted fields if requested
+                               if( $currentBlock->mHideName && !$data['HideUser'] ) {
+                                       RevisionDeleteUser::unsuppressUserName( $target, $userId );
+                               }
+
+                               # If hiding/unhiding a name, this should go in the private logs
+                               if( (bool)$currentBlock->mHideName ){
+                                       $data['HideUser'] = true;
+                               }
+                       }
+
+               } else {
+                       $logaction = 'block';
+               }
+
+               wfRunHooks( 'BlockIpComplete', array( $block, $wgUser ) );
+
+               # Set *_deleted fields if requested
+               if( $data['HideUser'] ) {
+                       RevisionDeleteUser::suppressUserName( $target, $userId );
+               }
+
+               # Can't watch a rangeblock
+               if( $type != Block::TYPE_RANGE && $data['Watch'] ) {
+                       $wgUser->addWatch( Title::makeTitle( NS_USER, $target ) );
+               }
+
+               # Block constructor sanitizes certain block options on insert
+               $data['BlockEmail'] = $block->mBlockEmail;
+               $data['AutoBlock'] = $block->mEnableAutoblock;
+
+               # Prepare log parameters
+               $logParams = array();
+               $logParams[] = $data['Expiry'];
+               $logParams[] = self::blockLogFlags( $data, $type );
+
+               # Make log entry, if the name is hidden, put it in the oversight log
+               $log_type = $data['HideUser'] ? 'suppress' : 'block';
+               $log = new LogPage( $log_type );
+               $log->addEntry(
+                       $logaction,
+                       Title::makeTitle( NS_USER, $target ),
+                       $data['Reason'][0],
+                       $logParams
+               );
+
+               # Report to the user
+               return true;
+       }
+
+       /**
+        * Get an array of suggested block durations from MediaWiki:Ipboptions
+        * FIXME: this uses a rather odd syntax for the options, should it be converted
+        *     to the standard "**<duration>|<displayname>" format?
+        * @return Array
+        */
+       protected static function getSuggestedDurations(){
+               $a = array();
+               foreach( explode( ',', wfMsgForContent( 'ipboptions' ) ) as $option ) {
+                       if( strpos( $option, ':' ) === false ) $option = "$option:$option";
+                       list( $show, $value ) = explode( ':', $option );
+                       $a[htmlspecialchars( $show )] = htmlspecialchars( $value );
+               }
+               return $a;
+       }
+
+       /**
+        * Can we do an email block?
+        * @param $user User: the sysop wanting to make a block
+        * @return Boolean
+        */
+       public static function canBlockEmail( $user ) {
+               global $wgEnableUserEmail, $wgSysopEmailBans;
+               return ( $wgEnableUserEmail && $wgSysopEmailBans && $user->isAllowed( 'blockemail' ) );
+       }
+
+       /**
+        * bug 15810: blocked admins should not be able to block/unblock
+        * others, and probably shouldn't be able to unblock themselves
+        * either.
+        * @param $user User|Int|String
+        */
+       public static function checkUnblockSelf( $user ) {
+               global $wgUser;
+               if ( is_int( $user ) ) {
+                       $user = User::newFromId( $user );
+               } elseif ( is_string( $user ) ) {
+                       $user = User::newFromName( $user );
+               }
+               if( $wgUser->isBlocked() ){
+                       if( $user instanceof User && $user->getId() == $wgUser->getId() ) {
+                               # User is trying to unblock themselves
+                               if ( $wgUser->isAllowed( 'unblockself' ) ) {
+                                       return true;
+                               } else {
+                                       return 'ipbnounblockself';
+                               }
+                       } else {
+                               # User is trying to block/unblock someone else
+                               return 'ipbblocked';
+                       }
+               } else {
+                       return true;
+               }
+       }
+
+       /**
+        * Return a comma-delimited list of "flags" to be passed to the log
+        * reader for this block, to provide more information in the logs
+        * @param $data Array from HTMLForm data
+        * @param $type Block::TYPE_ constant
+        * @return array
+        */
+       protected static function blockLogFlags( array $data, $type ) {
+               global $wgBlockAllowsUTEdit;
+               $flags = array();
+
+               # when blocking a user the option 'anononly' is not available/has no effect -> do not write this into log
+               if( !$data['HardBlock'] && $type != Block::TYPE_USER ){
+                       $flags[] = 'anononly';
+               }
+
+               if( $data['CreateAccount'] ){
+                       $flags[] = 'nocreate';
+               }
+
+               # Same as anononly, this is not displayed when blocking an IP address
+               if( !$data['AutoBlock'] && $type != Block::TYPE_IP ){
+                       $flags[] = 'noautoblock';
+               }
+
+               if( $data['DisableEmail'] ){
+                       $flags[] = 'noemail';
+               }
+
+               if( $data['DisableUTEdit'] && $wgBlockAllowsUTEdit ){
+                       $flags[] = 'nousertalk';
+               }
+
+               if( $data['HideUser'] ){
+                       $flags[] = 'hiddenname';
+               }
+
+               return implode( ',', $flags );
+       }
+}
+
+# BC @since 1.18
+class IPBlockForm extends SpecialBlock {}
diff --git a/includes/specials/SpecialBlockip.php b/includes/specials/SpecialBlockip.php
deleted file mode 100644 (file)
index 22f4edb..0000000
+++ /dev/null
@@ -1,846 +0,0 @@
-<?php
-/**
- * Implements Special:Blockip
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup SpecialPage
- */
-
-/**
- * A special page that allows users with 'block' right to block users from
- * editing pages and other actions
- *
- * @ingroup SpecialPage
- */
-class IPBlockForm extends SpecialPage {
-       var $BlockAddress, $BlockExpiry, $BlockReason, $BlockReasonList, $BlockOther, $BlockAnonOnly, $BlockCreateAccount,
-               $BlockEnableAutoblock, $BlockEmail, $BlockHideName, $BlockAllowUsertalk, $BlockReblock, $BlockWatchUser;
-       // The maximum number of edits a user can have and still be hidden
-       const HIDEUSER_CONTRIBLIMIT = 1000;
-
-       public function __construct() {
-               parent::__construct( 'Blockip', 'block' );
-       }
-
-       public function execute( $par ) {
-               global $wgUser, $wgOut, $wgRequest;
-
-               # Can't block when the database is locked
-               if( wfReadOnly() ) {
-                       $wgOut->readOnlyPage();
-                       return;
-               }
-               # Permission check
-               if( !$this->userCanExecute( $wgUser ) ) {
-                       $wgOut->permissionRequired( 'block' );
-                       return;
-               }
-
-               $this->setup( $par );
-       
-               # bug 15810: blocked admins should have limited access here
-               if ( $wgUser->isBlocked() ) {
-                       $status = IPBlockForm::checkUnblockSelf( $this->BlockAddress );
-                       if ( $status !== true ) {
-                               throw new ErrorPageError( 'badaccess', $status );
-                       }
-               }
-
-               $action = $wgRequest->getVal( 'action' );
-               if( 'success' == $action ) {
-                       $this->showSuccess();
-               } elseif( $wgRequest->wasPosted() && 'submit' == $action &&
-                       $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
-                       $this->doSubmit();
-               } else {
-                       $this->showForm( '' );
-               }
-       }
-
-       private function setup( $par ) {
-               global $wgRequest, $wgUser, $wgBlockAllowsUTEdit;
-
-               $this->BlockAddress = $wgRequest->getVal( 'wpBlockAddress', $wgRequest->getVal( 'ip', $par ) );
-               $this->BlockAddress = strtr( $this->BlockAddress, '_', ' ' );
-               $this->BlockReason = $wgRequest->getText( 'wpBlockReason' );
-               $this->BlockReasonList = $wgRequest->getText( 'wpBlockReasonList' );
-               $this->BlockExpiry = $wgRequest->getVal( 'wpBlockExpiry', wfMsg( 'ipbotheroption' ) );
-               $this->BlockOther = $wgRequest->getVal( 'wpBlockOther', '' );
-
-               # Unchecked checkboxes are not included in the form data at all, so having one
-               # that is true by default is a bit tricky
-               $byDefault = !$wgRequest->wasPosted();
-               $this->BlockAnonOnly = $wgRequest->getBool( 'wpAnonOnly', $byDefault );
-               $this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', $byDefault );
-               $this->BlockEnableAutoblock = $wgRequest->getBool( 'wpEnableAutoblock', $byDefault );
-               $this->BlockEmail = false;
-               if( self::canBlockEmail( $wgUser ) ) {
-                       $this->BlockEmail = $wgRequest->getBool( 'wpEmailBan', false );
-               }
-               $this->BlockWatchUser = $wgRequest->getBool( 'wpWatchUser', false ) && $wgUser->isLoggedIn();
-               # Re-check user's rights to hide names, very serious, defaults to null
-               if( $wgUser->isAllowed( 'hideuser' ) ) {
-                       $this->BlockHideName = $wgRequest->getBool( 'wpHideName', null );
-               } else {
-                       $this->BlockHideName = false;
-               }
-               $this->BlockAllowUsertalk = ( $wgRequest->getBool( 'wpAllowUsertalk', $byDefault ) && $wgBlockAllowsUTEdit );
-               $this->BlockReblock = $wgRequest->getBool( 'wpChangeBlock', false );
-               
-               $this->wasPosted = $wgRequest->wasPosted();
-       }
-
-       public function showForm( $err ) {
-               global $wgOut, $wgUser;
-
-               $wgOut->setPageTitle( wfMsg( 'blockip-title' ) );
-               $wgOut->addWikiMsg( 'blockiptext' );
-
-               $mIpaddress = Xml::label( wfMsg( 'ipadressorusername' ), 'mw-bi-target' );
-               $mIpbexpiry = Xml::label( wfMsg( 'ipbexpiry' ), 'wpBlockExpiry' );
-               $mIpbother = Xml::label( wfMsg( 'ipbother' ), 'mw-bi-other' );
-               $mIpbreasonother = Xml::label( wfMsg( 'ipbreason' ), 'wpBlockReasonList' );
-               $mIpbreason = Xml::label( wfMsg( 'ipbotherreason' ), 'mw-bi-reason' );
-
-               $titleObj = SpecialPage::getTitleFor( 'Blockip' );
-               $user = User::newFromName( $this->BlockAddress );
-               if ( is_object( $user ) || User::isIP( $this->BlockAddress ) ) {
-                       $wgUser->getSkin()->setRelevantUser( is_object($user) ? $user : User::newFromName( $this->BlockAddress, false ) );
-               }
-
-               $alreadyBlocked = false;
-               $otherBlockedMsgs = array();
-               if( $err && $err[0] != 'ipb_already_blocked' ) {
-                       $key = array_shift( $err );
-                       $msg = wfMsgExt( $key, 'parsemag', $err );
-                       $wgOut->setSubtitle( wfMsgHtml( 'formerror' ) );
-                       $wgOut->addHTML( Xml::tags( 'p', array( 'class' => 'error' ), $msg ) );
-               } elseif( $this->BlockAddress !== null ) {
-                       # Get other blocks, i.e. from GlobalBlocking or TorBlock extension
-                       wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockedMsgs, $this->BlockAddress ) );
-
-                       $userId = is_object( $user ) ? $user->getId() : 0;
-                       $currentBlock = Block::newFromDB( $this->BlockAddress, $userId );
-                       if( !is_null( $currentBlock ) && !$currentBlock->mAuto && # The block exists and isn't an autoblock
-                               ( $currentBlock->mRangeStart == $currentBlock->mRangeEnd || # The block isn't a rangeblock
-                               # or if it is, the range is what we're about to block
-                               ( $currentBlock->mAddress == $this->BlockAddress ) )
-                       ) {
-                               $alreadyBlocked = true;
-                               # Set the block form settings to the existing block
-                               if( !$this->wasPosted ) {
-                                       $this->BlockAnonOnly = $currentBlock->mAnonOnly;
-                                       $this->BlockCreateAccount = $currentBlock->mCreateAccount;
-                                       $this->BlockEnableAutoblock = $currentBlock->mEnableAutoblock;
-                                       $this->BlockEmail = $currentBlock->mBlockEmail;
-                                       $this->BlockHideName = $currentBlock->mHideName;
-                                       $this->BlockAllowUsertalk = $currentBlock->mAllowUsertalk;
-                                       if( $currentBlock->mExpiry == 'infinity' ) {
-                                               $this->BlockOther = 'indefinite';
-                                       } else {
-                                               $this->BlockOther = wfTimestamp( TS_ISO_8601, $currentBlock->mExpiry );
-                                       }
-                                       $this->BlockReason = $currentBlock->mReason;
-                               }
-                       }
-               }
-
-               # Show other blocks from extensions, i.e. GlockBlocking and TorBlock
-               if( count( $otherBlockedMsgs ) ) {
-                       $wgOut->addHTML(
-                               Html::rawElement( 'h2', array(), wfMsgExt( 'ipb-otherblocks-header', 'parseinline', count( $otherBlockedMsgs ) ) ) . "\n"
-                       );
-                       $list = '';
-                       foreach( $otherBlockedMsgs as $link ) {
-                               $list .= Html::rawElement( 'li', array(), $link ) . "\n";
-                       }
-                       $wgOut->addHTML( Html::rawElement( 'ul', array( 'class' => 'mw-blockip-alreadyblocked' ), $list ) . "\n" );
-               }
-
-               # Username/IP is blocked already locally
-               if( $alreadyBlocked ) {
-                       $wgOut->wrapWikiMsg( "<div class='mw-ipb-needreblock'>\n$1\n</div>", array( 'ipb-needreblock', $this->BlockAddress ) );
-               }
-
-               $scBlockExpiryOptions = wfMsgForContent( 'ipboptions' );
-
-               $showblockoptions = $scBlockExpiryOptions != '-';
-               if( !$showblockoptions ) $mIpbother = $mIpbexpiry;
-
-               $blockExpiryFormOptions = Xml::option( wfMsg( 'ipbotheroption' ), 'other' );
-               foreach( explode( ',', $scBlockExpiryOptions ) as $option ) {
-                       if( strpos( $option, ':' ) === false ) $option = "$option:$option";
-                       list( $show, $value ) = explode( ':', $option );
-                       $show = htmlspecialchars( $show );
-                       $value = htmlspecialchars( $value );
-                       $blockExpiryFormOptions .= Xml::option( $show, $value, $this->BlockExpiry === $value ) . "\n";
-               }
-
-               $reasonDropDown = Xml::listDropDown( 'wpBlockReasonList',
-                       wfMsgForContent( 'ipbreason-dropdown' ),
-                       wfMsgForContent( 'ipbreasonotherlist' ), $this->BlockReasonList, 'wpBlockDropDown', 4 );
-
-               # FIXME: this should actually use HTMLForm, not just some of its JavaScript
-               $wgOut->addModules( array( 'mediawiki.special.block', 'mediawiki.htmlform' ) );
-               
-               $wgOut->addHTML(
-                       Xml::openElement( 'form', array( 'method' => 'post', 'action' => $titleObj->getLocalURL( 'action=submit' ), 'id' => 'blockip' ) ) .
-                       Xml::openElement( 'fieldset' ) .
-                       Xml::element( 'legend', null, wfMsg( 'blockip-legend' ) ) .
-                       Xml::openElement( 'table', array( 'border' => '0', 'id' => 'mw-blockip-table' ) ) .
-                       "<tr>
-                               <td class='mw-label'>
-                                       {$mIpaddress}
-                               </td>
-                               <td class='mw-input'>" .
-                                       Html::input( 'wpBlockAddress', $this->BlockAddress, 'text', array(
-                                               'tabindex' => '1',
-                                               'id' => 'mw-bi-target',
-                                               'size' => '45',
-                                               'required' => ''
-                                       ) + ( $this->BlockAddress ? array() : array( 'autofocus' ) ) ). "
-                               </td>
-                       </tr>
-                       <tr>
-                               <td class='mw-label'>
-                                       {$mIpbexpiry}
-                               </td>
-                               <td class='mw-input'>"
-               );
-               if( $showblockoptions ) {
-                       $wgOut->addHTML(
-                                       Xml::tags( 'select',
-                                               array(
-                                                       'id' => 'wpBlockExpiry',
-                                                       'name' => 'wpBlockExpiry',
-                                                       'class' => 'mw-htmlform-select-or-other', # FIXME: actually make this use HTMLForm
-                                                       'tabindex' => '2' ),
-                                               $blockExpiryFormOptions
-                                       ) . "<br/>\n"
-                       );
-               }
-               $wgOut->addHTML(
-                                       Xml::input(
-                                               'wpBlockOther',
-                                               45,
-                                               $this->BlockOther,
-                                               array(
-                                                       'tabindex' => '3',
-                                                       'id' => 'wpBlockExpiry-other'
-                                               )
-                                       ) . "
-                               </td>
-                       </tr>
-                       <tr>
-                               <td class='mw-label'>
-                                       {$mIpbreasonother}
-                               </td>
-                               <td class='mw-input'>
-                                       {$reasonDropDown}
-                               </td>
-                       </tr>
-                       <tr id=\"wpBlockReason\">
-                               <td class='mw-label'>
-                                       {$mIpbreason}
-                               </td>
-                               <td class='mw-input'>" .
-                               Html::input( 'wpBlockReason', $this->BlockReason, 'text', array(
-                                       'tabindex' => '5',
-                                       'id' => 'mw-bi-reason',
-                                       'maxlength' => '200',
-                                       'size' => '45'
-                               ) + ( $this->BlockAddress ? array( 'autofocus' ) : array() ) ) . "
-                               </td>
-                       </tr>
-                       <tr id='wpCreateAccountRow'>
-                               <td>&#160;</td>
-                               <td class='mw-input'>" .
-                                       Xml::checkLabel( wfMsg( 'ipbcreateaccount' ),
-                                               'wpCreateAccount', 'wpCreateAccount', $this->BlockCreateAccount,
-                                               array( 'tabindex' => '7' ) ) . "
-                               </td>
-                       </tr>"
-               );
-
-               if( self::canBlockEmail( $wgUser ) ) {
-                       $wgOut->addHTML("
-                               <tr id='wpEnableEmailBan'>
-                                       <td>&#160;</td>
-                                       <td class='mw-input'>" .
-                                               Xml::checkLabel( wfMsg( 'ipbemailban' ),
-                                                       'wpEmailBan', 'wpEmailBan', $this->BlockEmail,
-                                                       array( 'tabindex' => '9' ) ) . "
-                                       </td>
-                               </tr>"
-                       );
-               }
-
-               # Can we explicitly disallow the use of user_talk?
-               global $wgBlockAllowsUTEdit;
-               if( $wgBlockAllowsUTEdit ){
-                       $wgOut->addHTML("
-                               <tr id='wpAllowUsertalkRow'>
-                                       <td>&#160;</td>
-                                       <td class='mw-input'>" .
-                                               Xml::checkLabel( wfMsg( 'ipballowusertalk' ),
-                                                       'wpAllowUsertalk', 'wpAllowUsertalk', $this->BlockAllowUsertalk,
-                                                       array( 'tabindex' => '12' ) ) . "
-                                       </td>
-                               </tr>"
-                       );
-               }
-
-               $wgOut->addHTML( "
-                       <tr id='wpEnableAutoblockRow'>
-                               <td>&#160;</td>
-                               <td class='mw-input'>" .
-                                       Xml::checkLabel( wfMsg( 'ipbenableautoblock' ),
-                                               'wpEnableAutoblock', 'wpEnableAutoblock', $this->BlockEnableAutoblock,
-                                               array( 'tabindex' => '8' ) ) . "
-                               </td>
-                       </tr>"
-               );
-
-               // Allow some users to hide name from block log, blocklist and listusers
-               if( $wgUser->isAllowed( 'hideuser' ) ) {
-                       $wgOut->addHTML("
-                               <tr id='wpEnableHideUser'>
-                                       <td>&#160;</td>
-                                       <td class='mw-input'><strong>" .
-                                               Xml::checkLabel( wfMsg( 'ipbhidename' ),
-                                                       'wpHideName', 'wpHideName', $this->BlockHideName,
-                                                       array( 'tabindex' => '10' )
-                                               ) . "
-                                       </strong></td>
-                               </tr>"
-                       );
-               }
-
-               # Watchlist their user page? (Only if user is logged in)
-               if( $wgUser->isLoggedIn() ) {
-                       $wgOut->addHTML("
-                       <tr id='wpEnableWatchUser'>
-                               <td>&#160;</td>
-                               <td class='mw-input'>" .
-                                       Xml::checkLabel( wfMsg( 'ipbwatchuser' ),
-                                               'wpWatchUser', 'wpWatchUser', $this->BlockWatchUser,
-                                               array( 'tabindex' => '11' ) ) . "
-                               </td>
-                       </tr>"
-                       );
-               }
-
-               $wgOut->addHTML("
-                       <tr id='wpAnonOnlyRow'>
-                               <td>&#160;</td>
-                               <td class='mw-input'>" .
-                                       Xml::checkLabel( wfMsg( 'ipbanononly' ),
-                                                       'wpAnonOnly', 'wpAnonOnly', $this->BlockAnonOnly,
-                                                       array( 'tabindex' => '6' ) ) . "
-                               </td>
-                       </tr>
-                       <tr>
-                               <td style='padding-top: 1em'>&#160;</td>
-                               <td  class='mw-submit' style='padding-top: 1em'>" .
-                                       Xml::submitButton( wfMsg( $alreadyBlocked ? 'ipb-change-block' : 'ipbsubmit' ),
-                                               array( 'name' => 'wpBlock', 'tabindex' => '13' )
-                                                       + $wgUser->getSkin()->tooltipAndAccessKeyAttribs( 'blockip-block' ) ). "
-                               </td>
-                       </tr>" .
-                       Xml::closeElement( 'table' ) .
-                       Html::hidden( 'wpEditToken', $wgUser->editToken() ) .
-                       ( $alreadyBlocked ? Html::hidden( 'wpChangeBlock', 1 ) : "" ) .
-                       Xml::closeElement( 'fieldset' ) .
-                       Xml::closeElement( 'form' )
-               );
-
-               $wgOut->addHTML( $this->getConvenienceLinks() );
-
-               if( is_object( $user ) ) {
-                       $this->showLogFragment( $wgOut, $user->getUserPage() );
-               } elseif( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $this->BlockAddress ) ) {
-                       $this->showLogFragment( $wgOut, Title::makeTitle( NS_USER, $this->BlockAddress ) );
-               } elseif( preg_match( '/^\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}/', $this->BlockAddress ) ) {
-                       $this->showLogFragment( $wgOut, Title::makeTitle( NS_USER, $this->BlockAddress ) );
-               }
-       }
-
-       /**
-        * Can we do an email block?
-        * @param $user User: the sysop wanting to make a block
-        * @return Boolean
-        */
-       public static function canBlockEmail( $user ) {
-               global $wgEnableUserEmail, $wgSysopEmailBans;
-               return ( $wgEnableUserEmail && $wgSysopEmailBans && $user->isAllowed( 'blockemail' ) );
-       }
-       
-       /**
-        * bug 15810: blocked admins should not be able to block/unblock
-        * others, and probably shouldn't be able to unblock themselves
-        * either.
-        * @param $user User|Int|String
-        */
-       public static function checkUnblockSelf( $user ) {
-               global $wgUser;
-               if ( is_int( $user ) ) {
-                       $user = User::newFromId( $user );
-               } elseif ( is_string( $user ) ) {
-                       $user = User::newFromName( $user );
-               }
-               if( $user instanceof User && $user->getId() == $wgUser->getId() ) {
-                       # User is trying to unblock themselves
-                       if ( $wgUser->isAllowed( 'unblockself' ) ) {
-                               return true;
-                       } else {
-                               return 'ipbnounblockself';
-                       }
-               } else {
-                       # User is trying to block/unblock someone else
-                       return 'ipbblocked';
-               }
-       }
-
-       /**
-        * Backend block code.
-        * $userID and $expiry will be filled accordingly
-        * @return array(message key, arguments) on failure, empty array on success
-        */
-       function doBlock( &$userId = null, &$expiry = null ) {
-               global $wgUser, $wgBlockAllowsUTEdit, $wgBlockCIDRLimit;
-
-               $userId = 0;
-               # Expand valid IPv6 addresses, usernames are left as is
-               $this->BlockAddress = IP::sanitizeIP( $this->BlockAddress );
-               # isIPv4() and IPv6() are used for final validation
-               $rxIP4 = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
-               $rxIP6 = '\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}';
-               $rxIP = "($rxIP4|$rxIP6)";
-
-               # Check for invalid specifications
-               if( !preg_match( "/^$rxIP$/", $this->BlockAddress ) ) {
-                       $matches = array();
-                       if( preg_match( "/^($rxIP4)\\/(\\d{1,2})$/", $this->BlockAddress, $matches ) ) {
-                               # IPv4
-                               if( $wgBlockCIDRLimit['IPv4'] != 32 ){
-                                       if( !IP::isIPv4( $this->BlockAddress ) || $matches[2] > 32 ) {
-                                               return array( 'ip_range_invalid' );
-                                       } elseif ( $matches[2] < $wgBlockCIDRLimit['IPv4'] ) {
-                                               return array( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
-                                       }
-                                       $this->BlockAddress = Block::normaliseRange( $this->BlockAddress );
-                               } else {
-                                       # Range block illegal
-                                       return array( 'range_block_disabled' );
-                               }
-                       } elseif( preg_match( "/^($rxIP6)\\/(\\d{1,3})$/", $this->BlockAddress, $matches ) ) {
-                               # IPv6
-                               if( $wgBlockCIDRLimit['IPv6'] != 128 ) {
-                                       if( !IP::isIPv6( $this->BlockAddress ) || $matches[2] > 128 ) {
-                                               return array( 'ip_range_invalid' );
-                                       } elseif( $matches[2] < $wgBlockCIDRLimit['IPv6'] ) {
-                                               return array( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] );
-                                       }
-                                       $this->BlockAddress = Block::normaliseRange( $this->BlockAddress );
-                               } else {
-                                       # Range block illegal
-                                       return array('range_block_disabled');
-                               }
-                       } else {
-                               # Username block
-                               $user = User::newFromName( $this->BlockAddress );
-                               if( $user instanceof User && $user->getId() ) {
-                                       # Use canonical name
-                                       $userId = $user->getId();
-                                       $this->BlockAddress = $user->getName();
-                               } else {
-                                       return array( 'nosuchusershort', htmlspecialchars( $user ? $user->getName() : $this->BlockAddress ) );
-                               }
-                       }
-               }
-
-               if( $wgUser->isBlocked() && ( $wgUser->getId() !== $userId ) ) {
-                       return array( 'cant-block-while-blocked' );
-               }
-
-               $reasonstr = $this->BlockReasonList;
-               if( $reasonstr != 'other' && $this->BlockReason != '' ) {
-                       // Entry from drop down menu + additional comment
-                       $reasonstr .= wfMsgForContent( 'colon-separator' ) . $this->BlockReason;
-               } elseif( $reasonstr == 'other' ) {
-                       $reasonstr = $this->BlockReason;
-               }
-
-               $expirestr = $this->BlockExpiry;
-               if( $expirestr == 'other' )
-                       $expirestr = $this->BlockOther;
-
-               if( ( strlen( $expirestr ) == 0) || ( strlen( $expirestr ) > 50 ) ) {
-                       return array( 'ipb_expiry_invalid' );
-               }
-               
-               if( false === ( $expiry = Block::parseExpiryInput( $expirestr ) ) ) {
-                       // Bad expiry.
-                       return array( 'ipb_expiry_invalid' );
-               }
-
-               if( $this->BlockHideName ) {
-                       // Recheck params here...
-                       if( !$userId || !$wgUser->isAllowed('hideuser') ) {
-                               $this->BlockHideName = false; // IP users should not be hidden
-                       } elseif( $expiry !== 'infinity' ) {
-                               // Bad expiry.
-                               return array( 'ipb_expiry_temp' );
-                       } elseif( User::edits( $userId ) > self::HIDEUSER_CONTRIBLIMIT ) {
-                               // Typically, the user should have a handful of edits.
-                               // Disallow hiding users with many edits for performance.
-                               return array( 'ipb_hide_invalid' );
-                       }
-               }
-
-               # Create block object
-               # Note: for a user block, ipb_address is only for display purposes
-               $block = new Block( $this->BlockAddress, $userId, $wgUser->getId(),
-                       $reasonstr, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly,
-                       $this->BlockCreateAccount, $this->BlockEnableAutoblock, $this->BlockHideName,
-                       $this->BlockEmail,
-                       isset( $this->BlockAllowUsertalk ) ? $this->BlockAllowUsertalk : $wgBlockAllowsUTEdit
-               );
-
-               # Should this be privately logged?
-               $suppressLog = (bool)$this->BlockHideName;
-               if( wfRunHooks( 'BlockIp', array( &$block, &$wgUser ) ) ) {
-                       # Try to insert block. Is there a conflicting block?
-                       if( !$block->insert() ) {
-                               # Show form unless the user is already aware of this...
-                               if( !$this->BlockReblock ) {
-                                       return array( 'ipb_already_blocked' );
-                               # Otherwise, try to update the block...
-                               } else {
-                                       # This returns direct blocks before autoblocks/rangeblocks, since we should
-                                       # be sure the user is blocked by now it should work for our purposes
-                                       $currentBlock = Block::newFromDB( $this->BlockAddress, $userId );
-                                       if( $block->equals( $currentBlock ) ) {
-                                               return array( 'ipb_already_blocked' );
-                                       }
-                                       # If the name was hidden and the blocking user cannot hide
-                                       # names, then don't allow any block changes...
-                                       if( $currentBlock->mHideName && !$wgUser->isAllowed( 'hideuser' ) ) {
-                                               return array( 'cant-see-hidden-user' );
-                                       }
-                                       $currentBlock->delete();
-                                       $block->insert();
-                                       # If hiding/unhiding a name, this should go in the private logs
-                                       $suppressLog = $suppressLog || (bool)$currentBlock->mHideName;
-                                       $log_action = 'reblock';
-                                       # Unset _deleted fields if requested
-                                       if( $currentBlock->mHideName && !$this->BlockHideName ) {
-                                               RevisionDeleteUser::unsuppressUserName( $this->BlockAddress, $userId );
-                                       }
-                               }
-                       } else {
-                               $log_action = 'block';
-                       }
-                       wfRunHooks( 'BlockIpComplete', array( $block, $wgUser ) );
-
-                       # Set *_deleted fields if requested
-                       if( $this->BlockHideName ) {
-                               RevisionDeleteUser::suppressUserName( $this->BlockAddress, $userId );
-                       }
-
-                       # Only show watch link when this is no range block
-                       if( $this->BlockWatchUser && $block->mRangeStart == $block->mRangeEnd ) {
-                               $wgUser->addWatch( Title::makeTitle( NS_USER, $this->BlockAddress ) );
-                       }
-
-                       # Block constructor sanitizes certain block options on insert
-                       $this->BlockEmail = $block->mBlockEmail;
-                       $this->BlockEnableAutoblock = $block->mEnableAutoblock;
-
-                       # Prepare log parameters
-                       $logParams = array();
-                       $logParams[] = $expirestr;
-                       $logParams[] = $this->blockLogFlags();
-
-                       # Make log entry, if the name is hidden, put it in the oversight log
-                       $log_type = $suppressLog ? 'suppress' : 'block';
-                       $log = new LogPage( $log_type );
-                       $log->addEntry( $log_action, Title::makeTitle( NS_USER, $this->BlockAddress ),
-                               $reasonstr, $logParams );
-
-                       # Report to the user
-                       return array();
-               } else {
-                       return array( 'hookaborted' );
-               }
-       }
-
-       # @deprecated since 1.18
-       public static function suppressUserName( $name, $userId, $dbw = null ) {
-               return RevisionDeleteUser::suppressUserName( $name, $userId, $dbw );
-       }
-
-       # @deprecated since 1.18
-       public static function unsuppressUserName( $name, $userId, $dbw = null ) {
-               return RevisionDeleteUser::unsuppressUserName( $name, $userId, $dbw );
-       }
-
-       /**
-        * UI entry point for blocking
-        * Wraps around doBlock()
-        */
-       public function doSubmit() {
-               global $wgOut;
-               $retval = $this->doBlock();
-               if( empty( $retval ) ) {
-                       $titleObj = SpecialPage::getTitleFor( 'Blockip' );
-                       $wgOut->redirect( $titleObj->getFullURL( 'action=success&ip=' .
-                               urlencode( $this->BlockAddress ) ) );
-                       return;
-               }
-               $this->showForm( $retval );
-       }
-
-       public function showSuccess() {
-               global $wgOut;
-
-               $wgOut->setPageTitle( wfMsg( 'blockip-title' ) );
-               $wgOut->setSubtitle( wfMsg( 'blockipsuccesssub' ) );
-               $text = wfMsgExt( 'blockipsuccesstext', array( 'parse' ), $this->BlockAddress );
-               $wgOut->addHTML( $text );
-       }
-
-       private function showLogFragment( $out, $title ) {
-               global $wgUser;
-
-               // Used to support GENDER in 'blocklog-showlog' and 'blocklog-showsuppresslog'
-               $userBlocked = $title->getText();
-
-               LogEventsList::showLogExtract(
-                       $out,
-                       'block',
-                       $title->getPrefixedText(),
-                       '',
-                       array(
-                               'lim' => 10,
-                               'msgKey' => array(
-                                       'blocklog-showlog',
-                                       $userBlocked
-                               ),
-                               'showIfEmpty' => false
-                       )
-               );
-
-               // Add suppression block entries if allowed
-               if( $wgUser->isAllowed( 'suppressionlog' ) ) {
-                       LogEventsList::showLogExtract( $out, 'suppress', $title->getPrefixedText(), '',
-                               array(
-                                       'lim' => 10,
-                                       'conds' => array(
-                                               'log_action' => array(
-                                                       'block',
-                                                       'reblock',
-                                                       'unblock'
-                                               )
-                                       ),
-                                       'msgKey' => array(
-                                               'blocklog-showsuppresslog',
-                                               $userBlocked
-                                       ),
-                                       'showIfEmpty' => false
-                               )
-                       );
-               }
-       }
-
-       /**
-        * Return a comma-delimited list of "flags" to be passed to the log
-        * reader for this block, to provide more information in the logs
-        *
-        * @return array
-        */
-       private function blockLogFlags() {
-               global $wgBlockAllowsUTEdit;
-               $flags = array();
-               if( $this->BlockAnonOnly && IP::isIPAddress( $this->BlockAddress ) )
-                       // when blocking a user the option 'anononly' is not available/has no effect -> do not write this into log
-                       $flags[] = 'anononly';
-               if( $this->BlockCreateAccount )
-                       $flags[] = 'nocreate';
-               if( !$this->BlockEnableAutoblock && !IP::isIPAddress( $this->BlockAddress ) )
-                       // Same as anononly, this is not displayed when blocking an IP address
-                       $flags[] = 'noautoblock';
-               if( $this->BlockEmail )
-                       $flags[] = 'noemail';
-               if( !$this->BlockAllowUsertalk && $wgBlockAllowsUTEdit )
-                       $flags[] = 'nousertalk';
-               if( $this->BlockHideName )
-                       $flags[] = 'hiddenname';
-               return implode( ',', $flags );
-       }
-
-       /**
-        * Builds unblock and block list links
-        *
-        * @return string
-        */
-       private function getConvenienceLinks() {
-               global $wgUser, $wgLang;
-               $skin = $wgUser->getSkin();
-               if( $this->BlockAddress )
-                       $links[] = $this->getContribsLink( $skin );
-               $links[] = $this->getUnblockLink( $skin );
-               $links[] = $this->getBlockListLink( $skin );
-               if ( $wgUser->isAllowed( 'editinterface' ) ) {
-                       $title = Title::makeTitle( NS_MEDIAWIKI, 'Ipbreason-dropdown' );
-                       $links[] = $skin->link(
-                               $title,
-                               wfMsgHtml( 'ipb-edit-dropdown' ),
-                               array(),
-                               array( 'action' => 'edit' )
-                       );
-               }
-               return '<p class="mw-ipb-conveniencelinks">' . $wgLang->pipeList( $links ) . '</p>';
-       }
-
-       /**
-        * Build a convenient link to a user or IP's contribs
-        * form
-        *
-        * @param $skin Skin to use
-        * @return string
-        */
-       private function getContribsLink( $skin ) {
-               $contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->BlockAddress );
-               return $skin->link( $contribsPage, wfMsgExt( 'ipb-blocklist-contribs', 'escape', $this->BlockAddress ) );
-       }
-
-       /**
-        * Build a convenient link to unblock the given username or IP
-        * address, if available; otherwise link to a blank unblock
-        * form
-        *
-        * @param $skin Skin to use
-        * @return string
-        */
-       private function getUnblockLink( $skin ) {
-               $list = SpecialPage::getTitleFor( 'Ipblocklist' );
-               $query = array( 'action' => 'unblock' );
-
-               if( $this->BlockAddress ) {
-                       $addr = strtr( $this->BlockAddress, '_', ' ' );
-                       $message = wfMsg( 'ipb-unblock-addr', $addr );
-                       $query['ip'] = $this->BlockAddress;
-               } else {
-                       $message = wfMsg( 'ipb-unblock' );
-               }
-               return $skin->linkKnown(
-                       $list,
-                       htmlspecialchars( $message ),
-                       array(),
-                       $query
-               );
-       }
-
-       /**
-        * Build a convenience link to the block list
-        *
-        * @param $skin Skin to use
-        * @return string
-        */
-       private function getBlockListLink( $skin ) {
-               return $skin->linkKnown(
-                       SpecialPage::getTitleFor( 'Ipblocklist' ),
-                       wfMsg( 'ipb-blocklist' )
-               );
-       }
-
-       /**
-        * Block a list of selected users
-        *
-        * @param $users Array
-        * @param $reason String
-        * @param $tag String: replaces user pages
-        * @param $talkTag String: replaces user talk pages
-        * @return Array: list of html-safe usernames
-        */
-       public static function doMassUserBlock( $users, $reason = '', $tag = '', $talkTag = '' ) {
-               global $wgUser;
-               $counter = $blockSize = 0;
-               $safeUsers = array();
-               $log = new LogPage( 'block' );
-               foreach( $users as $name ) {
-                       # Enforce limits
-                       $counter++;
-                       $blockSize++;
-                       # Lets not go *too* fast
-                       if( $blockSize >= 20 ) {
-                               $blockSize = 0;
-                               wfWaitForSlaves( 5 );
-                       }
-                       $u = User::newFromName( $name, false );
-                       // If user doesn't exist, it ought to be an IP then
-                       if( is_null( $u ) || ( !$u->getId() && !IP::isIPAddress( $u->getName() ) ) ) {
-                               continue;
-                       }
-                       $userTitle = $u->getUserPage();
-                       $userTalkTitle = $u->getTalkPage();
-                       $userpage = new Article( $userTitle );
-                       $usertalk = new Article( $userTalkTitle );
-                       $safeUsers[] = '[[' . $userTitle->getPrefixedText() . '|' . $userTitle->getText() . ']]';
-                       $expirestr = $u->getId() ? 'indefinite' : '1 week';
-                       $expiry = Block::parseExpiryInput( $expirestr );
-                       $anonOnly = IP::isIPAddress( $u->getName() ) ? 1 : 0;
-                       // Create the block
-                       $block = new Block( $u->getName(), // victim
-                               $u->getId(), // uid
-                               $wgUser->getId(), // blocker
-                               $reason, // comment
-                               wfTimestampNow(), // block time
-                               0, // auto ?
-                               $expiry, // duration
-                               $anonOnly, // anononly?
-                               1, // block account creation?
-                               1, // autoblocking?
-                               0, // suppress name?
-                               0 // block from sending email?
-                       );
-                       $oldblock = Block::newFromDB( $u->getName(), $u->getId() );
-                       if( !$oldblock ) {
-                               $block->insert();
-                               # Prepare log parameters
-                               $logParams = array();
-                               $logParams[] = $expirestr;
-                               if( $anonOnly ) {
-                                       $logParams[] = 'anononly';
-                               }
-                               $logParams[] = 'nocreate';
-                               # Add log entry
-                               $log->addEntry( 'block', $userTitle, $reason, $logParams );
-                       }
-                       # Tag userpage! (check length to avoid mistakes)
-                       if( strlen( $tag ) > 2 ) {
-                               $userpage->doEdit( $tag, $reason, EDIT_MINOR );
-                       }
-                       if( strlen( $talkTag ) > 2 ) {
-                               $usertalk->doEdit( $talkTag, $reason, EDIT_MINOR );
-                       }
-               }
-               return $safeUsers;
-       }
-}
index 764cddc..c71a41d 100644 (file)
@@ -79,7 +79,7 @@ class IPUnblockForm extends SpecialPage {
                                } else {
                                        $user = User::newFromName( $ip );
                                }
-                               $status = IPBlockForm::checkUnblockSelf( $user );
+                               $status = SpecialBlock::checkUnblockSelf( $user );
                                if ( $status !== true ) {
                                        throw new ErrorPageError( 'badaccess', $status );
                                }
index 6338bab..2bb1e4e 100644 (file)
@@ -438,7 +438,7 @@ $specialPageAliases = array(
        'Version'                   => array( 'Version' ),
        'Allmessages'               => array( 'AllMessages' ),
        'Log'                       => array( 'Log', 'Logs' ),
-       'Blockip'                   => array( 'Block', 'BlockIP', 'BlockUser' ),
+       'Block'                     => array( 'Block', 'BlockIP', 'BlockUser' ),
        'Undelete'                  => array( 'Undelete' ),
        'Import'                    => array( 'Import' ),
        'Lockdb'                    => array( 'LockDB' ),
@@ -3039,18 +3039,18 @@ Fill in a specific reason below (for example, citing particular pages that were
 ** Intimidating behaviour/harassment
 ** Abusing multiple accounts
 ** Unacceptable username',
-'ipbanononly'                     => 'Block anonymous users only',
 'ipbcreateaccount'                => 'Prevent account creation',
 'ipbemailban'                     => 'Prevent user from sending e-mail',
 'ipbenableautoblock'              => 'Automatically block the last IP address used by this user, and any subsequent IP addresses they try to edit from',
 'ipbsubmit'                       => 'Block this user',
 'ipbother'                        => 'Other time:',
-'ipboptions'                      => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
+'ipboptions'                      => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,indefinite:infinite',
 'ipbotheroption'                  => 'other',
 'ipbotherreason'                  => 'Other/additional reason:',
 'ipbhidename'                     => 'Hide username from edits and lists',
 'ipbwatchuser'                    => "Watch this user's user and talk pages",
-'ipballowusertalk'                => 'Allow this user to edit own talk page while blocked',
+'ipb-disableusertalk'             => 'Prevent this user from editing their own talk page while blocked',
+'ipb-hardblock'                   => 'Prevent logged-in users from editing from this IP address',
 'ipb-change-block'                => 'Re-block the user with these settings',
 'badipaddress'                    => 'Invalid IP address',
 'blockipsuccesssub'               => 'Block succeeded',
index 2a8cdfb..5ecf56a 100644 (file)
@@ -2054,7 +2054,7 @@ $wgMessageStructure = array(
                'ipbreason',
                'ipbreasonotherlist',
                'ipbreason-dropdown',
-               'ipbanononly',
+               'ipb-hardblock',
                'ipbcreateaccount',
                'ipbemailban',
                'ipbenableautoblock',
@@ -2065,7 +2065,7 @@ $wgMessageStructure = array(
                'ipbotherreason',
                'ipbhidename',
                'ipbwatchuser',
-               'ipballowusertalk',
+               'ipb-disableusertalk',
                'ipb-change-block',
                'badipaddress',
                'blockipsuccesssub',
index d7ed89a..08768a7 100644 (file)
@@ -3,9 +3,11 @@
 jQuery( function( $ ) {
 
        var     DO_INSTANT = true,
-               $blockTarget = $( '#mw-bi-target' ),    $anonOnlyRow = $( '#wpAnonOnlyRow' ),
-               $enableAutoblockRow = $( '#wpEnableAutoblockRow' ),
-               $hideUser = $( '#wpEnableHideUser' ),   $watchUser = $( '#wpEnableWatchUser' );
+               $blockTarget = $( '#mw-bi-target' ),
+               $anonOnlyRow = $( '#mw-input-wpHardblock' ).closest( 'tr' ),
+               $enableAutoblockRow = $( '#mw-input-wpAutoBlock' ).closest( 'tr' ),
+               $hideUser = $( '#mw-input-wpHideUser' ).closest( 'tr' ),
+               $watchUser = $( '#mw-input-wpWatch' ).closest( 'tr' );
 
        var updateBlockOptions = function( instant ) {
                if ( !$blockTarget.length ) {