MediaWiki  REL1_24
SpecialBlock.php
Go to the documentation of this file.
00001 <?php
00030 class SpecialBlock extends FormSpecialPage {
00033     protected $target;
00034 
00036     protected $type;
00037 
00039     protected $previousTarget;
00040 
00042     protected $requestedHideUser;
00043 
00045     protected $alreadyBlocked;
00046 
00048     protected $preErrors = array();
00049 
00050     public function __construct() {
00051         parent::__construct( 'Block', 'block' );
00052     }
00053 
00060     protected function checkExecutePermissions( User $user ) {
00061         parent::checkExecutePermissions( $user );
00062 
00063         # bug 15810: blocked admins should have limited access here
00064         $status = self::checkUnblockSelf( $this->target, $user );
00065         if ( $status !== true ) {
00066             throw new ErrorPageError( 'badaccess', $status );
00067         }
00068     }
00069 
00075     protected function setParameter( $par ) {
00076         # Extract variables from the request.  Try not to get into a situation where we
00077         # need to extract *every* variable from the form just for processing here, but
00078         # there are legitimate uses for some variables
00079         $request = $this->getRequest();
00080         list( $this->target, $this->type ) = self::getTargetAndType( $par, $request );
00081         if ( $this->target instanceof User ) {
00082             # Set the 'relevant user' in the skin, so it displays links like Contributions,
00083             # User logs, UserRights, etc.
00084             $this->getSkin()->setRelevantUser( $this->target );
00085         }
00086 
00087         list( $this->previousTarget, /*...*/ ) =
00088             Block::parseTarget( $request->getVal( 'wpPreviousTarget' ) );
00089         $this->requestedHideUser = $request->getBool( 'wpHideUser' );
00090     }
00091 
00097     protected function alterForm( HTMLForm $form ) {
00098         $form->setWrapperLegendMsg( 'blockip-legend' );
00099         $form->setHeaderText( '' );
00100         $form->setSubmitCallback( array( __CLASS__, 'processUIForm' ) );
00101 
00102         $msg = $this->alreadyBlocked ? 'ipb-change-block' : 'ipbsubmit';
00103         $form->setSubmitTextMsg( $msg );
00104 
00105         # Don't need to do anything if the form has been posted
00106         if ( !$this->getRequest()->wasPosted() && $this->preErrors ) {
00107             $s = HTMLForm::formatErrors( $this->preErrors );
00108             if ( $s ) {
00109                 $form->addHeaderText( Html::rawElement(
00110                     'div',
00111                     array( 'class' => 'error' ),
00112                     $s
00113                 ) );
00114             }
00115         }
00116     }
00117 
00122     protected function getFormFields() {
00123         global $wgBlockAllowsUTEdit;
00124 
00125         $user = $this->getUser();
00126 
00127         $suggestedDurations = self::getSuggestedDurations();
00128 
00129         $a = array(
00130             'Target' => array(
00131                 'type' => 'text',
00132                 'label-message' => 'ipaddressorusername',
00133                 'id' => 'mw-bi-target',
00134                 'size' => '45',
00135                 'autofocus' => true,
00136                 'required' => true,
00137                 'validation-callback' => array( __CLASS__, 'validateTargetField' ),
00138             ),
00139             'Expiry' => array(
00140                 'type' => !count( $suggestedDurations ) ? 'text' : 'selectorother',
00141                 'label-message' => 'ipbexpiry',
00142                 'required' => true,
00143                 'options' => $suggestedDurations,
00144                 'other' => $this->msg( 'ipbother' )->text(),
00145                 'default' => $this->msg( 'ipb-default-expiry' )->inContentLanguage()->text(),
00146             ),
00147             'Reason' => array(
00148                 'type' => 'selectandother',
00149                 'label-message' => 'ipbreason',
00150                 'options-message' => 'ipbreason-dropdown',
00151             ),
00152             'CreateAccount' => array(
00153                 'type' => 'check',
00154                 'label-message' => 'ipbcreateaccount',
00155                 'default' => true,
00156             ),
00157         );
00158 
00159         if ( self::canBlockEmail( $user ) ) {
00160             $a['DisableEmail'] = array(
00161                 'type' => 'check',
00162                 'label-message' => 'ipbemailban',
00163             );
00164         }
00165 
00166         if ( $wgBlockAllowsUTEdit ) {
00167             $a['DisableUTEdit'] = array(
00168                 'type' => 'check',
00169                 'label-message' => 'ipb-disableusertalk',
00170                 'default' => false,
00171             );
00172         }
00173 
00174         $a['AutoBlock'] = array(
00175             'type' => 'check',
00176             'label-message' => 'ipbenableautoblock',
00177             'default' => true,
00178         );
00179 
00180         # Allow some users to hide name from block log, blocklist and listusers
00181         if ( $user->isAllowed( 'hideuser' ) ) {
00182             $a['HideUser'] = array(
00183                 'type' => 'check',
00184                 'label-message' => 'ipbhidename',
00185                 'cssclass' => 'mw-block-hideuser',
00186             );
00187         }
00188 
00189         # Watchlist their user page? (Only if user is logged in)
00190         if ( $user->isLoggedIn() ) {
00191             $a['Watch'] = array(
00192                 'type' => 'check',
00193                 'label-message' => 'ipbwatchuser',
00194             );
00195         }
00196 
00197         $a['HardBlock'] = array(
00198             'type' => 'check',
00199             'label-message' => 'ipb-hardblock',
00200             'default' => false,
00201         );
00202 
00203         # This is basically a copy of the Target field, but the user can't change it, so we
00204         # can see if the warnings we maybe showed to the user before still apply
00205         $a['PreviousTarget'] = array(
00206             'type' => 'hidden',
00207             'default' => false,
00208         );
00209 
00210         # We'll turn this into a checkbox if we need to
00211         $a['Confirm'] = array(
00212             'type' => 'hidden',
00213             'default' => '',
00214             'label-message' => 'ipb-confirm',
00215         );
00216 
00217         $this->maybeAlterFormDefaults( $a );
00218 
00219         // Allow extensions to add more fields
00220         wfRunHooks( 'SpecialBlockModifyFormFields', array( $this, &$a ) );
00221 
00222         return $a;
00223     }
00224 
00232     protected function maybeAlterFormDefaults( &$fields ) {
00233         # This will be overwritten by request data
00234         $fields['Target']['default'] = (string)$this->target;
00235 
00236         # This won't be
00237         $fields['PreviousTarget']['default'] = (string)$this->target;
00238 
00239         $block = Block::newFromTarget( $this->target );
00240 
00241         if ( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
00242             && ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
00243                 || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
00244         ) {
00245             $fields['HardBlock']['default'] = $block->isHardblock();
00246             $fields['CreateAccount']['default'] = $block->prevents( 'createaccount' );
00247             $fields['AutoBlock']['default'] = $block->isAutoblocking();
00248 
00249             if ( isset( $fields['DisableEmail'] ) ) {
00250                 $fields['DisableEmail']['default'] = $block->prevents( 'sendemail' );
00251             }
00252 
00253             if ( isset( $fields['HideUser'] ) ) {
00254                 $fields['HideUser']['default'] = $block->mHideName;
00255             }
00256 
00257             if ( isset( $fields['DisableUTEdit'] ) ) {
00258                 $fields['DisableUTEdit']['default'] = $block->prevents( 'editownusertalk' );
00259             }
00260 
00261             // If the username was hidden (ipb_deleted == 1), don't show the reason
00262             // unless this user also has rights to hideuser: Bug 35839
00263             if ( !$block->mHideName || $this->getUser()->isAllowed( 'hideuser' ) ) {
00264                 $fields['Reason']['default'] = $block->mReason;
00265             } else {
00266                 $fields['Reason']['default'] = '';
00267             }
00268 
00269             if ( $this->getRequest()->wasPosted() ) {
00270                 # Ok, so we got a POST submission asking us to reblock a user.  So show the
00271                 # confirm checkbox; the user will only see it if they haven't previously
00272                 $fields['Confirm']['type'] = 'check';
00273             } else {
00274                 # We got a target, but it wasn't a POST request, so the user must have gone
00275                 # to a link like [[Special:Block/User]].  We don't need to show the checkbox
00276                 # as long as they go ahead and block *that* user
00277                 $fields['Confirm']['default'] = 1;
00278             }
00279 
00280             if ( $block->mExpiry == 'infinity' ) {
00281                 $fields['Expiry']['default'] = 'infinite';
00282             } else {
00283                 $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->mExpiry );
00284             }
00285 
00286             $this->alreadyBlocked = true;
00287             $this->preErrors[] = array( 'ipb-needreblock', wfEscapeWikiText( (string)$block->getTarget() ) );
00288         }
00289 
00290         # We always need confirmation to do HideUser
00291         if ( $this->requestedHideUser ) {
00292             $fields['Confirm']['type'] = 'check';
00293             unset( $fields['Confirm']['default'] );
00294             $this->preErrors[] = array( 'ipb-confirmhideuser', 'ipb-confirmaction' );
00295         }
00296 
00297         # Or if the user is trying to block themselves
00298         if ( (string)$this->target === $this->getUser()->getName() ) {
00299             $fields['Confirm']['type'] = 'check';
00300             unset( $fields['Confirm']['default'] );
00301             $this->preErrors[] = array( 'ipb-blockingself', 'ipb-confirmaction' );
00302         }
00303     }
00304 
00309     protected function preText() {
00310         $this->getOutput()->addModules( 'mediawiki.special.block' );
00311 
00312         $text = $this->msg( 'blockiptext' )->parse();
00313 
00314         $otherBlockMessages = array();
00315         if ( $this->target !== null ) {
00316             # Get other blocks, i.e. from GlobalBlocking or TorBlock extension
00317             wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockMessages, $this->target ) );
00318 
00319             if ( count( $otherBlockMessages ) ) {
00320                 $s = Html::rawElement(
00321                     'h2',
00322                     array(),
00323                     $this->msg( 'ipb-otherblocks-header', count( $otherBlockMessages ) )->parse()
00324                 ) . "\n";
00325 
00326                 $list = '';
00327 
00328                 foreach ( $otherBlockMessages as $link ) {
00329                     $list .= Html::rawElement( 'li', array(), $link ) . "\n";
00330                 }
00331 
00332                 $s .= Html::rawElement(
00333                     'ul',
00334                     array( 'class' => 'mw-blockip-alreadyblocked' ),
00335                     $list
00336                 ) . "\n";
00337 
00338                 $text .= $s;
00339             }
00340         }
00341 
00342         return $text;
00343     }
00344 
00349     protected function postText() {
00350         $links = array();
00351 
00352         # Link to the user's contributions, if applicable
00353         if ( $this->target instanceof User ) {
00354             $contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->target->getName() );
00355             $links[] = Linker::link(
00356                 $contribsPage,
00357                 $this->msg( 'ipb-blocklist-contribs', $this->target->getName() )->escaped()
00358             );
00359         }
00360 
00361         # Link to unblock the specified user, or to a blank unblock form
00362         if ( $this->target instanceof User ) {
00363             $message = $this->msg(
00364                 'ipb-unblock-addr',
00365                 wfEscapeWikiText( $this->target->getName() )
00366             )->parse();
00367             $list = SpecialPage::getTitleFor( 'Unblock', $this->target->getName() );
00368         } else {
00369             $message = $this->msg( 'ipb-unblock' )->parse();
00370             $list = SpecialPage::getTitleFor( 'Unblock' );
00371         }
00372         $links[] = Linker::linkKnown( $list, $message, array() );
00373 
00374         # Link to the block list
00375         $links[] = Linker::linkKnown(
00376             SpecialPage::getTitleFor( 'BlockList' ),
00377             $this->msg( 'ipb-blocklist' )->escaped()
00378         );
00379 
00380         $user = $this->getUser();
00381 
00382         # Link to edit the block dropdown reasons, if applicable
00383         if ( $user->isAllowed( 'editinterface' ) ) {
00384             $links[] = Linker::link(
00385                 Title::makeTitle( NS_MEDIAWIKI, 'Ipbreason-dropdown' ),
00386                 $this->msg( 'ipb-edit-dropdown' )->escaped(),
00387                 array(),
00388                 array( 'action' => 'edit' )
00389             );
00390         }
00391 
00392         $text = Html::rawElement(
00393             'p',
00394             array( 'class' => 'mw-ipb-conveniencelinks' ),
00395             $this->getLanguage()->pipeList( $links )
00396         );
00397 
00398         $userTitle = self::getTargetUserTitle( $this->target );
00399         if ( $userTitle ) {
00400             # Get relevant extracts from the block and suppression logs, if possible
00401             $out = '';
00402 
00403             LogEventsList::showLogExtract(
00404                 $out,
00405                 'block',
00406                 $userTitle,
00407                 '',
00408                 array(
00409                     'lim' => 10,
00410                     'msgKey' => array( 'blocklog-showlog', $userTitle->getText() ),
00411                     'showIfEmpty' => false
00412                 )
00413             );
00414             $text .= $out;
00415 
00416             # Add suppression block entries if allowed
00417             if ( $user->isAllowed( 'suppressionlog' ) ) {
00418                 LogEventsList::showLogExtract(
00419                     $out,
00420                     'suppress',
00421                     $userTitle,
00422                     '',
00423                     array(
00424                         'lim' => 10,
00425                         'conds' => array( 'log_action' => array( 'block', 'reblock', 'unblock' ) ),
00426                         'msgKey' => array( 'blocklog-showsuppresslog', $userTitle->getText() ),
00427                         'showIfEmpty' => false
00428                     )
00429                 );
00430 
00431                 $text .= $out;
00432             }
00433         }
00434 
00435         return $text;
00436     }
00437 
00444     protected static function getTargetUserTitle( $target ) {
00445         if ( $target instanceof User ) {
00446             return $target->getUserPage();
00447         } elseif ( IP::isIPAddress( $target ) ) {
00448             return Title::makeTitleSafe( NS_USER, $target );
00449         }
00450 
00451         return null;
00452     }
00453 
00462     public static function getTargetAndType( $par, WebRequest $request = null ) {
00463         $i = 0;
00464         $target = null;
00465 
00466         while ( true ) {
00467             switch ( $i++ ) {
00468                 case 0:
00469                     # The HTMLForm will check wpTarget first and only if it doesn't get
00470                     # a value use the default, which will be generated from the options
00471                     # below; so this has to have a higher precedence here than $par, or
00472                     # we could end up with different values in $this->target and the HTMLForm!
00473                     if ( $request instanceof WebRequest ) {
00474                         $target = $request->getText( 'wpTarget', null );
00475                     }
00476                     break;
00477                 case 1:
00478                     $target = $par;
00479                     break;
00480                 case 2:
00481                     if ( $request instanceof WebRequest ) {
00482                         $target = $request->getText( 'ip', null );
00483                     }
00484                     break;
00485                 case 3:
00486                     # B/C @since 1.18
00487                     if ( $request instanceof WebRequest ) {
00488                         $target = $request->getText( 'wpBlockAddress', null );
00489                     }
00490                     break;
00491                 case 4:
00492                     break 2;
00493             }
00494 
00495             list( $target, $type ) = Block::parseTarget( $target );
00496 
00497             if ( $type !== null ) {
00498                 return array( $target, $type );
00499             }
00500         }
00501 
00502         return array( null, null );
00503     }
00504 
00513     public static function validateTargetField( $value, $alldata, $form ) {
00514         $status = self::validateTarget( $value, $form->getUser() );
00515         if ( !$status->isOK() ) {
00516             $errors = $status->getErrorsArray();
00517 
00518             return call_user_func_array( array( $form, 'msg' ), $errors[0] );
00519         } else {
00520             return true;
00521         }
00522     }
00523 
00532     public static function validateTarget( $value, User $user ) {
00533         global $wgBlockCIDRLimit;
00534 
00536         list( $target, $type ) = self::getTargetAndType( $value );
00537         $status = Status::newGood( $target );
00538 
00539         if ( $type == Block::TYPE_USER ) {
00540             if ( $target->isAnon() ) {
00541                 $status->fatal(
00542                     'nosuchusershort',
00543                     wfEscapeWikiText( $target->getName() )
00544                 );
00545             }
00546 
00547             $unblockStatus = self::checkUnblockSelf( $target, $user );
00548             if ( $unblockStatus !== true ) {
00549                 $status->fatal( 'badaccess', $unblockStatus );
00550             }
00551         } elseif ( $type == Block::TYPE_RANGE ) {
00552             list( $ip, $range ) = explode( '/', $target, 2 );
00553 
00554             if (
00555                 ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 ) ||
00556                 ( IP::isIPv6( $ip ) && $wgBlockCIDRLimit['IPv6'] == 128 )
00557             ) {
00558                 // Range block effectively disabled
00559                 $status->fatal( 'range_block_disabled' );
00560             }
00561 
00562             if (
00563                 ( IP::isIPv4( $ip ) && $range > 32 ) ||
00564                 ( IP::isIPv6( $ip ) && $range > 128 )
00565             ) {
00566                 // Dodgy range
00567                 $status->fatal( 'ip_range_invalid' );
00568             }
00569 
00570             if ( IP::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
00571                 $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
00572             }
00573 
00574             if ( IP::isIPv6( $ip ) && $range < $wgBlockCIDRLimit['IPv6'] ) {
00575                 $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] );
00576             }
00577         } elseif ( $type == Block::TYPE_IP ) {
00578             # All is well
00579         } else {
00580             $status->fatal( 'badipaddress' );
00581         }
00582 
00583         return $status;
00584     }
00585 
00592     public static function processUIForm( array $data, HTMLForm $form ) {
00593         return self::processForm( $data, $form->getContext() );
00594     }
00595 
00602     public static function processForm( array $data, IContextSource $context ) {
00603         global $wgBlockAllowsUTEdit, $wgHideUserContribLimit, $wgContLang;
00604 
00605         $performer = $context->getUser();
00606 
00607         // Handled by field validator callback
00608         // self::validateTargetField( $data['Target'] );
00609 
00610         # This might have been a hidden field or a checkbox, so interesting data
00611         # can come from it
00612         $data['Confirm'] = !in_array( $data['Confirm'], array( '', '0', null, false ), true );
00613 
00615         list( $target, $type ) = self::getTargetAndType( $data['Target'] );
00616         if ( $type == Block::TYPE_USER ) {
00617             $user = $target;
00618             $target = $user->getName();
00619             $userId = $user->getId();
00620 
00621             # Give admins a heads-up before they go and block themselves.  Much messier
00622             # to do this for IPs, but it's pretty unlikely they'd ever get the 'block'
00623             # permission anyway, although the code does allow for it.
00624             # Note: Important to use $target instead of $data['Target']
00625             # since both $data['PreviousTarget'] and $target are normalized
00626             # but $data['target'] gets overriden by (non-normalized) request variable
00627             # from previous request.
00628             if ( $target === $performer->getName() &&
00629                 ( $data['PreviousTarget'] !== $target || !$data['Confirm'] )
00630             ) {
00631                 return array( 'ipb-blockingself', 'ipb-confirmaction' );
00632             }
00633         } elseif ( $type == Block::TYPE_RANGE ) {
00634             $userId = 0;
00635         } elseif ( $type == Block::TYPE_IP ) {
00636             $target = $target->getName();
00637             $userId = 0;
00638         } else {
00639             # This should have been caught in the form field validation
00640             return array( 'badipaddress' );
00641         }
00642 
00643         if ( ( strlen( $data['Expiry'] ) == 0 ) || ( strlen( $data['Expiry'] ) > 50 )
00644             || !self::parseExpiryInput( $data['Expiry'] )
00645         ) {
00646             return array( 'ipb_expiry_invalid' );
00647         }
00648 
00649         if ( !isset( $data['DisableEmail'] ) ) {
00650             $data['DisableEmail'] = false;
00651         }
00652 
00653         # If the user has done the form 'properly', they won't even have been given the
00654         # option to suppress-block unless they have the 'hideuser' permission
00655         if ( !isset( $data['HideUser'] ) ) {
00656             $data['HideUser'] = false;
00657         }
00658 
00659         if ( $data['HideUser'] ) {
00660             if ( !$performer->isAllowed( 'hideuser' ) ) {
00661                 # this codepath is unreachable except by a malicious user spoofing forms,
00662                 # or by race conditions (user has oversight and sysop, loads block form,
00663                 # and is de-oversighted before submission); so need to fail completely
00664                 # rather than just silently disable hiding
00665                 return array( 'badaccess-group0' );
00666             }
00667 
00668             # Recheck params here...
00669             if ( $type != Block::TYPE_USER ) {
00670                 $data['HideUser'] = false; # IP users should not be hidden
00671             } elseif ( !in_array( $data['Expiry'], array( 'infinite', 'infinity', 'indefinite' ) ) ) {
00672                 # Bad expiry.
00673                 return array( 'ipb_expiry_temp' );
00674             } elseif ( $wgHideUserContribLimit !== false
00675                 && $user->getEditCount() > $wgHideUserContribLimit
00676             ) {
00677                 # Typically, the user should have a handful of edits.
00678                 # Disallow hiding users with many edits for performance.
00679                 return array( array( 'ipb_hide_invalid',
00680                     Message::numParam( $wgHideUserContribLimit ) ) );
00681             } elseif ( !$data['Confirm'] ) {
00682                 return array( 'ipb-confirmhideuser', 'ipb-confirmaction' );
00683             }
00684         }
00685 
00686         # Create block object.
00687         $block = new Block();
00688         $block->setTarget( $target );
00689         $block->setBlocker( $performer );
00690         # Truncate reason for whole multibyte characters
00691         $block->mReason = $wgContLang->truncate( $data['Reason'][0], 255 );
00692         $block->mExpiry = self::parseExpiryInput( $data['Expiry'] );
00693         $block->prevents( 'createaccount', $data['CreateAccount'] );
00694         $block->prevents( 'editownusertalk', ( !$wgBlockAllowsUTEdit || $data['DisableUTEdit'] ) );
00695         $block->prevents( 'sendemail', $data['DisableEmail'] );
00696         $block->isHardblock( $data['HardBlock'] );
00697         $block->isAutoblocking( $data['AutoBlock'] );
00698         $block->mHideName = $data['HideUser'];
00699 
00700         $reason = array( 'hookaborted' );
00701         if ( !wfRunHooks( 'BlockIp', array( &$block, &$performer, &$reason ) ) ) {
00702             return $reason;
00703         }
00704 
00705         # Try to insert block. Is there a conflicting block?
00706         $status = $block->insert();
00707         if ( !$status ) {
00708             # Indicates whether the user is confirming the block and is aware of
00709             # the conflict (did not change the block target in the meantime)
00710             $blockNotConfirmed = !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
00711                 && $data['PreviousTarget'] !== $target );
00712 
00713             # Special case for API - bug 32434
00714             $reblockNotAllowed = ( array_key_exists( 'Reblock', $data ) && !$data['Reblock'] );
00715 
00716             # Show form unless the user is already aware of this...
00717             if ( $blockNotConfirmed || $reblockNotAllowed ) {
00718                 return array( array( 'ipb_already_blocked', $block->getTarget() ) );
00719                 # Otherwise, try to update the block...
00720             } else {
00721                 # This returns direct blocks before autoblocks/rangeblocks, since we should
00722                 # be sure the user is blocked by now it should work for our purposes
00723                 $currentBlock = Block::newFromTarget( $target );
00724 
00725                 if ( $block->equals( $currentBlock ) ) {
00726                     return array( array( 'ipb_already_blocked', $block->getTarget() ) );
00727                 }
00728 
00729                 # If the name was hidden and the blocking user cannot hide
00730                 # names, then don't allow any block changes...
00731                 if ( $currentBlock->mHideName && !$performer->isAllowed( 'hideuser' ) ) {
00732                     return array( 'cant-see-hidden-user' );
00733                 }
00734 
00735                 $currentBlock->isHardblock( $block->isHardblock() );
00736                 $currentBlock->prevents( 'createaccount', $block->prevents( 'createaccount' ) );
00737                 $currentBlock->mExpiry = $block->mExpiry;
00738                 $currentBlock->isAutoblocking( $block->isAutoblocking() );
00739                 $currentBlock->mHideName = $block->mHideName;
00740                 $currentBlock->prevents( 'sendemail', $block->prevents( 'sendemail' ) );
00741                 $currentBlock->prevents( 'editownusertalk', $block->prevents( 'editownusertalk' ) );
00742                 $currentBlock->mReason = $block->mReason;
00743 
00744                 $status = $currentBlock->update();
00745 
00746                 $logaction = 'reblock';
00747 
00748                 # Unset _deleted fields if requested
00749                 if ( $currentBlock->mHideName && !$data['HideUser'] ) {
00750                     RevisionDeleteUser::unsuppressUserName( $target, $userId );
00751                 }
00752 
00753                 # If hiding/unhiding a name, this should go in the private logs
00754                 if ( (bool)$currentBlock->mHideName ) {
00755                     $data['HideUser'] = true;
00756                 }
00757             }
00758         } else {
00759             $logaction = 'block';
00760         }
00761 
00762         wfRunHooks( 'BlockIpComplete', array( $block, $performer ) );
00763 
00764         # Set *_deleted fields if requested
00765         if ( $data['HideUser'] ) {
00766             RevisionDeleteUser::suppressUserName( $target, $userId );
00767         }
00768 
00769         # Can't watch a rangeblock
00770         if ( $type != Block::TYPE_RANGE && $data['Watch'] ) {
00771             WatchAction::doWatch(
00772                 Title::makeTitle( NS_USER, $target ),
00773                 $performer,
00774                 WatchedItem::IGNORE_USER_RIGHTS
00775             );
00776         }
00777 
00778         # Block constructor sanitizes certain block options on insert
00779         $data['BlockEmail'] = $block->prevents( 'sendemail' );
00780         $data['AutoBlock'] = $block->isAutoblocking();
00781 
00782         # Prepare log parameters
00783         $logParams = array();
00784         $logParams[] = $data['Expiry'];
00785         $logParams[] = self::blockLogFlags( $data, $type );
00786 
00787         # Make log entry, if the name is hidden, put it in the oversight log
00788         $log_type = $data['HideUser'] ? 'suppress' : 'block';
00789         $log = new LogPage( $log_type );
00790         $log_id = $log->addEntry(
00791             $logaction,
00792             Title::makeTitle( NS_USER, $target ),
00793             $data['Reason'][0],
00794             $logParams,
00795             $performer
00796         );
00797         # Relate log ID to block IDs (bug 25763)
00798         $blockIds = array_merge( array( $status['id'] ), $status['autoIds'] );
00799         $log->addRelations( 'ipb_id', $blockIds, $log_id );
00800 
00801         # Report to the user
00802         return true;
00803     }
00804 
00813     public static function getSuggestedDurations( $lang = null ) {
00814         $a = array();
00815         $msg = $lang === null
00816             ? wfMessage( 'ipboptions' )->inContentLanguage()->text()
00817             : wfMessage( 'ipboptions' )->inLanguage( $lang )->text();
00818 
00819         if ( $msg == '-' ) {
00820             return array();
00821         }
00822 
00823         foreach ( explode( ',', $msg ) as $option ) {
00824             if ( strpos( $option, ':' ) === false ) {
00825                 $option = "$option:$option";
00826             }
00827 
00828             list( $show, $value ) = explode( ':', $option );
00829             $a[htmlspecialchars( $show )] = htmlspecialchars( $value );
00830         }
00831 
00832         return $a;
00833     }
00834 
00841     public static function parseExpiryInput( $expiry ) {
00842         static $infinity;
00843         if ( $infinity == null ) {
00844             $infinity = wfGetDB( DB_SLAVE )->getInfinity();
00845         }
00846 
00847         if ( $expiry == 'infinite' || $expiry == 'indefinite' ) {
00848             $expiry = $infinity;
00849         } else {
00850             $expiry = strtotime( $expiry );
00851 
00852             if ( $expiry < 0 || $expiry === false ) {
00853                 return false;
00854             }
00855 
00856             $expiry = wfTimestamp( TS_MW, $expiry );
00857         }
00858 
00859         return $expiry;
00860     }
00861 
00867     public static function canBlockEmail( $user ) {
00868         global $wgEnableUserEmail, $wgSysopEmailBans;
00869 
00870         return ( $wgEnableUserEmail && $wgSysopEmailBans && $user->isAllowed( 'blockemail' ) );
00871     }
00872 
00881     public static function checkUnblockSelf( $user, User $performer ) {
00882         if ( is_int( $user ) ) {
00883             $user = User::newFromId( $user );
00884         } elseif ( is_string( $user ) ) {
00885             $user = User::newFromName( $user );
00886         }
00887 
00888         if ( $performer->isBlocked() ) {
00889             if ( $user instanceof User && $user->getId() == $performer->getId() ) {
00890                 # User is trying to unblock themselves
00891                 if ( $performer->isAllowed( 'unblockself' ) ) {
00892                     return true;
00893                     # User blocked themselves and is now trying to reverse it
00894                 } elseif ( $performer->blockedBy() === $performer->getName() ) {
00895                     return true;
00896                 } else {
00897                     return 'ipbnounblockself';
00898                 }
00899             } else {
00900                 # User is trying to block/unblock someone else
00901                 return 'ipbblocked';
00902             }
00903         } else {
00904             return true;
00905         }
00906     }
00907 
00915     protected static function blockLogFlags( array $data, $type ) {
00916         global $wgBlockAllowsUTEdit;
00917         $flags = array();
00918 
00919         # when blocking a user the option 'anononly' is not available/has no effect
00920         # -> do not write this into log
00921         if ( !$data['HardBlock'] && $type != Block::TYPE_USER ) {
00922             // For grepping: message block-log-flags-anononly
00923             $flags[] = 'anononly';
00924         }
00925 
00926         if ( $data['CreateAccount'] ) {
00927             // For grepping: message block-log-flags-nocreate
00928             $flags[] = 'nocreate';
00929         }
00930 
00931         # Same as anononly, this is not displayed when blocking an IP address
00932         if ( !$data['AutoBlock'] && $type == Block::TYPE_USER ) {
00933             // For grepping: message block-log-flags-noautoblock
00934             $flags[] = 'noautoblock';
00935         }
00936 
00937         if ( $data['DisableEmail'] ) {
00938             // For grepping: message block-log-flags-noemail
00939             $flags[] = 'noemail';
00940         }
00941 
00942         if ( $wgBlockAllowsUTEdit && $data['DisableUTEdit'] ) {
00943             // For grepping: message block-log-flags-nousertalk
00944             $flags[] = 'nousertalk';
00945         }
00946 
00947         if ( $data['HideUser'] ) {
00948             // For grepping: message block-log-flags-hiddenname
00949             $flags[] = 'hiddenname';
00950         }
00951 
00952         return implode( ',', $flags );
00953     }
00954 
00960     public function onSubmit( array $data ) {
00961         // This isn't used since we need that HTMLForm that's passed in the
00962         // second parameter. See alterForm for the real function
00963     }
00964 
00969     public function onSuccess() {
00970         $out = $this->getOutput();
00971         $out->setPageTitle( $this->msg( 'blockipsuccesssub' ) );
00972         $out->addWikiMsg( 'blockipsuccesstext', wfEscapeWikiText( $this->target ) );
00973     }
00974 
00975     protected function getGroupName() {
00976         return 'users';
00977     }
00978 }