133 parent::__construct(
'Block',
'block' );
135 $this->blockUtils = $blockUtils;
136 $this->blockPermissionCheckerFactory = $blockPermissionCheckerFactory;
137 $this->blockUserFactory = $blockUserFactory;
138 $this->blockStore = $blockStore;
139 $this->userNameUtils = $userNameUtils;
140 $this->userNamePrefixSearch = $userNamePrefixSearch;
141 $this->blockActionInfo = $blockActionInfo;
142 $this->titleFormatter = $titleFormatter;
143 $this->namespaceInfo = $namespaceInfo;
147 parent::execute(
$par );
150 $this->
getOutput()->addModules(
'mediawiki.special.block.codex' );
151 $this->
getOutput()->addJsConfigVars( $this->codexFormData );
166 parent::checkExecutePermissions( $user );
168 $status = $this->blockPermissionCheckerFactory
169 ->newBlockPermissionChecker( $this->target, $user )
170 ->checkBlockPermissions();
171 if ( $status !==
true ) {
199 $this->
getSkin()->setRelevantUser( $this->target );
203 ->parseBlockTarget( $request->getVal(
'wpPreviousTarget' ) );
204 $this->requestedHideUser = $request->getBool(
'wpHideUser' );
216 $msg = $this->alreadyBlocked ?
'ipb-change-block' :
'ipbsubmit';
222 if ( !$this->
getRequest()->wasPosted() && $this->preErrors ) {
228 'errors' => array_map(
function ( $errMsg ) {
229 return new HtmlSnippet( $this->
msg( $errMsg )->parse() );
252 $suggestedDurations = $this->
getLanguage()->getBlockDurations();
260 'id' =>
'mw-bi-target',
264 'placeholder' => $this->
msg(
'block-target-placeholder' )->text(),
265 'validation-callback' =>
function ( $value, $alldata, $form ) {
266 $status = $this->blockUtils->validateTarget( $value );
267 if ( !$status->isOK() ) {
268 $errors = $status->getMessages();
269 return $form->msg( $errors[0] );
273 'section' =>
'target',
279 'options-messages' => [
280 'ipb-sitewide' =>
'sitewide',
281 'ipb-partial' =>
'partial'
283 'option-descriptions-messages' => [
284 'sitewide' =>
'ipb-sitewide-help',
285 'partial' =>
'ipb-partial-help'
287 'option-descriptions-messages-parse' =>
true,
292 $this->
msg(
'ipb-sitewide' )->escaped() .
294 'classes' => [
'oo-ui-inline-help' ],
295 'label' =>
new HtmlSnippet( $this->
msg(
'ipb-sitewide-help' )->parse() ),
297 $this->
msg(
'ipb-partial' )->escaped() .
299 'classes' => [
'oo-ui-inline-help' ],
300 'label' =>
new HtmlSnippet( $this->
msg(
'ipb-partial-help' )->parse() ),
305 $a[
'EditingRestriction'] = [
307 'cssclass' =>
'mw-block-editing-restriction',
308 'default' =>
'sitewide',
309 'section' =>
'actions',
310 ] + $editingRestrictionOptions;
312 $a[
'PageRestrictions'] = [
313 'type' =>
'titlesmultiselect',
314 'label' => $this->
msg(
'ipb-pages-label' )->text(),
317 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction',
319 'showMissing' =>
false,
320 'excludeDynamicNamespaces' =>
true,
322 'autocomplete' => false
324 'section' =>
'actions',
327 $a[
'NamespaceRestrictions'] = [
328 'type' =>
'namespacesmultiselect',
329 'label' => $this->
msg(
'ipb-namespaces-label' )->text(),
331 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction',
334 'autocomplete' => false
336 'section' =>
'actions',
340 $blockActions = $this->blockActionInfo->getAllBlockActions();
341 $optionMessages = array_combine(
342 array_map(
static function ( $action ) {
343 return "ipb-action-$action";
344 }, array_keys( $blockActions ) ),
348 $this->codexFormData[
'partialBlockActionOptions'] = $optionMessages;
350 $a[
'ActionRestrictions'] = [
351 'type' =>
'multiselect',
352 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction mw-block-action-restriction',
353 'options-messages' => $optionMessages,
354 'section' =>
'actions',
358 $a[
'CreateAccount'] = [
360 'cssclass' =>
'mw-block-restriction',
361 'label-message' =>
'ipbcreateaccount',
363 'section' =>
'details',
366 if ( $this->blockPermissionCheckerFactory
367 ->newBlockPermissionChecker(
null, $user )
368 ->checkEmailPermissions()
370 $a[
'DisableEmail'] = [
372 'cssclass' =>
'mw-block-restriction',
373 'label-message' =>
'ipbemailban',
374 'section' =>
'details',
377 $this->codexFormData[
'blockAllowsEmailBan'] =
true;
380 if ( $blockAllowsUTEdit ) {
381 $a[
'DisableUTEdit'] = [
383 'cssclass' =>
'mw-block-restriction',
384 'label-message' =>
'ipb-disableusertalk',
386 'section' =>
'details',
389 $this->codexFormData[
'blockAllowsUTEdit'] =
true;
392 $defaultExpiry = $this->
msg(
'ipb-default-expiry' )->inContentLanguage();
393 if ( $this->type === DatabaseBlock::TYPE_RANGE || $this->type === DatabaseBlock::TYPE_IP ) {
394 $defaultExpiryIP = $this->
msg(
'ipb-default-expiry-ip' )->inContentLanguage();
395 if ( !$defaultExpiryIP->isDisabled() ) {
396 $defaultExpiry = $defaultExpiryIP;
403 'options' => $suggestedDurations,
404 'default' => $defaultExpiry->text(),
405 'section' =>
'expiry',
409 'type' =>
'selectandother',
413 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
414 'maxlength-unit' =>
'codepoints',
415 'options-message' =>
'ipbreason-dropdown',
416 'section' =>
'reason',
422 'ipbenableautoblock',
426 'section' =>
'options',
433 'label-message' =>
'ipbhidename',
434 'cssclass' =>
'mw-block-hideuser',
435 'section' =>
'options',
438 $this->codexFormData[
'hideUser'] =
true;
442 if ( $user->isRegistered() ) {
445 'label-message' =>
'ipbwatchuser',
446 'section' =>
'options',
452 'label-message' =>
'ipb-hardblock',
454 'section' =>
'options',
459 $a[
'PreviousTarget'] = [
468 'label-message' =>
'ipb-confirm',
469 'cssclass' =>
'mw-block-confirm',
475 $this->
getHookRunner()->onSpecialBlockModifyFormFields( $this, $a );
487 $fields[
'Target'][
'default'] = (string)$this->target;
489 if ( $this->target ) {
490 $status = $this->blockUtils->validateTarget( $this->target );
491 if ( !$status->isOK() ) {
492 $errors = $status->getMessages(
'error' );
493 $this->preErrors = array_merge( $this->preErrors, $errors );
498 $fields[
'PreviousTarget'][
'default'] = (string)$this->target;
500 $block = $this->blockStore->newFromTarget( $this->target );
505 && ( $this->type != DatabaseBlock::TYPE_RANGE
506 || ( $this->target && $block->isBlocking( $this->target ) ) )
508 $fields[
'HardBlock'][
'default'] = $block->isHardblock();
509 $fields[
'CreateAccount'][
'default'] = $block->isCreateAccountBlocked();
510 $fields[
'AutoBlock'][
'default'] = $block->isAutoblocking();
512 if ( isset( $fields[
'DisableEmail'] ) ) {
513 $fields[
'DisableEmail'][
'default'] = $block->isEmailBlocked();
516 if ( isset( $fields[
'HideUser'] ) ) {
517 $fields[
'HideUser'][
'default'] = $block->getHideName();
520 if ( isset( $fields[
'DisableUTEdit'] ) ) {
521 $fields[
'DisableUTEdit'][
'default'] = !$block->isUsertalkEditAllowed();
526 if ( !$block->getHideName() || $this->
getAuthority()->isAllowed(
'hideuser' ) ) {
527 $fields[
'Reason'][
'default'] = $block->getReasonComment()->text;
529 $fields[
'Reason'][
'default'] =
'';
535 $fields[
'Confirm'][
'type'] =
'check';
540 $fields[
'Confirm'][
'default'] = 1;
543 if ( $block->getExpiry() ==
'infinity' ) {
544 $fields[
'Expiry'][
'default'] =
'infinite';
546 $fields[
'Expiry'][
'default'] =
wfTimestamp( TS_RFC2822, $block->getExpiry() );
549 if ( !$block->isSitewide() ) {
550 $fields[
'EditingRestriction'][
'default'] =
'partial';
552 $pageRestrictions = [];
553 $namespaceRestrictions = [];
554 foreach ( $block->getRestrictions() as $restriction ) {
556 $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
558 $this->namespaceInfo->exists( $restriction->getValue() )
560 $namespaceRestrictions[] = $restriction->getValue();
565 sort( $pageRestrictions );
566 $fields[
'PageRestrictions'][
'default'] = implode(
"\n", $pageRestrictions );
567 sort( $namespaceRestrictions );
568 $fields[
'NamespaceRestrictions'][
'default'] = implode(
"\n", $namespaceRestrictions );
571 $actionRestrictions = [];
572 foreach ( $block->getRestrictions() as $restriction ) {
574 $actionRestrictions[] = $restriction->getValue();
577 $fields[
'ActionRestrictions'][
'default'] = $actionRestrictions;
581 $this->alreadyBlocked =
true;
582 $this->preErrors[] = $this->
msg(
'ipb-needreblock',
wfEscapeWikiText( $block->getTargetName() ) );
585 if ( $this->alreadyBlocked || $this->
getRequest()->wasPosted()
586 || $this->
getRequest()->getCheck(
'wpCreateAccount' )
588 $this->
getOutput()->addJsConfigVars(
'wgCreateAccountDirty',
true );
592 if ( $this->requestedHideUser ) {
593 $fields[
'Confirm'][
'type'] =
'check';
594 unset( $fields[
'Confirm'][
'default'] );
595 $this->preErrors[] = $this->
msg(
'ipb-confirmhideuser',
'ipb-confirmaction' );
600 $fields[
'Confirm'][
'type'] =
'check';
601 unset( $fields[
'Confirm'][
'default'] );
602 $this->preErrors[] = $this->
msg(
'ipb-blockingself',
'ipb-confirmaction' );
611 $this->
getOutput()->addModuleStyles( [
'mediawiki.special' ] );
612 $this->
getOutput()->addModules( [
'mediawiki.special.block' ] );
615 $text = $this->
msg(
'blockiptext', $blockCIDRLimit[
'IPv4'], $blockCIDRLimit[
'IPv6'] )->parse();
617 $otherBlockMessages = [];
618 if ( $this->target !==
null ) {
621 $targetName = $this->target->
getName();
625 $otherBlockMessages, $targetName );
627 if ( count( $otherBlockMessages ) ) {
628 $s = Html::rawElement(
631 $this->
msg(
'ipb-otherblocks-header', count( $otherBlockMessages ) )->parse()
636 foreach ( $otherBlockMessages as $link ) {
637 $list .= Html::rawElement(
'li', [], $link ) .
"\n";
640 $s .= Html::rawElement(
642 [
'class' =>
'mw-blockip-alreadyblocked' ],
660 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
666 $links[] = $linkRenderer->makeLink(
668 $this->
msg(
'ipb-blocklist-contribs', $this->target->getName() )->text()
674 $message = $this->
msg(
680 $message = $this->
msg(
'ipb-unblock' )->parse();
683 $links[] = $linkRenderer->makeKnownLink(
689 $links[] = $linkRenderer->makeKnownLink(
691 $this->
msg(
'ipb-blocklist' )->text()
695 if ( $this->
getAuthority()->isAllowed(
'editinterface' ) ) {
696 $links[] = $linkRenderer->makeKnownLink(
697 $this->
msg(
'ipbreason-dropdown' )->inContentLanguage()->
getTitle(),
698 $this->
msg(
'ipb-edit-dropdown' )->text(),
700 [
'action' =>
'edit' ]
704 $text = Html::rawElement(
706 [
'class' =>
'mw-ipb-conveniencelinks' ],
715 LogEventsList::showLogExtract(
724 $this->titleFormatter->getText( $userPage ),
726 'showIfEmpty' =>
false
732 if ( $this->
getAuthority()->isAllowed(
'suppressionlog' ) ) {
733 LogEventsList::showLogExtract(
740 'conds' => [
'log_action' => [
'block',
'reblock',
'unblock' ] ],
742 'blocklog-showsuppresslog',
743 $this->titleFormatter->getText( $userPage ),
745 'showIfEmpty' =>
false
785 private static function getTargetAndTypeInternal( ?
string $par, WebRequest $request =
null ) {
786 if ( !$request instanceof WebRequest ) {
791 $request->getVal(
'wpTarget',
null ),
793 $request->getVal(
'ip',
null ),
795 $request->getVal(
'wpBlockAddress',
null ),
797 foreach ( $possibleTargets as $possibleTarget ) {
800 ->parseBlockTarget( $possibleTarget );
802 if ( $targetAndType[ 1 ] !==
null ) {
806 return $targetAndType;
819 return self::processFormInternal(
822 $services->getBlockUserFactory(),
823 $services->getBlockUtils()
837 private static function processFormInternal(
847 $isPartialBlock = isset( $data[
'EditingRestriction'] ) &&
848 $data[
'EditingRestriction'] ===
'partial';
852 $data[
'Confirm'] = !in_array( $data[
'Confirm'], [
'',
'0',
null,
false ],
true );
856 if ( !isset( $data[
'HideUser'] ) ) {
857 $data[
'HideUser'] =
false;
862 if ( $type == DatabaseBlock::TYPE_USER ) {
863 $target = $target->getName();
872 if ( $target === $performer->
getUser()->getName() &&
873 ( $data[
'PreviousTarget'] !== $target || !$data[
'Confirm'] )
875 return [
'ipb-blockingself',
'ipb-confirmaction' ];
878 if ( $data[
'HideUser'] && !$data[
'Confirm'] ) {
879 return [
'ipb-confirmhideuser',
'ipb-confirmaction' ];
881 } elseif ( $type == DatabaseBlock::TYPE_IP ) {
882 $target = $target->getName();
883 } elseif ( $type != DatabaseBlock::TYPE_RANGE ) {
885 return [
'badipaddress' ];
890 $blockReason = $data[
'Reason'][0] ??
'';
892 $pageRestrictions = [];
893 $namespaceRestrictions = [];
894 $actionRestrictions = [];
895 if ( $isPartialBlock ) {
896 if ( isset( $data[
'PageRestrictions'] ) && $data[
'PageRestrictions'] !==
'' ) {
897 $titles = explode(
"\n", $data[
'PageRestrictions'] );
898 foreach ( $titles as $title ) {
899 $pageRestrictions[] = PageRestriction::newFromTitle( $title );
902 if ( isset( $data[
'NamespaceRestrictions'] ) && $data[
'NamespaceRestrictions'] !==
'' ) {
903 $namespaceRestrictions = array_map(
static function ( $id ) {
904 return new NamespaceRestriction( 0, (
int)$id );
905 }, explode(
"\n", $data[
'NamespaceRestrictions'] ) );
908 $enablePartialActionBlocks &&
909 isset( $data[
'ActionRestrictions'] ) &&
910 $data[
'ActionRestrictions'] !==
''
912 $actionRestrictions = array_map(
static function ( $id ) {
913 return new ActionRestriction( 0, $id );
914 }, $data[
'ActionRestrictions'] );
917 $restrictions = array_merge( $pageRestrictions, $namespaceRestrictions, $actionRestrictions );
919 if ( !isset( $data[
'Tags'] ) ) {
924 'isCreateAccountBlocked' => $data[
'CreateAccount'],
925 'isHardBlock' => $data[
'HardBlock'],
926 'isAutoblocking' => $data[
'AutoBlock'],
927 'isHideUser' => $data[
'HideUser'],
928 'isPartial' => $isPartialBlock,
931 if ( isset( $data[
'DisableUTEdit'] ) ) {
932 $blockOptions[
'isUserTalkEditBlocked'] = $data[
'DisableUTEdit'];
934 if ( isset( $data[
'DisableEmail'] ) ) {
935 $blockOptions[
'isEmailBlocked'] = $data[
'DisableEmail'];
950 $blockNotConfirmed = !$data[
'Confirm'] || ( array_key_exists(
'PreviousTarget', $data )
951 && $data[
'PreviousTarget'] !== $target );
954 $reblockNotAllowed = ( array_key_exists(
'Reblock', $data ) && !$data[
'Reblock'] );
956 $doReblock = !$blockNotConfirmed && !$reblockNotAllowed;
958 $status = $blockUser->placeBlock( $doReblock );
959 if ( !$status->isOK() ) {
965 $type != DatabaseBlock::TYPE_RANGE
970 && array_key_exists(
'Watch', $data )
975 Title::makeTitle(
NS_USER, $target )
995 return $lang->getBlockDurations( $includeOther );
1020 ->getBlockPermissionCheckerFactory()
1021 ->newBlockPermissionChecker(
null, User::newFromIdentity( $user ) )
1022 ->checkEmailPermissions();
1032 return self::processFormInternal(
1035 $this->blockUserFactory,
1045 $out = $this->getOutput();
1046 $out->setPageTitleMsg( $this->msg(
'blockipsuccesssub' ) );
1047 $out->addWikiMsg(
'blockipsuccesstext',
wfEscapeWikiText( $this->target ) );
1059 $search = $this->userNameUtils->getCanonical( $search );
1065 return $this->userNamePrefixSearch
1066 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
1075class_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.
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 UseCodexSpecialBlock
Name constant for the UseCodexSpecialBlock setting, for use with Config::get()
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.