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