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