MediaWiki  1.34.0
SpecialBlock.php
Go to the documentation of this file.
1 <?php
29 
40  protected $target;
41 
43  protected $type;
44 
46  protected $previousTarget;
47 
49  protected $requestedHideUser;
50 
52  protected $alreadyBlocked;
53 
55  protected $preErrors = [];
56 
57  public function __construct() {
58  parent::__construct( 'Block', 'block' );
59  }
60 
61  public function doesWrites() {
62  return true;
63  }
64 
71  protected function checkExecutePermissions( User $user ) {
72  parent::checkExecutePermissions( $user );
73  # T17810: blocked admins should have limited access here
74  $status = self::checkUnblockSelf( $this->target, $user );
75  if ( $status !== true ) {
76  throw new ErrorPageError( 'badaccess', $status );
77  }
78  }
79 
85  public function requiresUnblock() {
86  return false;
87  }
88 
94  protected function setParameter( $par ) {
95  # Extract variables from the request. Try not to get into a situation where we
96  # need to extract *every* variable from the form just for processing here, but
97  # there are legitimate uses for some variables
98  $request = $this->getRequest();
99  list( $this->target, $this->type ) = self::getTargetAndType( $par, $request );
100  if ( $this->target instanceof User ) {
101  # Set the 'relevant user' in the skin, so it displays links like Contributions,
102  # User logs, UserRights, etc.
103  $this->getSkin()->setRelevantUser( $this->target );
104  }
105 
106  list( $this->previousTarget, /*...*/ ) =
107  DatabaseBlock::parseTarget( $request->getVal( 'wpPreviousTarget' ) );
108  $this->requestedHideUser = $request->getBool( 'wpHideUser' );
109  }
110 
116  protected function alterForm( HTMLForm $form ) {
117  $form->setHeaderText( '' );
118  $form->setSubmitDestructive();
119 
120  $msg = $this->alreadyBlocked ? 'ipb-change-block' : 'ipbsubmit';
121  $form->setSubmitTextMsg( $msg );
122 
123  $this->addHelpLink( 'Help:Blocking users' );
124 
125  # Don't need to do anything if the form has been posted
126  if ( !$this->getRequest()->wasPosted() && $this->preErrors ) {
127  $s = $form->formatErrors( $this->preErrors );
128  if ( $s ) {
129  $form->addHeaderText( Html::rawElement(
130  'div',
131  [ 'class' => 'error' ],
132  $s
133  ) );
134  }
135  }
136  }
137 
138  protected function getDisplayFormat() {
139  return 'ooui';
140  }
141 
146  protected function getFormFields() {
147  $conf = $this->getConfig();
148  $enablePartialBlocks = $conf->get( 'EnablePartialBlocks' );
149  $blockAllowsUTEdit = $conf->get( 'BlockAllowsUTEdit' );
150 
151  $this->getOutput()->enableOOUI();
152 
153  $user = $this->getUser();
154 
155  $suggestedDurations = self::getSuggestedDurations();
156 
157  $a = [];
158 
159  $a['Target'] = [
160  'type' => 'user',
161  'ipallowed' => true,
162  'iprange' => true,
163  'id' => 'mw-bi-target',
164  'size' => '45',
165  'autofocus' => true,
166  'required' => true,
167  'validation-callback' => [ __CLASS__, 'validateTargetField' ],
168  'section' => 'target',
169  ];
170 
171  $a['Editing'] = [
172  'type' => 'check',
173  'label-message' => 'block-prevent-edit',
174  'default' => true,
175  'section' => 'actions',
176  'disabled' => $enablePartialBlocks ? false : true,
177  ];
178 
179  if ( $enablePartialBlocks ) {
180  $a['EditingRestriction'] = [
181  'type' => 'radio',
182  'cssclass' => 'mw-block-editing-restriction',
183  'options' => [
184  $this->msg( 'ipb-sitewide' )->escaped() .
185  new \OOUI\LabelWidget( [
186  'classes' => [ 'oo-ui-inline-help' ],
187  'label' => $this->msg( 'ipb-sitewide-help' )->text(),
188  ] ) => 'sitewide',
189  $this->msg( 'ipb-partial' )->escaped() .
190  new \OOUI\LabelWidget( [
191  'classes' => [ 'oo-ui-inline-help' ],
192  'label' => $this->msg( 'ipb-partial-help' )->text(),
193  ] ) => 'partial',
194  ],
195  'section' => 'actions',
196  ];
197  $a['PageRestrictions'] = [
198  'type' => 'titlesmultiselect',
199  'label' => $this->msg( 'ipb-pages-label' )->text(),
200  'exists' => true,
201  'max' => 10,
202  'cssclass' => 'mw-block-restriction',
203  'showMissing' => false,
204  'excludeDynamicNamespaces' => true,
205  'input' => [
206  'autocomplete' => false
207  ],
208  'section' => 'actions',
209  ];
210  $a['NamespaceRestrictions'] = [
211  'type' => 'namespacesmultiselect',
212  'label' => $this->msg( 'ipb-namespaces-label' )->text(),
213  'exists' => true,
214  'cssclass' => 'mw-block-restriction',
215  'input' => [
216  'autocomplete' => false
217  ],
218  'section' => 'actions',
219  ];
220  }
221 
222  $a['CreateAccount'] = [
223  'type' => 'check',
224  'label-message' => 'ipbcreateaccount',
225  'default' => true,
226  'section' => 'actions',
227  ];
228 
229  if ( self::canBlockEmail( $user ) ) {
230  $a['DisableEmail'] = [
231  'type' => 'check',
232  'label-message' => 'ipbemailban',
233  'section' => 'actions',
234  ];
235  }
236 
237  if ( $blockAllowsUTEdit ) {
238  $a['DisableUTEdit'] = [
239  'type' => 'check',
240  'label-message' => 'ipb-disableusertalk',
241  'default' => false,
242  'section' => 'actions',
243  ];
244  }
245 
246  $a['Expiry'] = [
247  'type' => 'expiry',
248  'required' => true,
249  'options' => $suggestedDurations,
250  'default' => $this->msg( 'ipb-default-expiry' )->inContentLanguage()->text(),
251  'section' => 'expiry',
252  ];
253 
254  $a['Reason'] = [
255  'type' => 'selectandother',
256  // HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
257  // (e.g. emojis) count for two each. This limit is overridden in JS to instead count
258  // Unicode codepoints.
260  'maxlength-unit' => 'codepoints',
261  'options-message' => 'ipbreason-dropdown',
262  'section' => 'reason',
263  ];
264 
265  $a['AutoBlock'] = [
266  'type' => 'check',
267  'label-message' => 'ipbenableautoblock',
268  'default' => true,
269  'section' => 'options',
270  ];
271 
272  # Allow some users to hide name from block log, blocklist and listusers
273  if ( MediaWikiServices::getInstance()
275  ->userHasRight( $user, 'hideuser' )
276  ) {
277  $a['HideUser'] = [
278  'type' => 'check',
279  'label-message' => 'ipbhidename',
280  'cssclass' => 'mw-block-hideuser',
281  'section' => 'options',
282  ];
283  }
284 
285  # Watchlist their user page? (Only if user is logged in)
286  if ( $user->isLoggedIn() ) {
287  $a['Watch'] = [
288  'type' => 'check',
289  'label-message' => 'ipbwatchuser',
290  'section' => 'options',
291  ];
292  }
293 
294  $a['HardBlock'] = [
295  'type' => 'check',
296  'label-message' => 'ipb-hardblock',
297  'default' => false,
298  'section' => 'options',
299  ];
300 
301  # This is basically a copy of the Target field, but the user can't change it, so we
302  # can see if the warnings we maybe showed to the user before still apply
303  $a['PreviousTarget'] = [
304  'type' => 'hidden',
305  'default' => false,
306  ];
307 
308  # We'll turn this into a checkbox if we need to
309  $a['Confirm'] = [
310  'type' => 'hidden',
311  'default' => '',
312  'label-message' => 'ipb-confirm',
313  'cssclass' => 'mw-block-confirm',
314  ];
315 
316  $this->maybeAlterFormDefaults( $a );
317 
318  // Allow extensions to add more fields
319  Hooks::run( 'SpecialBlockModifyFormFields', [ $this, &$a ] );
320 
321  return $a;
322  }
323 
329  protected function maybeAlterFormDefaults( &$fields ) {
330  # This will be overwritten by request data
331  $fields['Target']['default'] = (string)$this->target;
332 
333  if ( $this->target ) {
334  $status = self::validateTarget( $this->target, $this->getUser() );
335  if ( !$status->isOK() ) {
336  $errors = $status->getErrorsArray();
337  $this->preErrors = array_merge( $this->preErrors, $errors );
338  }
339  }
340 
341  # This won't be
342  $fields['PreviousTarget']['default'] = (string)$this->target;
343 
344  $block = DatabaseBlock::newFromTarget( $this->target );
345 
346  // Populate fields if there is a block that is not an autoblock; if it is a range
347  // block, only populate the fields if the range is the same as $this->target
348  if ( $block instanceof DatabaseBlock && $block->getType() !== DatabaseBlock::TYPE_AUTO
349  && ( $this->type != DatabaseBlock::TYPE_RANGE
350  || $block->getTarget() == $this->target )
351  ) {
352  $fields['HardBlock']['default'] = $block->isHardblock();
353  $fields['CreateAccount']['default'] = $block->isCreateAccountBlocked();
354  $fields['AutoBlock']['default'] = $block->isAutoblocking();
355 
356  if ( isset( $fields['DisableEmail'] ) ) {
357  $fields['DisableEmail']['default'] = $block->isEmailBlocked();
358  }
359 
360  if ( isset( $fields['HideUser'] ) ) {
361  $fields['HideUser']['default'] = $block->getHideName();
362  }
363 
364  if ( isset( $fields['DisableUTEdit'] ) ) {
365  $fields['DisableUTEdit']['default'] = !$block->isUsertalkEditAllowed();
366  }
367 
368  // If the username was hidden (ipb_deleted == 1), don't show the reason
369  // unless this user also has rights to hideuser: T37839
370  if ( !$block->getHideName() || MediaWikiServices::getInstance()
371  ->getPermissionManager()
372  ->userHasRight( $this->getUser(), 'hideuser' )
373  ) {
374  $fields['Reason']['default'] = $block->getReason();
375  } else {
376  $fields['Reason']['default'] = '';
377  }
378 
379  if ( $this->getRequest()->wasPosted() ) {
380  # Ok, so we got a POST submission asking us to reblock a user. So show the
381  # confirm checkbox; the user will only see it if they haven't previously
382  $fields['Confirm']['type'] = 'check';
383  } else {
384  # We got a target, but it wasn't a POST request, so the user must have gone
385  # to a link like [[Special:Block/User]]. We don't need to show the checkbox
386  # as long as they go ahead and block *that* user
387  $fields['Confirm']['default'] = 1;
388  }
389 
390  if ( $block->getExpiry() == 'infinity' ) {
391  $fields['Expiry']['default'] = 'infinite';
392  } else {
393  $fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->getExpiry() );
394  }
395 
396  $this->alreadyBlocked = true;
397  $this->preErrors[] = [ 'ipb-needreblock', wfEscapeWikiText( (string)$block->getTarget() ) ];
398  }
399 
400  if ( $this->alreadyBlocked || $this->getRequest()->wasPosted()
401  || $this->getRequest()->getCheck( 'wpCreateAccount' )
402  ) {
403  $this->getOutput()->addJsConfigVars( 'wgCreateAccountDirty', true );
404  }
405 
406  # We always need confirmation to do HideUser
407  if ( $this->requestedHideUser ) {
408  $fields['Confirm']['type'] = 'check';
409  unset( $fields['Confirm']['default'] );
410  $this->preErrors[] = [ 'ipb-confirmhideuser', 'ipb-confirmaction' ];
411  }
412 
413  # Or if the user is trying to block themselves
414  if ( (string)$this->target === $this->getUser()->getName() ) {
415  $fields['Confirm']['type'] = 'check';
416  unset( $fields['Confirm']['default'] );
417  $this->preErrors[] = [ 'ipb-blockingself', 'ipb-confirmaction' ];
418  }
419 
420  if ( $this->getConfig()->get( 'EnablePartialBlocks' ) ) {
421  if ( $block instanceof DatabaseBlock && !$block->isSitewide() ) {
422  $fields['EditingRestriction']['default'] = 'partial';
423  } else {
424  $fields['EditingRestriction']['default'] = 'sitewide';
425  }
426 
427  if ( $block instanceof DatabaseBlock ) {
428  $pageRestrictions = [];
429  $namespaceRestrictions = [];
430  foreach ( $block->getRestrictions() as $restriction ) {
431  switch ( $restriction->getType() ) {
432  case PageRestriction::TYPE:
434  '@phan-var PageRestriction $restriction';
435  if ( $restriction->getTitle() ) {
436  $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
437  }
438  break;
439  case NamespaceRestriction::TYPE:
440  $namespaceRestrictions[] = $restriction->getValue();
441  break;
442  }
443  }
444 
445  if (
446  !$block->isSitewide() &&
447  empty( $pageRestrictions ) &&
448  empty( $namespaceRestrictions )
449  ) {
450  $fields['Editing']['default'] = false;
451  }
452 
453  // Sort the restrictions so they are in alphabetical order.
454  sort( $pageRestrictions );
455  $fields['PageRestrictions']['default'] = implode( "\n", $pageRestrictions );
456  sort( $namespaceRestrictions );
457  $fields['NamespaceRestrictions']['default'] = implode( "\n", $namespaceRestrictions );
458  }
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  Hooks::run( 'OtherBlockLogLink', [ &$otherBlockMessages, $targetName ] );
484 
485  if ( count( $otherBlockMessages ) ) {
486  $s = Html::rawElement(
487  'h2',
488  [],
489  $this->msg( 'ipb-otherblocks-header', count( $otherBlockMessages ) )->parse()
490  ) . "\n";
491 
492  $list = '';
493 
494  foreach ( $otherBlockMessages as $link ) {
495  $list .= Html::rawElement( 'li', [], $link ) . "\n";
496  }
497 
498  $s .= Html::rawElement(
499  'ul',
500  [ 'class' => 'mw-blockip-alreadyblocked' ],
501  $list
502  ) . "\n";
503 
504  $text .= $s;
505  }
506  }
507 
508  return $text;
509  }
510 
515  protected function postText() {
516  $links = [];
517 
518  $this->getOutput()->addModuleStyles( 'mediawiki.special' );
519 
520  $linkRenderer = $this->getLinkRenderer();
521  # Link to the user's contributions, if applicable
522  if ( $this->target instanceof User ) {
523  $contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->target->getName() );
524  $links[] = $linkRenderer->makeLink(
525  $contribsPage,
526  $this->msg( 'ipb-blocklist-contribs', $this->target->getName() )->text()
527  );
528  }
529 
530  # Link to unblock the specified user, or to a blank unblock form
531  if ( $this->target instanceof User ) {
532  $message = $this->msg(
533  'ipb-unblock-addr',
534  wfEscapeWikiText( $this->target->getName() )
535  )->parse();
536  $list = SpecialPage::getTitleFor( 'Unblock', $this->target->getName() );
537  } else {
538  $message = $this->msg( 'ipb-unblock' )->parse();
539  $list = SpecialPage::getTitleFor( 'Unblock' );
540  }
541  $links[] = $linkRenderer->makeKnownLink(
542  $list,
543  new HtmlArmor( $message )
544  );
545 
546  # Link to the block list
547  $links[] = $linkRenderer->makeKnownLink(
548  SpecialPage::getTitleFor( 'BlockList' ),
549  $this->msg( 'ipb-blocklist' )->text()
550  );
551 
552  $user = $this->getUser();
553 
554  # Link to edit the block dropdown reasons, if applicable
555  $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
556  if ( $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 ( $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 ( IP::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 );
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  ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 ) ||
730  ( IP::isIPv6( $ip ) && $wgBlockCIDRLimit['IPv6'] == 128 )
731  ) {
732  // Range block effectively disabled
733  $status->fatal( 'range_block_disabled' );
734  }
735 
736  if (
737  ( IP::isIPv4( $ip ) && $range > 32 ) ||
738  ( IP::isIPv6( $ip ) && $range > 128 )
739  ) {
740  // Dodgy range
741  $status->fatal( 'ip_range_invalid' );
742  }
743 
744  if ( IP::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
745  $status->fatal( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
746  }
747 
748  if ( IP::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  $enablePartialBlocks = $context->getConfig()->get( 'EnablePartialBlocks' );
770  $isPartialBlock = $enablePartialBlocks &&
771  isset( $data['EditingRestriction'] ) &&
772  $data['EditingRestriction'] === 'partial';
773 
774  # This might have been a hidden field or a checkbox, so interesting data
775  # can come from it
776  $data['Confirm'] = !in_array( $data['Confirm'], [ '', '0', null, false ], true );
777 
779  list( $target, $type ) = self::getTargetAndType( $data['Target'] );
780  if ( $type == DatabaseBlock::TYPE_USER ) {
781  $user = $target;
782  $target = $user->getName();
783  $userId = $user->getId();
784 
785  # Give admins a heads-up before they go and block themselves. Much messier
786  # to do this for IPs, but it's pretty unlikely they'd ever get the 'block'
787  # permission anyway, although the code does allow for it.
788  # Note: Important to use $target instead of $data['Target']
789  # since both $data['PreviousTarget'] and $target are normalized
790  # but $data['target'] gets overridden by (non-normalized) request variable
791  # from previous request.
792  if ( $target === $performer->getName() &&
793  ( $data['PreviousTarget'] !== $target || !$data['Confirm'] )
794  ) {
795  return [ 'ipb-blockingself', 'ipb-confirmaction' ];
796  }
797  } elseif ( $type == DatabaseBlock::TYPE_RANGE ) {
798  $user = null;
799  $userId = 0;
800  } elseif ( $type == DatabaseBlock::TYPE_IP ) {
801  $user = null;
802  $target = $target->getName();
803  $userId = 0;
804  } else {
805  # This should have been caught in the form field validation
806  return [ 'badipaddress' ];
807  }
808 
809  $expiryTime = self::parseExpiryInput( $data['Expiry'] );
810 
811  if (
812  // an expiry time is needed
813  ( strlen( $data['Expiry'] ) == 0 ) ||
814  // can't be a larger string as 50 (it should be a time format in any way)
815  ( strlen( $data['Expiry'] ) > 50 ) ||
816  // check, if the time could be parsed
817  !$expiryTime
818  ) {
819  return [ 'ipb_expiry_invalid' ];
820  }
821 
822  // an expiry time should be in the future, not in the
823  // past (wouldn't make any sense) - bug T123069
824  if ( $expiryTime < wfTimestampNow() ) {
825  return [ 'ipb_expiry_old' ];
826  }
827 
828  if ( !isset( $data['DisableEmail'] ) ) {
829  $data['DisableEmail'] = false;
830  }
831 
832  # If the user has done the form 'properly', they won't even have been given the
833  # option to suppress-block unless they have the 'hideuser' permission
834  if ( !isset( $data['HideUser'] ) ) {
835  $data['HideUser'] = false;
836  }
837 
838  if ( $data['HideUser'] ) {
839  if ( !MediaWikiServices::getInstance()
841  ->userHasRight( $performer, 'hideuser' )
842  ) {
843  # this codepath is unreachable except by a malicious user spoofing forms,
844  # or by race conditions (user has hideuser and block rights, loads block form,
845  # and loses hideuser rights before submission); so need to fail completely
846  # rather than just silently disable hiding
847  return [ 'badaccess-group0' ];
848  }
849 
850  if ( $isPartialBlock ) {
851  return [ 'ipb_hide_partial' ];
852  }
853 
854  # Recheck params here...
855  $hideUserContribLimit = $context->getConfig()->get( 'HideUserContribLimit' );
856  if ( $type != DatabaseBlock::TYPE_USER ) {
857  $data['HideUser'] = false; # IP users should not be hidden
858  } elseif ( !wfIsInfinity( $data['Expiry'] ) ) {
859  # Bad expiry.
860  return [ 'ipb_expiry_temp' ];
861  } elseif ( $hideUserContribLimit !== false
862  && $user->getEditCount() > $hideUserContribLimit
863  ) {
864  # Typically, the user should have a handful of edits.
865  # Disallow hiding users with many edits for performance.
866  return [ [ 'ipb_hide_invalid',
867  Message::numParam( $hideUserContribLimit ) ] ];
868  } elseif ( !$data['Confirm'] ) {
869  return [ 'ipb-confirmhideuser', 'ipb-confirmaction' ];
870  }
871  }
872 
873  $blockAllowsUTEdit = $context->getConfig()->get( 'BlockAllowsUTEdit' );
874  $userTalkEditAllowed = !$blockAllowsUTEdit || !$data['DisableUTEdit'];
875  if ( !$userTalkEditAllowed &&
876  $isPartialBlock &&
877  !in_array( NS_USER_TALK, explode( "\n", $data['NamespaceRestrictions'] ) )
878  ) {
879  return [ 'ipb-prevent-user-talk-edit' ];
880  }
881 
882  # Create block object.
883  $block = new DatabaseBlock();
884  $block->setTarget( $target );
885  $block->setBlocker( $performer );
886  $block->setReason( $data['Reason'][0] );
887  $block->setExpiry( $expiryTime );
888  $block->isCreateAccountBlocked( $data['CreateAccount'] );
889  $block->isUsertalkEditAllowed( $userTalkEditAllowed );
890  $block->isEmailBlocked( $data['DisableEmail'] );
891  $block->isHardblock( $data['HardBlock'] );
892  $block->isAutoblocking( $data['AutoBlock'] );
893  $block->setHideName( $data['HideUser'] );
894 
895  if ( $isPartialBlock ) {
896  $block->isSitewide( false );
897  }
898 
899  $reason = [ 'hookaborted' ];
900  if ( !Hooks::run( 'BlockIp', [ &$block, &$performer, &$reason ] ) ) {
901  return $reason;
902  }
903 
904  $pageRestrictions = [];
905  $namespaceRestrictions = [];
906  if ( $enablePartialBlocks ) {
907  if ( $data['PageRestrictions'] !== '' ) {
908  $pageRestrictions = array_map( function ( $text ) {
909  $title = Title::newFromText( $text );
910  // Use the link cache since the title has already been loaded when
911  // the field was validated.
912  $restriction = new PageRestriction( 0, $title->getArticleID() );
913  $restriction->setTitle( $title );
914  return $restriction;
915  }, explode( "\n", $data['PageRestrictions'] ) );
916  }
917  if ( $data['NamespaceRestrictions'] !== '' ) {
918  $namespaceRestrictions = array_map( function ( $id ) {
919  return new NamespaceRestriction( 0, $id );
920  }, explode( "\n", $data['NamespaceRestrictions'] ) );
921  }
922 
923  $restrictions = ( array_merge( $pageRestrictions, $namespaceRestrictions ) );
924  $block->setRestrictions( $restrictions );
925  }
926 
927  $priorBlock = null;
928  # Try to insert block. Is there a conflicting block?
929  $status = $block->insert();
930  if ( !$status ) {
931  # Indicates whether the user is confirming the block and is aware of
932  # the conflict (did not change the block target in the meantime)
933  $blockNotConfirmed = !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
934  && $data['PreviousTarget'] !== $target );
935 
936  # Special case for API - T34434
937  $reblockNotAllowed = ( array_key_exists( 'Reblock', $data ) && !$data['Reblock'] );
938 
939  # Show form unless the user is already aware of this...
940  if ( $blockNotConfirmed || $reblockNotAllowed ) {
941  return [ [ 'ipb_already_blocked', $block->getTarget() ] ];
942  # Otherwise, try to update the block...
943  } else {
944  # This returns direct blocks before autoblocks/rangeblocks, since we should
945  # be sure the user is blocked by now it should work for our purposes
946  $currentBlock = DatabaseBlock::newFromTarget( $target );
947  if ( $block->equals( $currentBlock ) ) {
948  return [ [ 'ipb_already_blocked', $block->getTarget() ] ];
949  }
950  # If the name was hidden and the blocking user cannot hide
951  # names, then don't allow any block changes...
952  if ( $currentBlock->getHideName() && !MediaWikiServices::getInstance()
953  ->getPermissionManager()
954  ->userHasRight( $performer, 'hideuser' )
955  ) {
956  return [ 'cant-see-hidden-user' ];
957  }
958 
959  $priorBlock = clone $currentBlock;
960  $currentBlock->isHardblock( $block->isHardblock() );
961  $currentBlock->isCreateAccountBlocked( $block->isCreateAccountBlocked() );
962  $currentBlock->setExpiry( $block->getExpiry() );
963  $currentBlock->isAutoblocking( $block->isAutoblocking() );
964  $currentBlock->setHideName( $block->getHideName() );
965  $currentBlock->isEmailBlocked( $block->isEmailBlocked() );
966  $currentBlock->isUsertalkEditAllowed( $block->isUsertalkEditAllowed() );
967  $currentBlock->setReason( $block->getReason() );
968 
969  if ( $enablePartialBlocks ) {
970  // Maintain the sitewide status. If partial blocks is not enabled,
971  // saving the block will result in a sitewide block.
972  $currentBlock->isSitewide( $block->isSitewide() );
973 
974  // Set the block id of the restrictions.
975  $blockRestrictionStore = MediaWikiServices::getInstance()->getBlockRestrictionStore();
976  $currentBlock->setRestrictions(
977  $blockRestrictionStore->setBlockId( $currentBlock->getId(), $restrictions )
978  );
979  }
980 
981  $status = $currentBlock->update();
982  // TODO handle failure
983 
984  $logaction = 'reblock';
985 
986  # Unset _deleted fields if requested
987  if ( $currentBlock->getHideName() && !$data['HideUser'] ) {
989  }
990 
991  # If hiding/unhiding a name, this should go in the private logs
992  if ( (bool)$currentBlock->getHideName() ) {
993  $data['HideUser'] = true;
994  }
995 
996  $block = $currentBlock;
997  }
998  } else {
999  $logaction = 'block';
1000  }
1001 
1002  Hooks::run( 'BlockIpComplete', [ $block, $performer, $priorBlock ] );
1003 
1004  # Set *_deleted fields if requested
1005  if ( $data['HideUser'] ) {
1007  }
1008 
1009  # Can't watch a rangeblock
1010  if ( $type != DatabaseBlock::TYPE_RANGE && $data['Watch'] ) {
1013  $performer,
1015  );
1016  }
1017 
1018  # DatabaseBlock constructor sanitizes certain block options on insert
1019  $data['BlockEmail'] = $block->isEmailBlocked();
1020  $data['AutoBlock'] = $block->isAutoblocking();
1021 
1022  # Prepare log parameters
1023  $logParams = [];
1024  $logParams['5::duration'] = $data['Expiry'];
1025  $logParams['6::flags'] = self::blockLogFlags( $data, $type );
1026  $logParams['sitewide'] = $block->isSitewide();
1027 
1028  if ( $enablePartialBlocks && !$block->isSitewide() ) {
1029  if ( $data['PageRestrictions'] !== '' ) {
1030  $logParams['7::restrictions']['pages'] = explode( "\n", $data['PageRestrictions'] );
1031  }
1032 
1033  if ( $data['NamespaceRestrictions'] !== '' ) {
1034  $logParams['7::restrictions']['namespaces'] = explode( "\n", $data['NamespaceRestrictions'] );
1035  }
1036  }
1037 
1038  # Make log entry, if the name is hidden, put it in the suppression log
1039  $log_type = $data['HideUser'] ? 'suppress' : 'block';
1040  $logEntry = new ManualLogEntry( $log_type, $logaction );
1041  $logEntry->setTarget( Title::makeTitle( NS_USER, $target ) );
1042  $logEntry->setComment( $data['Reason'][0] );
1043  $logEntry->setPerformer( $performer );
1044  $logEntry->setParameters( $logParams );
1045  # Relate log ID to block ID (T27763)
1046  $logEntry->setRelations( [ 'ipb_id' => $block->getId() ] );
1047  $logId = $logEntry->insert();
1048 
1049  if ( !empty( $data['Tags'] ) ) {
1050  $logEntry->addTags( $data['Tags'] );
1051  }
1052 
1053  $logEntry->publish( $logId );
1054 
1055  return true;
1056  }
1057 
1068  public static function getSuggestedDurations( Language $lang = null, $includeOther = true ) {
1069  $a = [];
1070  $msg = $lang === null
1071  ? wfMessage( 'ipboptions' )->inContentLanguage()->text()
1072  : wfMessage( 'ipboptions' )->inLanguage( $lang )->text();
1073 
1074  if ( $msg == '-' ) {
1075  return [];
1076  }
1077 
1078  foreach ( explode( ',', $msg ) as $option ) {
1079  if ( strpos( $option, ':' ) === false ) {
1080  $option = "$option:$option";
1081  }
1082 
1083  list( $show, $value ) = explode( ':', $option );
1084  $a[$show] = $value;
1085  }
1086 
1087  if ( $a && $includeOther ) {
1088  // if options exist, add other to the end instead of the begining (which
1089  // is what happens by default).
1090  $a[ wfMessage( 'ipbother' )->text() ] = 'other';
1091  }
1092 
1093  return $a;
1094  }
1095 
1107  public static function parseExpiryInput( $expiry ) {
1108  if ( wfIsInfinity( $expiry ) ) {
1109  return 'infinity';
1110  }
1111 
1112  $expiry = strtotime( $expiry );
1113 
1114  if ( $expiry < 0 || $expiry === false ) {
1115  return false;
1116  }
1117 
1118  return wfTimestamp( TS_MW, $expiry );
1119  }
1120 
1126  public static function canBlockEmail( UserIdentity $user ) {
1127  global $wgEnableUserEmail;
1128 
1129  return ( $wgEnableUserEmail && MediaWikiServices::getInstance()
1131  ->userHasRight( $user, 'blockemail' ) );
1132  }
1133 
1148  public static function checkUnblockSelf( $target, User $performer ) {
1149  if ( is_int( $target ) ) {
1151  } elseif ( is_string( $target ) ) {
1153  }
1154  if ( $performer->getBlock() ) {
1155  if ( $target instanceof User && $target->getId() == $performer->getId() ) {
1156  # User is trying to unblock themselves
1157  if ( MediaWikiServices::getInstance()
1158  ->getPermissionManager()
1159  ->userHasRight( $performer, 'unblockself' )
1160  ) {
1161  return true;
1162  # User blocked themselves and is now trying to reverse it
1163  } elseif ( $performer->blockedBy() === $performer->getName() ) {
1164  return true;
1165  } else {
1166  return 'ipbnounblockself';
1167  }
1168  } elseif (
1169  $target instanceof User &&
1170  $performer->getBlock() instanceof DatabaseBlock &&
1171  $performer->getBlock()->getBy() &&
1172  $performer->getBlock()->getBy() === $target->getId()
1173  ) {
1174  // Allow users to block the user that blocked them.
1175  // This is to prevent a situation where a malicious user
1176  // blocks all other users. This way, the non-malicious
1177  // user can block the malicious user back, resulting
1178  // in a stalemate.
1179  return true;
1180 
1181  } else {
1182  # User is trying to block/unblock someone else
1183  return 'ipbblocked';
1184  }
1185  } else {
1186  return true;
1187  }
1188  }
1189 
1197  protected static function blockLogFlags( array $data, $type ) {
1198  $config = RequestContext::getMain()->getConfig();
1199 
1200  $blockAllowsUTEdit = $config->get( 'BlockAllowsUTEdit' );
1201 
1202  $flags = [];
1203 
1204  # when blocking a user the option 'anononly' is not available/has no effect
1205  # -> do not write this into log
1206  if ( !$data['HardBlock'] && $type != DatabaseBlock::TYPE_USER ) {
1207  // For grepping: message block-log-flags-anononly
1208  $flags[] = 'anononly';
1209  }
1210 
1211  if ( $data['CreateAccount'] ) {
1212  // For grepping: message block-log-flags-nocreate
1213  $flags[] = 'nocreate';
1214  }
1215 
1216  # Same as anononly, this is not displayed when blocking an IP address
1217  if ( !$data['AutoBlock'] && $type == DatabaseBlock::TYPE_USER ) {
1218  // For grepping: message block-log-flags-noautoblock
1219  $flags[] = 'noautoblock';
1220  }
1221 
1222  if ( $data['DisableEmail'] ) {
1223  // For grepping: message block-log-flags-noemail
1224  $flags[] = 'noemail';
1225  }
1226 
1227  if ( $blockAllowsUTEdit && $data['DisableUTEdit'] ) {
1228  // For grepping: message block-log-flags-nousertalk
1229  $flags[] = 'nousertalk';
1230  }
1231 
1232  if ( $data['HideUser'] ) {
1233  // For grepping: message block-log-flags-hiddenname
1234  $flags[] = 'hiddenname';
1235  }
1236 
1237  return implode( ',', $flags );
1238  }
1239 
1246  public function onSubmit( array $data, HTMLForm $form = null ) {
1247  // If "Editing" checkbox is unchecked, the block must be a partial block affecting
1248  // actions other than editing, and there must be no restrictions.
1249  if ( isset( $data['Editing'] ) && $data['Editing'] === false ) {
1250  $data['EditingRestriction'] = 'partial';
1251  $data['PageRestrictions'] = '';
1252  $data['NamespaceRestrictions'] = '';
1253  }
1254  return self::processForm( $data, $form->getContext() );
1255  }
1256 
1261  public function onSuccess() {
1262  $out = $this->getOutput();
1263  $out->setPageTitle( $this->msg( 'blockipsuccesssub' ) );
1264  $out->addWikiMsg( 'blockipsuccesstext', wfEscapeWikiText( $this->target ) );
1265  }
1266 
1275  public function prefixSearchSubpages( $search, $limit, $offset ) {
1276  $user = User::newFromName( $search );
1277  if ( !$user ) {
1278  // No prefix suggestion for invalid user
1279  return [];
1280  }
1281  // Autocomplete subpage as user list - public to allow caching
1282  return UserNamePrefixSearch::search( 'public', $search, $limit, $offset );
1283  }
1284 
1285  protected function getGroupName() {
1286  return 'users';
1287  }
1288 }
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:539
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:316
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:1126
SpecialBlock\onSuccess
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
Definition: SpecialBlock.php:1261
User\getId
getId()
Get the user's ID.
Definition: User.php:2203
User\isAnon
isAnon()
Get whether the user is anonymous.
Definition: User.php:3532
SpecialBlock\$type
int $type
DatabaseBlock::TYPE_ constant.
Definition: SpecialBlock.php:43
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:117
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
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:1148
SpecialBlock\$preErrors
array $preErrors
Definition: SpecialBlock.php:55
HTMLForm\addHeaderText
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition: HTMLForm.php:802
SpecialBlock\$requestedHideUser
bool $requestedHideUser
Whether the previous submission of the form asked for HideUser.
Definition: SpecialBlock.php:49
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:1869
HTMLForm\setHeaderText
setHeaderText( $msg, $section=null)
Set header text, inside the form.
Definition: HTMLForm.php:824
HTMLForm\formatErrors
formatErrors( $errors)
Format a stack of error messages into a single HTML string.
Definition: HTMLForm.php:1339
MediaWiki\Block\DatabaseBlock\getType
getType()
Get the type of target for this particular block.int AbstractBlock::TYPE_ constant,...
Definition: DatabaseBlock.php:1356
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:40
SpecialBlock\$previousTarget
User string $previousTarget
The previous block target.
Definition: SpecialBlock.php:46
$wgEnableUserEmail
$wgEnableUserEmail
Set to true to enable user-to-user e-mail.
Definition: DefaultSettings.php:1693
IP
A collection of public static functions to play with IP address and IP ranges.
Definition: IP.php:67
SpecialBlock\onSubmit
onSubmit(array $data, HTMLForm $form=null)
Process the form on POST submission.
Definition: SpecialBlock.php:1246
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:515
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1264
IP\isIPv6
static isIPv6( $ip)
Given a string, determine if it as valid IP in IPv6 only.
Definition: IP.php:88
User\getUserPage
getUserPage()
Get this user's personal page title.
Definition: User.php:4275
$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:61
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:71
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:94
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:515
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:329
SpecialBlock\__construct
__construct()
Definition: SpecialBlock.php:57
SpecialBlock\alterForm
alterForm(HTMLForm $form)
Customizes the HTMLForm a bit.
Definition: SpecialBlock.php:116
getPermissionManager
getPermissionManager()
SpecialBlock
A special page that allows users with 'block' right to block users from editing pages and other actio...
Definition: SpecialBlock.php:36
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:617
$title
$title
Definition: testCompression.php:34
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:586
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:1898
MediaWiki\Block\AbstractBlock\isSitewide
isSitewide( $x=null)
Indicates that the block is a sitewide block.
Definition: AbstractBlock.php:203
User\getBlock
getBlock( $fromReplica=true)
Get the block affecting the user, or null if the user is not blocked.
Definition: User.php:2068
SpecialBlock\prefixSearchSubpages
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
Definition: SpecialBlock.php:1275
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:613
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:2960
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:1551
SpecialBlock\getFormFields
getFormFields()
Get the HTMLForm descriptor array for the block form.
Definition: SpecialBlock.php:146
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:431
User\blockedBy
blockedBy()
If user is blocked, return the name of the user who placed the block.
Definition: User.php:2093
HTMLForm\setSubmitDestructive
setSubmitDestructive()
Identify that the submit button in the form has a destructive action.
Definition: HTMLForm.php:1374
IP\isIPv4
static isIPv4( $ip)
Given a string, determine if it as valid IP in IPv4 only.
Definition: IP.php:99
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:42
$context
$context
Definition: load.php:45
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:1388
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:904
$status
return $status
Definition: SyntaxHighlight.php:347
$wgBlockCIDRLimit
$wgBlockCIDRLimit
Limits on the possible sizes of range blocks.
Definition: DefaultSettings.php:5015
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:52
SpecialBlock\validateTarget
static validateTarget( $value, User $user)
Validate a block target.
Definition: SpecialBlock.php:706
SpecialBlock\getDisplayFormat
getDisplayFormat()
Get display format for the form.
Definition: SpecialBlock.php:138
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:1107
SpecialBlock\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialBlock.php:1285
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:1068
ManualLogEntry
Class for creating new log entries and inserting them into the database.
Definition: ManualLogEntry.php:37
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:83
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:1197
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:51
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:2232
Language
Internationalisation code.
Definition: Language.php:37
IP\isIPAddress
static isIPAddress( $ip)
Determine if a string is as valid IP address or network (CIDR prefix).
Definition: IP.php:77
SpecialBlock\requiresUnblock
requiresUnblock()
We allow certain special cases where user is blocked.
Definition: SpecialBlock.php:85
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:131