MediaWiki  master
SpecialBlock.php
Go to the documentation of this file.
1 <?php
30 use Wikimedia\IPUtils;
31 
43 
47  protected $target;
48 
50  protected $type;
51 
53  protected $previousTarget;
54 
56  protected $requestedHideUser;
57 
59  protected $alreadyBlocked;
60 
62  protected $preErrors = [];
63 
65  parent::__construct( 'Block', 'block' );
66 
67  $this->permissionManager = $permissionManager;
68  }
69 
70  public function doesWrites() {
71  return true;
72  }
73 
80  protected function checkExecutePermissions( User $user ) {
81  parent::checkExecutePermissions( $user );
82  # T17810: blocked admins should have limited access here
83  $status = self::checkUnblockSelf( $this->target, $user );
84  if ( $status !== true ) {
85  throw new ErrorPageError( 'badaccess', $status );
86  }
87  }
88 
94  public function requiresUnblock() {
95  return false;
96  }
97 
103  protected function setParameter( $par ) {
104  # Extract variables from the request. Try not to get into a situation where we
105  # need to extract *every* variable from the form just for processing here, but
106  # there are legitimate uses for some variables
107  $request = $this->getRequest();
108  list( $this->target, $this->type ) = self::getTargetAndType( $par, $request );
109  if ( $this->target instanceof User ) {
110  # Set the 'relevant user' in the skin, so it displays links like Contributions,
111  # User logs, UserRights, etc.
112  $this->getSkin()->setRelevantUser( $this->target );
113  }
114 
115  list( $this->previousTarget, /*...*/ ) =
116  DatabaseBlock::parseTarget( $request->getVal( 'wpPreviousTarget' ) );
117  $this->requestedHideUser = $request->getBool( 'wpHideUser' );
118  }
119 
125  protected function alterForm( HTMLForm $form ) {
126  $form->setHeaderText( '' );
127  $form->setSubmitDestructive();
128 
129  $msg = $this->alreadyBlocked ? 'ipb-change-block' : 'ipbsubmit';
130  $form->setSubmitTextMsg( $msg );
131 
132  $this->addHelpLink( 'Help:Blocking users' );
133 
134  # Don't need to do anything if the form has been posted
135  if ( !$this->getRequest()->wasPosted() && $this->preErrors ) {
136  $s = $form->formatErrors( $this->preErrors );
137  if ( $s ) {
139  'div',
140  [ 'class' => 'error' ],
141  $s
142  ) );
143  }
144  }
145  }
146 
147  protected function getDisplayFormat() {
148  return 'ooui';
149  }
150 
155  protected function getFormFields() {
156  $conf = $this->getConfig();
157  $blockAllowsUTEdit = $conf->get( 'BlockAllowsUTEdit' );
158 
159  $this->getOutput()->enableOOUI();
160 
161  $user = $this->getUser();
162 
163  $suggestedDurations = self::getSuggestedDurations();
164 
165  $a = [];
166 
167  $a['Target'] = [
168  'type' => 'user',
169  'ipallowed' => true,
170  'iprange' => true,
171  'id' => 'mw-bi-target',
172  'size' => '45',
173  'autofocus' => true,
174  'required' => true,
175  'validation-callback' => [ __CLASS__, 'validateTargetField' ],
176  'section' => 'target',
177  ];
178 
179  $a['Editing'] = [
180  'type' => 'check',
181  'label-message' => 'block-prevent-edit',
182  'default' => true,
183  'section' => 'actions',
184  ];
185 
186  $a['EditingRestriction'] = [
187  'type' => 'radio',
188  'cssclass' => 'mw-block-editing-restriction',
189  'default' => 'sitewide',
190  'options' => [
191  $this->msg( 'ipb-sitewide' )->escaped() .
192  new \OOUI\LabelWidget( [
193  'classes' => [ 'oo-ui-inline-help' ],
194  'label' => $this->msg( 'ipb-sitewide-help' )->text(),
195  ] ) => 'sitewide',
196  $this->msg( 'ipb-partial' )->escaped() .
197  new \OOUI\LabelWidget( [
198  'classes' => [ 'oo-ui-inline-help' ],
199  'label' => $this->msg( 'ipb-partial-help' )->text(),
200  ] ) => 'partial',
201  ],
202  'section' => 'actions',
203  ];
204 
205  $a['PageRestrictions'] = [
206  'type' => 'titlesmultiselect',
207  'label' => $this->msg( 'ipb-pages-label' )->text(),
208  'exists' => true,
209  'max' => 10,
210  'cssclass' => 'mw-block-restriction',
211  'showMissing' => false,
212  'excludeDynamicNamespaces' => true,
213  'input' => [
214  'autocomplete' => false
215  ],
216  'section' => 'actions',
217  ];
218 
219  $a['NamespaceRestrictions'] = [
220  'type' => 'namespacesmultiselect',
221  'label' => $this->msg( 'ipb-namespaces-label' )->text(),
222  'exists' => true,
223  'cssclass' => 'mw-block-restriction',
224  'input' => [
225  'autocomplete' => false
226  ],
227  'section' => 'actions',
228  ];
229 
230  $a['CreateAccount'] = [
231  'type' => 'check',
232  'label-message' => 'ipbcreateaccount',
233  'default' => true,
234  'section' => 'actions',
235  ];
236 
237  if ( self::canBlockEmail( $user ) ) {
238  $a['DisableEmail'] = [
239  'type' => 'check',
240  'label-message' => 'ipbemailban',
241  'section' => 'actions',
242  ];
243  }
244 
245  if ( $blockAllowsUTEdit ) {
246  $a['DisableUTEdit'] = [
247  'type' => 'check',
248  'label-message' => 'ipb-disableusertalk',
249  'default' => false,
250  'section' => 'actions',
251  ];
252  }
253 
254  $defaultExpiry = $this->msg( 'ipb-default-expiry' )->inContentLanguage();
255  if ( $this->type === DatabaseBlock::TYPE_RANGE || $this->type === DatabaseBlock::TYPE_IP ) {
256  $defaultExpiryIP = $this->msg( 'ipb-default-expiry-ip' )->inContentLanguage();
257  if ( !$defaultExpiryIP->isDisabled() ) {
258  $defaultExpiry = $defaultExpiryIP;
259  }
260  }
261 
262  $a['Expiry'] = [
263  'type' => 'expiry',
264  'required' => true,
265  'options' => $suggestedDurations,
266  'default' => $defaultExpiry->text(),
267  'section' => 'expiry',
268  ];
269 
270  $a['Reason'] = [
271  'type' => 'selectandother',
272  // HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
273  // (e.g. emojis) count for two each. This limit is overridden in JS to instead count
274  // Unicode codepoints.
276  'maxlength-unit' => 'codepoints',
277  'options-message' => 'ipbreason-dropdown',
278  'section' => 'reason',
279  ];
280 
281  $a['AutoBlock'] = [
282  'type' => 'check',
283  'label-message' => 'ipbenableautoblock',
284  'default' => true,
285  'section' => 'options',
286  ];
287 
288  # Allow some users to hide name from block log, blocklist and listusers
289  if ( $this->permissionManager->userHasRight( $user, 'hideuser' ) ) {
290  $a['HideUser'] = [
291  'type' => 'check',
292  'label-message' => 'ipbhidename',
293  'cssclass' => 'mw-block-hideuser',
294  'section' => 'options',
295  ];
296  }
297 
298  # Watchlist their user page? (Only if user is logged in)
299  if ( $user->isLoggedIn() ) {
300  $a['Watch'] = [
301  'type' => 'check',
302  'label-message' => 'ipbwatchuser',
303  'section' => 'options',
304  ];
305  }
306 
307  $a['HardBlock'] = [
308  'type' => 'check',
309  'label-message' => 'ipb-hardblock',
310  'default' => false,
311  'section' => 'options',
312  ];
313 
314  # This is basically a copy of the Target field, but the user can't change it, so we
315  # can see if the warnings we maybe showed to the user before still apply
316  $a['PreviousTarget'] = [
317  'type' => 'hidden',
318  'default' => false,
319  ];
320 
321  # We'll turn this into a checkbox if we need to
322  $a['Confirm'] = [
323  'type' => 'hidden',
324  'default' => '',
325  'label-message' => 'ipb-confirm',
326  'cssclass' => 'mw-block-confirm',
327  ];
328 
329  $this->maybeAlterFormDefaults( $a );
330 
331  // Allow extensions to add more fields
332  $this->getHookRunner()->onSpecialBlockModifyFormFields( $this, $a );
333 
334  return $a;
335  }
336 
342  protected function maybeAlterFormDefaults( &$fields ) {
343  # This will be overwritten by request data
344  $fields['Target']['default'] = (string)$this->target;
345 
346  if ( $this->target ) {
347  $status = self::validateTarget( $this->target, $this->getUser() );
348  if ( !$status->isOK() ) {
349  $errors = $status->getErrorsArray();
350  $this->preErrors = array_merge( $this->preErrors, $errors );
351  }
352  }
353 
354  # This won't be
355  $fields['PreviousTarget']['default'] = (string)$this->target;
356 
357  $block = DatabaseBlock::newFromTarget( $this->target );
358 
359  // Populate fields if there is a block that is not an autoblock; if it is a range
360  // block, only populate the fields if the range is the same as $this->target
361  if ( $block instanceof DatabaseBlock && $block->getType() !== DatabaseBlock::TYPE_AUTO
362  && ( $this->type != DatabaseBlock::TYPE_RANGE
363  || $block->getTarget() == $this->target )
364  ) {
365  $fields['HardBlock']['default'] = $block->isHardblock();
366  $fields['CreateAccount']['default'] = $block->isCreateAccountBlocked();
367  $fields['AutoBlock']['default'] = $block->isAutoblocking();
368 
369  if ( isset( $fields['DisableEmail'] ) ) {
370  $fields['DisableEmail']['default'] = $block->isEmailBlocked();
371  }
372 
373  if ( isset( $fields['HideUser'] ) ) {
374  $fields['HideUser']['default'] = $block->getHideName();
375  }
376 
377  if ( isset( $fields['DisableUTEdit'] ) ) {
378  $fields['DisableUTEdit']['default'] = !$block->isUsertalkEditAllowed();
379  }
380 
381  // If the username was hidden (ipb_deleted == 1), don't show the reason
382  // unless this user also has rights to hideuser: T37839
383  if ( !$block->getHideName() || $this->permissionManager
384  ->userHasRight( $this->getUser(), 'hideuser' )
385  ) {
386  $fields['Reason']['default'] = $block->getReasonComment()->text;
387  } else {
388  $fields['Reason']['default'] = '';
389  }
390 
391  if ( $this->getRequest()->wasPosted() ) {
392  # Ok, so we got a POST submission asking us to reblock a user. So show the
393  # confirm checkbox; the user will only see it if they haven't previously
394  $fields['Confirm']['type'] = 'check';
395  } else {
396  # We got a target, but it wasn't a POST request, so the user must have gone
397  # to a link like [[Special:Block/User]]. We don't need to show the checkbox
398  # as long as they go ahead and block *that* user
399  $fields['Confirm']['default'] = 1;
400  }
401 
402  if ( $block->getExpiry() == 'infinity' ) {
403  $fields['Expiry']['default'] = 'infinite';
404  } else {
405  $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->getExpiry() );
406  }
407 
408  if ( !$block->isSitewide() ) {
409  $fields['EditingRestriction']['default'] = 'partial';
410 
411  $pageRestrictions = [];
412  $namespaceRestrictions = [];
413  foreach ( $block->getRestrictions() as $restriction ) {
414  if ( $restriction instanceof PageRestriction && $restriction->getTitle() ) {
415  $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
416  } elseif ( $restriction instanceof NamespaceRestriction ) {
417  $namespaceRestrictions[] = $restriction->getValue();
418  }
419  }
420 
421  // Sort the restrictions so they are in alphabetical order.
422  sort( $pageRestrictions );
423  $fields['PageRestrictions']['default'] = implode( "\n", $pageRestrictions );
424  sort( $namespaceRestrictions );
425  $fields['NamespaceRestrictions']['default'] = implode( "\n", $namespaceRestrictions );
426 
427  if (
428  // @phan-suppress-next-line PhanImpossibleCondition
429  empty( $pageRestrictions ) &&
430  // @phan-suppress-next-line PhanImpossibleCondition
431  empty( $namespaceRestrictions )
432  ) {
433  $fields['Editing']['default'] = false;
434  }
435  }
436 
437  $this->alreadyBlocked = true;
438  $this->preErrors[] = [ 'ipb-needreblock', wfEscapeWikiText( (string)$block->getTarget() ) ];
439  }
440 
441  if ( $this->alreadyBlocked || $this->getRequest()->wasPosted()
442  || $this->getRequest()->getCheck( 'wpCreateAccount' )
443  ) {
444  $this->getOutput()->addJsConfigVars( 'wgCreateAccountDirty', true );
445  }
446 
447  # We always need confirmation to do HideUser
448  if ( $this->requestedHideUser ) {
449  $fields['Confirm']['type'] = 'check';
450  unset( $fields['Confirm']['default'] );
451  $this->preErrors[] = [ 'ipb-confirmhideuser', 'ipb-confirmaction' ];
452  }
453 
454  # Or if the user is trying to block themselves
455  if ( (string)$this->target === $this->getUser()->getName() ) {
456  $fields['Confirm']['type'] = 'check';
457  unset( $fields['Confirm']['default'] );
458  $this->preErrors[] = [ 'ipb-blockingself', 'ipb-confirmaction' ];
459  }
460  }
461 
466  protected function preText() {
467  $this->getOutput()->addModuleStyles( [
468  'mediawiki.widgets.TagMultiselectWidget.styles',
469  'mediawiki.special',
470  ] );
471  $this->getOutput()->addModules( [ 'mediawiki.special.block' ] );
472 
473  $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
474  $text = $this->msg( 'blockiptext', $blockCIDRLimit['IPv4'], $blockCIDRLimit['IPv6'] )->parse();
475 
476  $otherBlockMessages = [];
477  if ( $this->target !== null ) {
478  $targetName = $this->target;
479  if ( $this->target instanceof User ) {
480  $targetName = $this->target->getName();
481  }
482  # Get other blocks, i.e. from GlobalBlocking or TorBlock extension
483  $this->getHookRunner()->onOtherBlockLogLink(
484  $otherBlockMessages, $targetName );
485 
486  if ( count( $otherBlockMessages ) ) {
488  'h2',
489  [],
490  $this->msg( 'ipb-otherblocks-header', count( $otherBlockMessages ) )->parse()
491  ) . "\n";
492 
493  $list = '';
494 
495  foreach ( $otherBlockMessages as $link ) {
496  $list .= Html::rawElement( 'li', [], $link ) . "\n";
497  }
498 
499  $s .= Html::rawElement(
500  'ul',
501  [ 'class' => 'mw-blockip-alreadyblocked' ],
502  $list
503  ) . "\n";
504 
505  $text .= $s;
506  }
507  }
508 
509  return $text;
510  }
511 
516  protected function postText() {
517  $links = [];
518 
519  $this->getOutput()->addModuleStyles( 'mediawiki.special' );
520 
521  $linkRenderer = $this->getLinkRenderer();
522  # Link to the user's contributions, if applicable
523  if ( $this->target instanceof User ) {
524  $contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->target->getName() );
525  $links[] = $linkRenderer->makeLink(
526  $contribsPage,
527  $this->msg( 'ipb-blocklist-contribs', $this->target->getName() )->text()
528  );
529  }
530 
531  # Link to unblock the specified user, or to a blank unblock form
532  if ( $this->target instanceof User ) {
533  $message = $this->msg(
534  'ipb-unblock-addr',
535  wfEscapeWikiText( $this->target->getName() )
536  )->parse();
537  $list = SpecialPage::getTitleFor( 'Unblock', $this->target->getName() );
538  } else {
539  $message = $this->msg( 'ipb-unblock' )->parse();
540  $list = SpecialPage::getTitleFor( 'Unblock' );
541  }
542  $links[] = $linkRenderer->makeKnownLink(
543  $list,
544  new HtmlArmor( $message )
545  );
546 
547  # Link to the block list
548  $links[] = $linkRenderer->makeKnownLink(
549  SpecialPage::getTitleFor( 'BlockList' ),
550  $this->msg( 'ipb-blocklist' )->text()
551  );
552 
553  $user = $this->getUser();
554 
555  # Link to edit the block dropdown reasons, if applicable
556  if ( $this->permissionManager->userHasRight( $user, 'editinterface' ) ) {
557  $links[] = $linkRenderer->makeKnownLink(
558  $this->msg( 'ipbreason-dropdown' )->inContentLanguage()->getTitle(),
559  $this->msg( 'ipb-edit-dropdown' )->text(),
560  [],
561  [ 'action' => 'edit' ]
562  );
563  }
564 
565  $text = Html::rawElement(
566  'p',
567  [ 'class' => 'mw-ipb-conveniencelinks' ],
568  $this->getLanguage()->pipeList( $links )
569  );
570 
571  $userTitle = self::getTargetUserTitle( $this->target );
572  if ( $userTitle ) {
573  # Get relevant extracts from the block and suppression logs, if possible
574  $out = '';
575 
577  $out,
578  'block',
579  $userTitle,
580  '',
581  [
582  'lim' => 10,
583  'msgKey' => [ 'blocklog-showlog', $userTitle->getText() ],
584  'showIfEmpty' => false
585  ]
586  );
587  $text .= $out;
588 
589  # Add suppression block entries if allowed
590  if ( $this->permissionManager->userHasRight( $user, 'suppressionlog' ) ) {
592  $out,
593  'suppress',
594  $userTitle,
595  '',
596  [
597  'lim' => 10,
598  'conds' => [ 'log_action' => [ 'block', 'reblock', 'unblock' ] ],
599  'msgKey' => [ 'blocklog-showsuppresslog', $userTitle->getText() ],
600  'showIfEmpty' => false
601  ]
602  );
603 
604  $text .= $out;
605  }
606  }
607 
608  return $text;
609  }
610 
617  protected static function getTargetUserTitle( $target ) {
618  if ( $target instanceof User ) {
619  return $target->getUserPage();
620  } elseif ( IPUtils::isIPAddress( $target ) ) {
622  }
623 
624  return null;
625  }
626 
636  public static function getTargetAndType( $par, WebRequest $request = null ) {
637  $i = 0;
638  $target = null;
639 
640  while ( true ) {
641  switch ( $i++ ) {
642  case 0:
643  # The HTMLForm will check wpTarget first and only if it doesn't get
644  # a value use the default, which will be generated from the options
645  # below; so this has to have a higher precedence here than $par, or
646  # we could end up with different values in $this->target and the HTMLForm!
647  if ( $request instanceof WebRequest ) {
648  $target = $request->getText( 'wpTarget', null );
649  }
650  break;
651  case 1:
652  $target = $par;
653  break;
654  case 2:
655  if ( $request instanceof WebRequest ) {
656  $target = $request->getText( 'ip', null );
657  }
658  break;
659  case 3:
660  # B/C @since 1.18
661  if ( $request instanceof WebRequest ) {
662  $target = $request->getText( 'wpBlockAddress', null );
663  }
664  break;
665  case 4:
666  break 2;
667  }
668 
669  list( $target, $type ) = DatabaseBlock::parseTarget( $target );
670 
671  if ( $type !== null ) {
672  return [ $target, $type ];
673  }
674  }
675 
676  return [ null, null ];
677  }
678 
687  public static function validateTargetField( $value, $alldata, $form ) {
688  $status = self::validateTarget( $value, $form->getUser() );
689  if ( !$status->isOK() ) {
690  $errors = $status->getErrorsArray();
691 
692  return $form->msg( ...$errors[0] );
693  } else {
694  return true;
695  }
696  }
697 
706  public static function validateTarget( $value, User $user ) {
707  global $wgBlockCIDRLimit;
708 
710  list( $target, $type ) = self::getTargetAndType( $value );
711  $status = Status::newGood( $target );
712 
713  if ( $type == DatabaseBlock::TYPE_USER ) {
714  if ( $target->isAnon() ) {
715  $status->fatal(
716  'nosuchusershort',
718  );
719  }
720 
721  $unblockStatus = self::checkUnblockSelf( $target, $user );
722  if ( $unblockStatus !== true ) {
723  $status->fatal( 'badaccess', $unblockStatus );
724  }
725  } elseif ( $type == DatabaseBlock::TYPE_RANGE ) {
726  list( $ip, $range ) = explode( '/', $target, 2 );
727 
728  if (
729  ( IPUtils::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 ) ||
730  ( IPUtils::isIPv6( $ip ) && $wgBlockCIDRLimit['IPv6'] == 128 )
731  ) {
732  // Range block effectively disabled
733  $status->fatal( 'range_block_disabled' );
734  }
735 
736  if (
737  ( IPUtils::isIPv4( $ip ) && $range > 32 ) ||
738  ( IPUtils::isIPv6( $ip ) && $range > 128 )
739  ) {
740  // Dodgy range
741  $status->fatal( 'ip_range_invalid' );
742  }
743 
744  if ( IPUtils::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
745  $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
746  }
747 
748  if ( IPUtils::isIPv6( $ip ) && $range < $wgBlockCIDRLimit['IPv6'] ) {
749  $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] );
750  }
751  } elseif ( $type == DatabaseBlock::TYPE_IP ) {
752  # All is well
753  } else {
754  $status->fatal( 'badipaddress' );
755  }
756 
757  return $status;
758  }
759 
767  public static function processForm( array $data, IContextSource $context ) {
768  $performer = $context->getUser();
769  $isPartialBlock = isset( $data['EditingRestriction'] ) &&
770  $data['EditingRestriction'] === 'partial';
771 
772  # This might have been a hidden field or a checkbox, so interesting data
773  # can come from it
774  $data['Confirm'] = !in_array( $data['Confirm'], [ '', '0', null, false ], true );
775 
777  list( $target, $type ) = self::getTargetAndType( $data['Target'] );
778  if ( $type == DatabaseBlock::TYPE_USER ) {
779  $user = $target;
780  $target = $user->getName();
781  $userId = $user->getId();
782 
783  # Give admins a heads-up before they go and block themselves. Much messier
784  # to do this for IPs, but it's pretty unlikely they'd ever get the 'block'
785  # permission anyway, although the code does allow for it.
786  # Note: Important to use $target instead of $data['Target']
787  # since both $data['PreviousTarget'] and $target are normalized
788  # but $data['target'] gets overridden by (non-normalized) request variable
789  # from previous request.
790  if ( $target === $performer->getName() &&
791  ( $data['PreviousTarget'] !== $target || !$data['Confirm'] )
792  ) {
793  return [ 'ipb-blockingself', 'ipb-confirmaction' ];
794  }
795  } elseif ( $type == DatabaseBlock::TYPE_RANGE ) {
796  $user = null;
797  $userId = 0;
798  } elseif ( $type == DatabaseBlock::TYPE_IP ) {
799  $user = null;
800  $target = $target->getName();
801  $userId = 0;
802  } else {
803  # This should have been caught in the form field validation
804  return [ 'badipaddress' ];
805  }
806 
807  // Reason, to be passed to the block object. For default values of reason, see
808  // HTMLSelectAndOtherField::getDefault
809  // @phan-suppress-next-line PhanPluginDuplicateConditionalNullCoalescing
810  $blockReason = isset( $data['Reason'][0] ) ? $data['Reason'][0] : '';
811 
812  $expiryTime = self::parseExpiryInput( $data['Expiry'] );
813 
814  if (
815  // an expiry time is needed
816  ( strlen( $data['Expiry'] ) == 0 ) ||
817  // can't be a larger string as 50 (it should be a time format in any way)
818  ( strlen( $data['Expiry'] ) > 50 ) ||
819  // check, if the time could be parsed
820  !$expiryTime
821  ) {
822  return [ 'ipb_expiry_invalid' ];
823  }
824 
825  // an expiry time should be in the future, not in the
826  // past (wouldn't make any sense) - bug T123069
827  if ( $expiryTime < wfTimestampNow() ) {
828  return [ 'ipb_expiry_old' ];
829  }
830 
831  if ( !isset( $data['DisableEmail'] ) ) {
832  $data['DisableEmail'] = false;
833  }
834 
835  # If the user has done the form 'properly', they won't even have been given the
836  # option to suppress-block unless they have the 'hideuser' permission
837  if ( !isset( $data['HideUser'] ) ) {
838  $data['HideUser'] = false;
839  }
840 
841  if ( $data['HideUser'] ) {
842  if ( !MediaWikiServices::getInstance()
844  ->userHasRight( $performer, 'hideuser' )
845  ) {
846  # this codepath is unreachable except by a malicious user spoofing forms,
847  # or by race conditions (user has hideuser and block rights, loads block form,
848  # and loses hideuser rights before submission); so need to fail completely
849  # rather than just silently disable hiding
850  return [ 'badaccess-group0' ];
851  }
852 
853  if ( $isPartialBlock ) {
854  return [ 'ipb_hide_partial' ];
855  }
856 
857  # Recheck params here...
858  $hideUserContribLimit = $context->getConfig()->get( 'HideUserContribLimit' );
859  if ( $type != DatabaseBlock::TYPE_USER ) {
860  $data['HideUser'] = false; # IP users should not be hidden
861  } elseif ( !wfIsInfinity( $data['Expiry'] ) ) {
862  # Bad expiry.
863  return [ 'ipb_expiry_temp' ];
864  } elseif ( $hideUserContribLimit !== false
865  && $user->getEditCount() > $hideUserContribLimit
866  ) {
867  # Typically, the user should have a handful of edits.
868  # Disallow hiding users with many edits for performance.
869  return [ [ 'ipb_hide_invalid',
870  Message::numParam( $hideUserContribLimit ) ] ];
871  } elseif ( !$data['Confirm'] ) {
872  return [ 'ipb-confirmhideuser', 'ipb-confirmaction' ];
873  }
874  }
875 
876  // Check whether the user can edit their own user talk page.
877  $blockAllowsUTEdit = $context->getConfig()->get( 'BlockAllowsUTEdit' );
878  $isUserTalkNamespaceBlock = !$isPartialBlock ||
879  in_array( NS_USER_TALK, explode( "\n", $data['NamespaceRestrictions'] ) );
880  if ( $isUserTalkNamespaceBlock ) {
881  // If the block blocks the user talk namespace, disallow own user talk edit if
882  // the global config disallows it; otherwise use the form field value.
883  $userTalkEditAllowed = $blockAllowsUTEdit ? !$data['DisableUTEdit'] : false;
884  } else {
885  // If the block doesn't block the user talk namespace, then it can't block own
886  // user talk edit, regardless of the config or field (T210475). Return error
887  // message if the field tries to disallow own user talk edit.
888  if ( isset( $data['DisableUTEdit'] ) && $data['DisableUTEdit'] ) {
889  return [ 'ipb-prevent-user-talk-edit' ];
890  }
891  $userTalkEditAllowed = true;
892  }
893 
894  // A block is empty if it is a partial block, the page restrictions are empty, the
895  // namespace restrictions are empty, and none of the actions are enabled
896  if ( $isPartialBlock &&
897  !( isset( $data['PageRestrictions'] ) && $data['PageRestrictions'] !== '' ) &&
898  !( isset( $data['NamespaceRestrictions'] ) && $data['NamespaceRestrictions'] !== '' ) &&
899  $data['DisableEmail'] === false &&
900  ( $userTalkEditAllowed || !$blockAllowsUTEdit ) &&
901  !$data['CreateAccount']
902  ) {
903  return [ 'ipb-empty-block' ];
904  }
905 
906  # Create block object.
907  $block = new DatabaseBlock();
908  $block->setTarget( $target );
909  $block->setBlocker( $performer );
910  $block->setReason( $blockReason );
911  $block->setExpiry( $expiryTime );
912  $block->isCreateAccountBlocked( $data['CreateAccount'] );
913  $block->isUsertalkEditAllowed( $userTalkEditAllowed );
914  $block->isEmailBlocked( $data['DisableEmail'] );
915  $block->isHardblock( $data['HardBlock'] );
916  $block->isAutoblocking( $data['AutoBlock'] );
917  $block->setHideName( $data['HideUser'] );
918 
919  if ( $isPartialBlock ) {
920  $block->isSitewide( false );
921  }
922 
923  $reason = [ 'hookaborted' ];
924  if ( !Hooks::runner()->onBlockIp( $block, $performer, $reason ) ) {
925  return $reason;
926  }
927 
928  $pageRestrictions = [];
929  $namespaceRestrictions = [];
930  if ( isset( $data['PageRestrictions'] ) && $data['PageRestrictions'] !== '' ) {
931  $pageRestrictions = array_map( function ( $text ) {
932  $title = Title::newFromText( $text );
933  // Use the link cache since the title has already been loaded when
934  // the field was validated.
935  $restriction = new PageRestriction( 0, $title->getArticleID() );
936  $restriction->setTitle( $title );
937  return $restriction;
938  }, explode( "\n", $data['PageRestrictions'] ) );
939  }
940  if ( isset( $data['NamespaceRestrictions'] ) && $data['NamespaceRestrictions'] !== '' ) {
941  $namespaceRestrictions = array_map( function ( $id ) {
942  return new NamespaceRestriction( 0, $id );
943  }, explode( "\n", $data['NamespaceRestrictions'] ) );
944  }
945 
946  $restrictions = ( array_merge( $pageRestrictions, $namespaceRestrictions ) );
947  $block->setRestrictions( $restrictions );
948 
949  $priorBlock = null;
950  # Try to insert block. Is there a conflicting block?
951  $status = $block->insert();
952  if ( !$status ) {
953  # Indicates whether the user is confirming the block and is aware of
954  # the conflict (did not change the block target in the meantime)
955  $blockNotConfirmed = !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
956  && $data['PreviousTarget'] !== $target );
957 
958  # Special case for API - T34434
959  $reblockNotAllowed = ( array_key_exists( 'Reblock', $data ) && !$data['Reblock'] );
960 
961  # Show form unless the user is already aware of this...
962  if ( $blockNotConfirmed || $reblockNotAllowed ) {
963  return [ [ 'ipb_already_blocked', $block->getTarget() ] ];
964  # Otherwise, try to update the block...
965  } else {
966  # This returns direct blocks before autoblocks/rangeblocks, since we should
967  # be sure the user is blocked by now it should work for our purposes
968  $currentBlock = DatabaseBlock::newFromTarget( $target );
969  if ( $block->equals( $currentBlock ) ) {
970  return [ [ 'ipb_already_blocked', $block->getTarget() ] ];
971  }
972  # If the name was hidden and the blocking user cannot hide
973  # names, then don't allow any block changes...
974  if ( $currentBlock->getHideName() && !MediaWikiServices::getInstance()
975  ->getPermissionManager()
976  ->userHasRight( $performer, 'hideuser' )
977  ) {
978  return [ 'cant-see-hidden-user' ];
979  }
980 
981  $priorBlock = clone $currentBlock;
982  $currentBlock->setBlocker( $performer );
983  $currentBlock->isHardblock( $block->isHardblock() );
984  $currentBlock->isCreateAccountBlocked( $block->isCreateAccountBlocked() );
985  $currentBlock->setExpiry( $block->getExpiry() );
986  $currentBlock->isAutoblocking( $block->isAutoblocking() );
987  $currentBlock->setHideName( $block->getHideName() );
988  $currentBlock->isEmailBlocked( $block->isEmailBlocked() );
989  $currentBlock->isUsertalkEditAllowed( $block->isUsertalkEditAllowed() );
990  $currentBlock->setReason( $block->getReasonComment() );
991 
992  // Maintain the sitewide status. If partial blocks is not enabled,
993  // saving the block will result in a sitewide block.
994  $currentBlock->isSitewide( $block->isSitewide() );
995 
996  // Set the block id of the restrictions.
997  $blockRestrictionStore = MediaWikiServices::getInstance()->getBlockRestrictionStore();
998  $currentBlock->setRestrictions(
999  $blockRestrictionStore->setBlockId( $currentBlock->getId(), $restrictions )
1000  );
1001 
1002  $status = $currentBlock->update();
1003  // TODO handle failure
1004 
1005  $logaction = 'reblock';
1006 
1007  # Unset _deleted fields if requested
1008  if ( $currentBlock->getHideName() && !$data['HideUser'] ) {
1010  }
1011 
1012  # If hiding/unhiding a name, this should go in the private logs
1013  if ( (bool)$currentBlock->getHideName() ) {
1014  $data['HideUser'] = true;
1015  }
1016 
1017  $block = $currentBlock;
1018  }
1019  } else {
1020  $logaction = 'block';
1021  }
1022 
1023  Hooks::runner()->onBlockIpComplete( $block, $performer, $priorBlock );
1024 
1025  # Set *_deleted fields if requested
1026  if ( $data['HideUser'] ) {
1028  }
1029 
1030  # Can't watch a rangeblock
1031  if ( $type != DatabaseBlock::TYPE_RANGE && $data['Watch'] ) {
1034  $performer,
1036  );
1037  }
1038 
1039  # DatabaseBlock constructor sanitizes certain block options on insert
1040  $data['BlockEmail'] = $block->isEmailBlocked();
1041  $data['AutoBlock'] = $block->isAutoblocking();
1042 
1043  # Prepare log parameters
1044  $logParams = [];
1045 
1046  $rawExpiry = $data['Expiry'];
1047  $logExpiry = wfIsInfinity( $rawExpiry ) ? 'infinity' : $rawExpiry;
1048 
1049  $logParams['5::duration'] = $logExpiry;
1050  $logParams['6::flags'] = self::blockLogFlags( $data, $type );
1051  $logParams['sitewide'] = $block->isSitewide();
1052 
1053  if ( !$block->isSitewide() ) {
1054  if ( $data['PageRestrictions'] !== '' ) {
1055  $logParams['7::restrictions']['pages'] = explode( "\n", $data['PageRestrictions'] );
1056  }
1057 
1058  if ( $data['NamespaceRestrictions'] !== '' ) {
1059  $logParams['7::restrictions']['namespaces'] = explode( "\n", $data['NamespaceRestrictions'] );
1060  }
1061  }
1062 
1063  # Make log entry, if the name is hidden, put it in the suppression log
1064  $log_type = $data['HideUser'] ? 'suppress' : 'block';
1065  $logEntry = new ManualLogEntry( $log_type, $logaction );
1066  $logEntry->setTarget( Title::makeTitle( NS_USER, $target ) );
1067  $logEntry->setComment( $blockReason );
1068  $logEntry->setPerformer( $performer );
1069  $logEntry->setParameters( $logParams );
1070  # Relate log ID to block ID (T27763)
1071  $logEntry->setRelations( [ 'ipb_id' => $block->getId() ] );
1072  $logId = $logEntry->insert();
1073 
1074  if ( !empty( $data['Tags'] ) ) {
1075  $logEntry->addTags( $data['Tags'] );
1076  }
1077 
1078  $logEntry->publish( $logId );
1079 
1080  return true;
1081  }
1082 
1093  public static function getSuggestedDurations( Language $lang = null, $includeOther = true ) {
1094  $msg = $lang === null
1095  ? wfMessage( 'ipboptions' )->inContentLanguage()->text()
1096  : wfMessage( 'ipboptions' )->inLanguage( $lang )->text();
1097 
1098  if ( $msg == '-' ) {
1099  return [];
1100  }
1101 
1102  $a = XmlSelect::parseOptionsMessage( $msg );
1103 
1104  if ( $a && $includeOther ) {
1105  // if options exist, add other to the end instead of the begining (which
1106  // is what happens by default).
1107  $a[ wfMessage( 'ipbother' )->text() ] = 'other';
1108  }
1109 
1110  return $a;
1111  }
1112 
1124  public static function parseExpiryInput( $expiry ) {
1125  if ( wfIsInfinity( $expiry ) ) {
1126  return 'infinity';
1127  }
1128 
1129  $expiry = strtotime( $expiry );
1130 
1131  if ( $expiry < 0 || $expiry === false ) {
1132  return false;
1133  }
1134 
1135  return wfTimestamp( TS_MW, $expiry );
1136  }
1137 
1143  public static function canBlockEmail( UserIdentity $user ) {
1144  global $wgEnableUserEmail;
1145 
1146  return ( $wgEnableUserEmail && MediaWikiServices::getInstance()
1148  ->userHasRight( $user, 'blockemail' ) );
1149  }
1150 
1164  public static function checkUnblockSelf( $target, User $performer ) {
1165  return MediaWikiServices::getInstance()
1166  ->getBlockPermissionCheckerFactory()
1167  ->newBlockPermissionChecker( $target, $performer )
1168  ->checkBlockPermissions();
1169  }
1170 
1178  protected static function blockLogFlags( array $data, $type ) {
1179  $config = RequestContext::getMain()->getConfig();
1180 
1181  $blockAllowsUTEdit = $config->get( 'BlockAllowsUTEdit' );
1182 
1183  $flags = [];
1184 
1185  # when blocking a user the option 'anononly' is not available/has no effect
1186  # -> do not write this into log
1187  if ( !$data['HardBlock'] && $type != DatabaseBlock::TYPE_USER ) {
1188  // For grepping: message block-log-flags-anononly
1189  $flags[] = 'anononly';
1190  }
1191 
1192  if ( $data['CreateAccount'] ) {
1193  // For grepping: message block-log-flags-nocreate
1194  $flags[] = 'nocreate';
1195  }
1196 
1197  # Same as anononly, this is not displayed when blocking an IP address
1198  if ( !$data['AutoBlock'] && $type == DatabaseBlock::TYPE_USER ) {
1199  // For grepping: message block-log-flags-noautoblock
1200  $flags[] = 'noautoblock';
1201  }
1202 
1203  if ( $data['DisableEmail'] ) {
1204  // For grepping: message block-log-flags-noemail
1205  $flags[] = 'noemail';
1206  }
1207 
1208  if ( $blockAllowsUTEdit && $data['DisableUTEdit'] ) {
1209  // For grepping: message block-log-flags-nousertalk
1210  $flags[] = 'nousertalk';
1211  }
1212 
1213  if ( $data['HideUser'] ) {
1214  // For grepping: message block-log-flags-hiddenname
1215  $flags[] = 'hiddenname';
1216  }
1217 
1218  return implode( ',', $flags );
1219  }
1220 
1227  public function onSubmit( array $data, HTMLForm $form = null ) {
1228  // If "Editing" checkbox is unchecked, the block must be a partial block affecting
1229  // actions other than editing, and there must be no restrictions.
1230  if ( isset( $data['Editing'] ) && $data['Editing'] === false ) {
1231  $data['EditingRestriction'] = 'partial';
1232  $data['PageRestrictions'] = '';
1233  $data['NamespaceRestrictions'] = '';
1234  }
1235  return self::processForm( $data, $form->getContext() );
1236  }
1237 
1242  public function onSuccess() {
1243  $out = $this->getOutput();
1244  $out->setPageTitle( $this->msg( 'blockipsuccesssub' ) );
1245  $out->addWikiMsg( 'blockipsuccesstext', wfEscapeWikiText( $this->target ) );
1246  }
1247 
1256  public function prefixSearchSubpages( $search, $limit, $offset ) {
1257  $user = User::newFromName( $search );
1258  if ( !$user ) {
1259  // No prefix suggestion for invalid user
1260  return [];
1261  }
1262  // Autocomplete subpage as user list - public to allow caching
1263  return UserNamePrefixSearch::search( 'public', $search, $limit, $offset );
1264  }
1265 
1266  protected function getGroupName() {
1267  return 'users';
1268  }
1269 }
Message\numParam
static numParam( $num)
Definition: Message.php:1048
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:828
MediaWiki\Block\Restriction\PageRestriction\getTitle
getTitle()
Get Title.
Definition: PageRestriction.php:72
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:329
HtmlArmor
Marks HTML that shouldn't be escaped.
Definition: HtmlArmor.php:30
SpecialBlock\canBlockEmail
static canBlockEmail(UserIdentity $user)
Can we do an email block?
Definition: SpecialBlock.php:1143
SpecialBlock\$permissionManager
PermissionManager $permissionManager
Definition: SpecialBlock.php:42
SpecialBlock\onSuccess
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
Definition: SpecialBlock.php:1242
WatchAction\doWatch
static doWatch(Title $title, User $user, $checkRights=User::CHECK_USER_RIGHTS, ?string $expiry=null)
Watch a page.
Definition: WatchAction.php:207
User\isAnon
isAnon()
Get whether the user is anonymous.
Definition: User.php:3022
SpecialBlock\$type
int $type
DatabaseBlock::TYPE_ constant.
Definition: SpecialBlock.php:50
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:744
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:154
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
SpecialBlock\checkUnblockSelf
static checkUnblockSelf( $target, User $performer)
T17810: Sitewide blocked admins should not be able to block/unblock others with one exception; they c...
Definition: SpecialBlock.php:1164
SpecialBlock\$preErrors
array $preErrors
Definition: SpecialBlock.php:62
HTMLForm\addHeaderText
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition: HTMLForm.php:819
SpecialBlock\$requestedHideUser
bool $requestedHideUser
Whether the previous submission of the form asked for HideUser.
Definition: SpecialBlock.php:56
SpecialBlock\processForm
static processForm(array $data, IContextSource $context)
Given the form data, actually implement a block.
Definition: SpecialBlock.php:767
SpecialBlock\preText
preText()
Add header elements like block log entries, etc.
Definition: SpecialBlock.php:466
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1808
HTMLForm\setHeaderText
setHeaderText( $msg, $section=null)
Set header text, inside the form.
Definition: HTMLForm.php:841
HTMLForm\formatErrors
formatErrors( $errors)
Format a stack of error messages into a single HTML string.
Definition: HTMLForm.php:1358
MediaWiki\Block\DatabaseBlock\getType
getType()
Get the type of target for this particular block.int|null AbstractBlock::TYPE_ constant,...
Definition: DatabaseBlock.php:1110
UserNamePrefixSearch\search
static search( $audience, $search, $limit, $offset=0)
Do a prefix search of user names and return a list of matching user names.
Definition: UserNamePrefixSearch.php:41
SpecialBlock\$target
User string null $target
User to be blocked, as passed either by parameter (url?wpTarget=Foo) or as subpage (Special:Block/Foo...
Definition: SpecialBlock.php:47
SpecialBlock\$previousTarget
User string $previousTarget
The previous block target.
Definition: SpecialBlock.php:53
$wgEnableUserEmail
$wgEnableUserEmail
Set to true to enable user-to-user e-mail.
Definition: DefaultSettings.php:1798
IP
Pre-librarized class name for IPUtils.
Definition: IP.php:80
SpecialBlock\onSubmit
onSubmit(array $data, HTMLForm $form=null)
Process the form on POST submission.
Definition: SpecialBlock.php:1227
FormSpecialPage
Special page which uses an HTMLForm to handle processing.
Definition: FormSpecialPage.php:31
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:539
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1219
User\getUserPage
getUserPage()
Get this user's personal page title.
Definition: User.php:3739
$s
$s
Definition: mergeMessageFileList.php:185
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:92
SpecialPage\getSkin
getSkin()
Shortcut to get the skin being used for this instance.
Definition: SpecialPage.php:764
RevisionDeleteUser\unsuppressUserName
static unsuppressUserName( $name, $userId, IDatabase $dbw=null)
Definition: RevisionDeleteUser.php:168
SpecialBlock\doesWrites
doesWrites()
Indicates whether this special page may perform database writes.
Definition: SpecialBlock.php:70
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:774
SpecialBlock\checkExecutePermissions
checkExecutePermissions(User $user)
Checks that the user can unblock themselves if they are trying to do so.
Definition: SpecialBlock.php:80
SpecialPage\getName
getName()
Get the name of this Special Page.
Definition: SpecialPage.php:164
SpecialBlock\setParameter
setParameter( $par)
Handle some magic here.
Definition: SpecialBlock.php:103
XmlSelect\parseOptionsMessage
static parseOptionsMessage(string $msg)
Parse labels and values out of a comma- and colon-separated list of options, such as is used for expi...
Definition: XmlSelect.php:145
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:32
SpecialBlock\__construct
__construct(PermissionManager $permissionManager)
Definition: SpecialBlock.php:64
SpecialBlock\postText
postText()
Add footer elements to the form.
Definition: SpecialBlock.php:516
MediaWiki\Block\DatabaseBlock
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
Definition: DatabaseBlock.php:52
SpecialPage\addHelpLink
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Definition: SpecialPage.php:864
SpecialPage\getHookRunner
getHookRunner()
Definition: SpecialPage.php:1010
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:794
SpecialBlock\maybeAlterFormDefaults
maybeAlterFormDefaults(&$fields)
If the user has already been blocked with similar settings, load that block and change the defaults f...
Definition: SpecialBlock.php:342
SpecialBlock\alterForm
alterForm(HTMLForm $form)
Customizes the HTMLForm a bit.
Definition: SpecialBlock.php:125
getPermissionManager
getPermissionManager()
SpecialBlock
A special page that allows users with 'block' right to block users from editing pages and other actio...
Definition: SpecialBlock.php:38
SpecialBlock\getTargetUserTitle
static getTargetUserTitle( $target)
Get a user page target for things like logs.
Definition: SpecialBlock.php:617
$title
$title
Definition: testCompression.php:38
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:754
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:592
LogEventsList\showLogExtract
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Definition: LogEventsList.php:639
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1837
SpecialBlock\prefixSearchSubpages
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
Definition: SpecialBlock.php:1256
FormSpecialPage\$par
string null $par
The sub-page of the special page.
Definition: FormSpecialPage.php:36
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:618
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:49
NS_USER_TALK
const NS_USER_TALK
Definition: Defines.php:72
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:172
wfIsInfinity
wfIsInfinity( $str)
Determine input string is represents as infinity.
Definition: GlobalFunctions.php:2785
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:734
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1487
SpecialBlock\getFormFields
getFormFields()
Get the HTMLForm descriptor array for the block form.
Definition: SpecialBlock.php:155
IContextSource\getUser
getUser()
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:453
HTMLForm\setSubmitDestructive
setSubmitDestructive()
Identify that the submit button in the form has a destructive action.
Definition: HTMLForm.php:1393
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:55
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:42
MediaWiki\Block\Restriction\NamespaceRestriction
Definition: NamespaceRestriction.php:25
CommentStore\COMMENT_CHARACTER_LIMIT
const COMMENT_CHARACTER_LIMIT
Maximum length of a comment in UTF-8 characters.
Definition: CommentStore.php:48
HTMLForm\setSubmitTextMsg
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1407
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:944
$wgBlockCIDRLimit
$wgBlockCIDRLimit
Limits on the possible sizes of range blocks.
Definition: DefaultSettings.php:5438
SpecialBlock\validateTargetField
static validateTargetField( $value, $alldata, $form)
HTMLForm field validation-callback for Target field.
Definition: SpecialBlock.php:687
MediaWiki\Block\Restriction\PageRestriction
Definition: PageRestriction.php:25
SpecialBlock\$alreadyBlocked
bool $alreadyBlocked
Definition: SpecialBlock.php:59
SpecialBlock\validateTarget
static validateTarget( $value, User $user)
Validate a block target.
Definition: SpecialBlock.php:706
IContextSource\getConfig
getConfig()
Get the site configuration.
SpecialBlock\getDisplayFormat
getDisplayFormat()
Get display format for the form.
Definition: SpecialBlock.php:147
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
getTitle
getTitle()
Definition: RevisionSearchResultTrait.php:81
SpecialBlock\parseExpiryInput
static parseExpiryInput( $expiry)
Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute ("24 May 2034",...
Definition: SpecialBlock.php:1124
SpecialBlock\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialBlock.php:1266
NS_USER
const NS_USER
Definition: Defines.php:71
SpecialBlock\getSuggestedDurations
static getSuggestedDurations(Language $lang=null, $includeOther=true)
Get an array of suggested block durations from MediaWiki:Ipboptions.
Definition: SpecialBlock.php:1093
ManualLogEntry
Class for creating new log entries and inserting them into the database.
Definition: ManualLogEntry.php:42
SpecialBlock\getTargetAndType
static getTargetAndType( $par, WebRequest $request=null)
Determine the target of the block, and the type of target.
Definition: SpecialBlock.php:636
RevisionDeleteUser\suppressUserName
static suppressUserName( $name, $userId, IDatabase $dbw=null)
Definition: RevisionDeleteUser.php:158
User\IGNORE_USER_RIGHTS
const IGNORE_USER_RIGHTS
Definition: User.php:90
SpecialPage\$linkRenderer
MediaWiki Linker LinkRenderer null $linkRenderer
Definition: SpecialPage.php:71
SpecialBlock\blockLogFlags
static blockLogFlags(array $data, $type)
Return a comma-delimited list of "flags" to be passed to the log reader for this block,...
Definition: SpecialBlock.php:1178
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:30
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
User\getName
getName()
Get the user name, or the IP of an anonymous user.
Definition: User.php:2054
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:41
SpecialBlock\requiresUnblock
requiresUnblock()
We allow certain special cases where user is blocked.
Definition: SpecialBlock.php:94
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:135