131 parent::__construct(
'Block',
'block' );
133 $this->blockUtils = $blockUtils;
134 $this->blockPermissionCheckerFactory = $blockPermissionCheckerFactory;
135 $this->blockUserFactory = $blockUserFactory;
136 $this->blockStore = $blockStore;
137 $this->userNameUtils = $userNameUtils;
138 $this->userNamePrefixSearch = $userNamePrefixSearch;
139 $this->blockActionInfo = $blockActionInfo;
140 $this->titleFormatter = $titleFormatter;
141 $this->namespaceInfo = $namespaceInfo;
145 parent::execute(
$par );
147 if ( $this->
getConfig()->
get(
'UseCodexSpecialBlock' ) ) {
148 $this->
getOutput()->addModules(
'mediawiki.special.block.codex' );
163 parent::checkExecutePermissions( $user );
165 $status = $this->blockPermissionCheckerFactory
166 ->newBlockPermissionChecker( $this->target, $user )
167 ->checkBlockPermissions();
168 if ( $status !==
true ) {
196 $this->
getSkin()->setRelevantUser( $this->target );
200 ->parseBlockTarget( $request->getVal(
'wpPreviousTarget' ) );
201 $this->requestedHideUser = $request->getBool(
'wpHideUser' );
213 $msg = $this->alreadyBlocked ?
'ipb-change-block' :
'ipbsubmit';
219 if ( !$this->
getRequest()->wasPosted() && $this->preErrors ) {
225 'errors' => array_map(
function ( $errMsg ) {
227 return new HtmlSnippet( $this->
msg( ...$errMsg )->parse() );
235 return $this->
getConfig()->get(
'UseCodexSpecialBlock' ) ?
'codex' :
'ooui';
250 $suggestedDurations = $this->
getLanguage()->getBlockDurations();
258 'id' =>
'mw-bi-target',
262 'placeholder' => $this->
msg(
'block-target-placeholder' )->text(),
263 'validation-callback' =>
function ( $value, $alldata, $form ) {
264 $status = $this->blockUtils->validateTarget( $value );
265 if ( !$status->isOK() ) {
266 $errors = $status->getErrorsArray();
268 return $form->msg( ...$errors[0] );
272 'section' =>
'target',
275 $editingRestrictionOptions = $this->
getConfig()->get(
'UseCodexSpecialBlock' ) ?
278 'options-messages' => [
279 'ipb-sitewide' =>
'sitewide',
280 'ipb-partial' =>
'partial'
282 'option-descriptions-messages' => [
283 'sitewide' =>
'ipb-sitewide-help',
284 'partial' =>
'ipb-partial-help'
286 'option-descriptions-messages-parse' =>
true,
291 $this->
msg(
'ipb-sitewide' )->escaped() .
293 'classes' => [
'oo-ui-inline-help' ],
294 'label' =>
new HtmlSnippet( $this->
msg(
'ipb-sitewide-help' )->parse() ),
296 $this->
msg(
'ipb-partial' )->escaped() .
298 'classes' => [
'oo-ui-inline-help' ],
299 'label' =>
new HtmlSnippet( $this->
msg(
'ipb-partial-help' )->parse() ),
304 $a[
'EditingRestriction'] = [
306 'cssclass' =>
'mw-block-editing-restriction',
307 'default' =>
'sitewide',
308 'section' =>
'actions',
309 ] + $editingRestrictionOptions;
311 $a[
'PageRestrictions'] = [
312 'type' =>
'titlesmultiselect',
313 'label' => $this->
msg(
'ipb-pages-label' )->text(),
316 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction',
318 'showMissing' =>
false,
319 'excludeDynamicNamespaces' =>
true,
321 'autocomplete' => false
323 'section' =>
'actions',
326 $a[
'NamespaceRestrictions'] = [
327 'type' =>
'namespacesmultiselect',
328 'label' => $this->
msg(
'ipb-namespaces-label' )->text(),
330 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction',
333 'autocomplete' => false
335 'section' =>
'actions',
339 $blockActions = $this->blockActionInfo->getAllBlockActions();
340 $a[
'ActionRestrictions'] = [
341 'type' =>
'multiselect',
342 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction mw-block-action-restriction',
343 'options-messages' => array_combine(
344 array_map(
static function ( $action ) {
345 return "ipb-action-$action";
346 }, array_keys( $blockActions ) ),
349 'section' =>
'actions',
353 $a[
'CreateAccount'] = [
355 'cssclass' =>
'mw-block-restriction',
356 'label-message' =>
'ipbcreateaccount',
358 'section' =>
'details',
361 if ( $this->blockPermissionCheckerFactory
362 ->newBlockPermissionChecker(
null, $user )
363 ->checkEmailPermissions()
365 $a[
'DisableEmail'] = [
367 'cssclass' =>
'mw-block-restriction',
368 'label-message' =>
'ipbemailban',
369 'section' =>
'details',
373 if ( $blockAllowsUTEdit ) {
374 $a[
'DisableUTEdit'] = [
376 'cssclass' =>
'mw-block-restriction',
377 'label-message' =>
'ipb-disableusertalk',
379 'section' =>
'details',
383 $defaultExpiry = $this->
msg(
'ipb-default-expiry' )->inContentLanguage();
384 if ( $this->type === DatabaseBlock::TYPE_RANGE || $this->type === DatabaseBlock::TYPE_IP ) {
385 $defaultExpiryIP = $this->
msg(
'ipb-default-expiry-ip' )->inContentLanguage();
386 if ( !$defaultExpiryIP->isDisabled() ) {
387 $defaultExpiry = $defaultExpiryIP;
394 'options' => $suggestedDurations,
395 'default' => $defaultExpiry->text(),
396 'section' =>
'expiry',
400 'type' =>
'selectandother',
404 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
405 'maxlength-unit' =>
'codepoints',
406 'options-message' =>
'ipbreason-dropdown',
407 'section' =>
'reason',
413 'ipbenableautoblock',
417 'section' =>
'options',
424 'label-message' =>
'ipbhidename',
425 'cssclass' =>
'mw-block-hideuser',
426 'section' =>
'options',
431 if ( $user->isRegistered() ) {
434 'label-message' =>
'ipbwatchuser',
435 'section' =>
'options',
441 'label-message' =>
'ipb-hardblock',
443 'section' =>
'options',
448 $a[
'PreviousTarget'] = [
457 'label-message' =>
'ipb-confirm',
458 'cssclass' =>
'mw-block-confirm',
464 $this->
getHookRunner()->onSpecialBlockModifyFormFields( $this, $a );
476 $fields[
'Target'][
'default'] = (string)$this->target;
478 if ( $this->target ) {
479 $status = $this->blockUtils->validateTarget( $this->target );
480 if ( !$status->isOK() ) {
481 $errors = $status->getErrorsArray();
482 $this->preErrors = array_merge( $this->preErrors, $errors );
487 $fields[
'PreviousTarget'][
'default'] = (string)$this->target;
489 $block = $this->blockStore->newFromTarget( $this->target );
494 && ( $this->type != DatabaseBlock::TYPE_RANGE
495 || ( $this->target && $block->isBlocking( $this->target ) ) )
497 $fields[
'HardBlock'][
'default'] = $block->isHardblock();
498 $fields[
'CreateAccount'][
'default'] = $block->isCreateAccountBlocked();
499 $fields[
'AutoBlock'][
'default'] = $block->isAutoblocking();
501 if ( isset( $fields[
'DisableEmail'] ) ) {
502 $fields[
'DisableEmail'][
'default'] = $block->isEmailBlocked();
505 if ( isset( $fields[
'HideUser'] ) ) {
506 $fields[
'HideUser'][
'default'] = $block->getHideName();
509 if ( isset( $fields[
'DisableUTEdit'] ) ) {
510 $fields[
'DisableUTEdit'][
'default'] = !$block->isUsertalkEditAllowed();
515 if ( !$block->getHideName() || $this->
getAuthority()->isAllowed(
'hideuser' ) ) {
516 $fields[
'Reason'][
'default'] = $block->getReasonComment()->text;
518 $fields[
'Reason'][
'default'] =
'';
524 $fields[
'Confirm'][
'type'] =
'check';
529 $fields[
'Confirm'][
'default'] = 1;
532 if ( $block->getExpiry() ==
'infinity' ) {
533 $fields[
'Expiry'][
'default'] =
'infinite';
535 $fields[
'Expiry'][
'default'] =
wfTimestamp( TS_RFC2822, $block->getExpiry() );
538 if ( !$block->isSitewide() ) {
539 $fields[
'EditingRestriction'][
'default'] =
'partial';
541 $pageRestrictions = [];
542 $namespaceRestrictions = [];
543 foreach ( $block->getRestrictions() as $restriction ) {
545 $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
547 $this->namespaceInfo->exists( $restriction->getValue() )
549 $namespaceRestrictions[] = $restriction->getValue();
554 sort( $pageRestrictions );
555 $fields[
'PageRestrictions'][
'default'] = implode(
"\n", $pageRestrictions );
556 sort( $namespaceRestrictions );
557 $fields[
'NamespaceRestrictions'][
'default'] = implode(
"\n", $namespaceRestrictions );
560 $actionRestrictions = [];
561 foreach ( $block->getRestrictions() as $restriction ) {
563 $actionRestrictions[] = $restriction->getValue();
566 $fields[
'ActionRestrictions'][
'default'] = $actionRestrictions;
570 $this->alreadyBlocked =
true;
571 $this->preErrors[] = [
'ipb-needreblock',
wfEscapeWikiText( $block->getTargetName() ) ];
574 if ( $this->alreadyBlocked || $this->
getRequest()->wasPosted()
575 || $this->
getRequest()->getCheck(
'wpCreateAccount' )
577 $this->
getOutput()->addJsConfigVars(
'wgCreateAccountDirty',
true );
581 if ( $this->requestedHideUser ) {
582 $fields[
'Confirm'][
'type'] =
'check';
583 unset( $fields[
'Confirm'][
'default'] );
584 $this->preErrors[] = [
'ipb-confirmhideuser',
'ipb-confirmaction' ];
589 $fields[
'Confirm'][
'type'] =
'check';
590 unset( $fields[
'Confirm'][
'default'] );
591 $this->preErrors[] = [
'ipb-blockingself',
'ipb-confirmaction' ];
600 $this->
getOutput()->addModuleStyles( [
'mediawiki.special' ] );
601 $this->
getOutput()->addModules( [
'mediawiki.special.block' ] );
604 $text = $this->
msg(
'blockiptext', $blockCIDRLimit[
'IPv4'], $blockCIDRLimit[
'IPv6'] )->parse();
606 $otherBlockMessages = [];
607 if ( $this->target !==
null ) {
610 $targetName = $this->target->
getName();
614 $otherBlockMessages, $targetName );
616 if ( count( $otherBlockMessages ) ) {
617 $s = Html::rawElement(
620 $this->
msg(
'ipb-otherblocks-header', count( $otherBlockMessages ) )->parse()
625 foreach ( $otherBlockMessages as $link ) {
626 $list .= Html::rawElement(
'li', [], $link ) .
"\n";
629 $s .= Html::rawElement(
631 [
'class' =>
'mw-blockip-alreadyblocked' ],
649 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
655 $links[] = $linkRenderer->makeLink(
657 $this->
msg(
'ipb-blocklist-contribs', $this->target->getName() )->text()
663 $message = $this->
msg(
669 $message = $this->
msg(
'ipb-unblock' )->parse();
672 $links[] = $linkRenderer->makeKnownLink(
678 $links[] = $linkRenderer->makeKnownLink(
680 $this->
msg(
'ipb-blocklist' )->text()
684 if ( $this->
getAuthority()->isAllowed(
'editinterface' ) ) {
685 $links[] = $linkRenderer->makeKnownLink(
686 $this->
msg(
'ipbreason-dropdown' )->inContentLanguage()->
getTitle(),
687 $this->
msg(
'ipb-edit-dropdown' )->text(),
689 [
'action' =>
'edit' ]
693 $text = Html::rawElement(
695 [
'class' =>
'mw-ipb-conveniencelinks' ],
704 LogEventsList::showLogExtract(
713 $this->titleFormatter->getText( $userPage ),
715 'showIfEmpty' =>
false
721 if ( $this->
getAuthority()->isAllowed(
'suppressionlog' ) ) {
722 LogEventsList::showLogExtract(
729 'conds' => [
'log_action' => [
'block',
'reblock',
'unblock' ] ],
731 'blocklog-showsuppresslog',
732 $this->titleFormatter->getText( $userPage ),
734 'showIfEmpty' =>
false
779 return self::getTargetAndTypeInternal( $par, $request );
793 private static function getTargetAndTypeInternal( ?
string $par,
WebRequest $request =
null ) {
799 $request->getVal(
'wpTarget',
null ),
801 $request->getVal(
'ip',
null ),
803 $request->getVal(
'wpBlockAddress',
null ),
805 foreach ( $possibleTargets as $possibleTarget ) {
808 ->parseBlockTarget( $possibleTarget );
810 if ( $targetAndType[ 1 ] !==
null ) {
814 return $targetAndType;
827 return self::processFormInternal(
830 $services->getBlockUserFactory(),
831 $services->getBlockUtils()
845 private static function processFormInternal(
855 $isPartialBlock = isset( $data[
'EditingRestriction'] ) &&
856 $data[
'EditingRestriction'] ===
'partial';
860 $data[
'Confirm'] = !in_array( $data[
'Confirm'], [
'',
'0',
null,
false ],
true );
864 if ( !isset( $data[
'HideUser'] ) ) {
865 $data[
'HideUser'] =
false;
870 if ( $type == DatabaseBlock::TYPE_USER ) {
871 $target = $target->getName();
880 if ( $target === $performer->
getUser()->getName() &&
881 ( $data[
'PreviousTarget'] !== $target || !$data[
'Confirm'] )
883 return [
'ipb-blockingself',
'ipb-confirmaction' ];
886 if ( $data[
'HideUser'] && !$data[
'Confirm'] ) {
887 return [
'ipb-confirmhideuser',
'ipb-confirmaction' ];
889 } elseif ( $type == DatabaseBlock::TYPE_IP ) {
890 $target = $target->getName();
891 } elseif ( $type != DatabaseBlock::TYPE_RANGE ) {
893 return [
'badipaddress' ];
898 $blockReason = $data[
'Reason'][0] ??
'';
900 $pageRestrictions = [];
901 $namespaceRestrictions = [];
902 $actionRestrictions = [];
903 if ( $isPartialBlock ) {
904 if ( isset( $data[
'PageRestrictions'] ) && $data[
'PageRestrictions'] !==
'' ) {
905 $titles = explode(
"\n", $data[
'PageRestrictions'] );
906 foreach ( $titles as $title ) {
907 $pageRestrictions[] = PageRestriction::newFromTitle( $title );
910 if ( isset( $data[
'NamespaceRestrictions'] ) && $data[
'NamespaceRestrictions'] !==
'' ) {
911 $namespaceRestrictions = array_map(
static function ( $id ) {
912 return new NamespaceRestriction( 0, (
int)$id );
913 }, explode(
"\n", $data[
'NamespaceRestrictions'] ) );
916 $enablePartialActionBlocks &&
917 isset( $data[
'ActionRestrictions'] ) &&
918 $data[
'ActionRestrictions'] !==
''
920 $actionRestrictions = array_map(
static function ( $id ) {
921 return new ActionRestriction( 0, $id );
922 }, $data[
'ActionRestrictions'] );
925 $restrictions = array_merge( $pageRestrictions, $namespaceRestrictions, $actionRestrictions );
927 if ( !isset( $data[
'Tags'] ) ) {
932 'isCreateAccountBlocked' => $data[
'CreateAccount'],
933 'isHardBlock' => $data[
'HardBlock'],
934 'isAutoblocking' => $data[
'AutoBlock'],
935 'isHideUser' => $data[
'HideUser'],
936 'isPartial' => $isPartialBlock,
939 if ( isset( $data[
'DisableUTEdit'] ) ) {
940 $blockOptions[
'isUserTalkEditBlocked'] = $data[
'DisableUTEdit'];
942 if ( isset( $data[
'DisableEmail'] ) ) {
943 $blockOptions[
'isEmailBlocked'] = $data[
'DisableEmail'];
958 $blockNotConfirmed = !$data[
'Confirm'] || ( array_key_exists(
'PreviousTarget', $data )
959 && $data[
'PreviousTarget'] !== $target );
962 $reblockNotAllowed = ( array_key_exists(
'Reblock', $data ) && !$data[
'Reblock'] );
964 $doReblock = !$blockNotConfirmed && !$reblockNotAllowed;
966 $status = $blockUser->placeBlock( $doReblock );
967 if ( !$status->isOK() ) {
973 $type != DatabaseBlock::TYPE_RANGE
978 && array_key_exists(
'Watch', $data )
983 Title::makeTitle(
NS_USER, $target )
1003 return $lang->getBlockDurations( $includeOther );
1028 ->getBlockPermissionCheckerFactory()
1029 ->newBlockPermissionChecker(
null, User::newFromIdentity( $user ) )
1030 ->checkEmailPermissions();
1040 return self::processFormInternal(
1043 $this->blockUserFactory,
1053 $out = $this->getOutput();
1054 $out->setPageTitleMsg( $this->msg(
'blockipsuccesssub' ) );
1055 $out->addWikiMsg(
'blockipsuccesstext',
wfEscapeWikiText( $this->target ) );
1067 $search = $this->userNameUtils->getCanonical( $search );
1073 return $this->userNamePrefixSearch
1074 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
1083class_alias( SpecialBlock::class,
'SpecialBlock' );
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
if(!defined('MW_SETUP_CALLBACK'))
An error page which can definitely be safely rendered using the OutputPage.
Marks HTML that shouldn't be escaped.
Base class for language-specific code.
A class containing constants representing the names of configuration variables.
const AutoblockExpiry
Name constant for the AutoblockExpiry setting, for use with Config::get()
const BlockAllowsUTEdit
Name constant for the BlockAllowsUTEdit setting, for use with Config::get()
const BlockCIDRLimit
Name constant for the BlockCIDRLimit setting, for use with Config::get()
const EnablePartialActionBlocks
Name constant for the EnablePartialActionBlocks setting, for use with Config::get()
Special page which uses an HTMLForm to handle processing.
string null $par
The sub-page of the special page.
Parent class for all special pages.
getSkin()
Shortcut to get the skin being used for this instance.
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,...
getUser()
Shortcut to get the User executing this instance.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getAuthority()
Shortcut to get the Authority executing this instance.
getLanguage()
Shortcut to get user's language.
getName()
Get the canonical, unlocalized name of this special page without namespace.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Interface for objects which can provide a MediaWiki context on request.