Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4079606
SpecialMassGlobalBlock.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
SpecialMassGlobalBlock.php
View Options
<?php
namespace
MediaWiki\Extension\GlobalBlocking\Special
;
use
MediaWiki\CommentStore\CommentStore
;
use
MediaWiki\Exception\UserBlockedError
;
use
MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockingConnectionProvider
;
use
MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockingExpirySelectorBuilder
;
use
MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockingGlobalBlockDetailsRenderer
;
use
MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockingLinkBuilder
;
use
MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockLookup
;
use
MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockManager
;
use
MediaWiki\Html\Html
;
use
MediaWiki\HTMLForm\HTMLForm
;
use
MediaWiki\Linker\Linker
;
use
MediaWiki\Message\Message
;
use
MediaWiki\Permissions\PermissionManager
;
use
MediaWiki\SpecialPage\SpecialPage
;
use
MediaWiki\User\UserIdentityLookup
;
use
Wikimedia\IPUtils
;
use
Wikimedia\ScopedCallback
;
class
SpecialMassGlobalBlock
extends
SpecialPage
{
private
array
$targetsForLookup
;
private
array
$targets
;
private
PermissionManager
$permissionManager
;
private
UserIdentityLookup
$userIdentityLookup
;
private
GlobalBlockManager
$globalBlockManager
;
private
GlobalBlockLookup
$globalBlockLookup
;
private
GlobalBlockingLinkBuilder
$globalBlockingLinkBuilder
;
private
GlobalBlockingGlobalBlockDetailsRenderer
$globalBlockDetailsRenderer
;
private
GlobalBlockingConnectionProvider
$globalBlockingConnectionProvider
;
private
GlobalBlockingExpirySelectorBuilder
$globalBlockingExpirySelectorBuilder
;
public
function
__construct
(
PermissionManager
$permissionManager
,
UserIdentityLookup
$userIdentityLookup
,
GlobalBlockManager
$globalBlockManager
,
GlobalBlockLookup
$globalBlockLookup
,
GlobalBlockingLinkBuilder
$globalBlockingLinkBuilder
,
GlobalBlockingGlobalBlockDetailsRenderer
$globalBlockDetailsRenderer
,
GlobalBlockingConnectionProvider
$globalBlockingConnectionProvider
,
GlobalBlockingExpirySelectorBuilder
$globalBlockingExpirySelectorBuilder
)
{
parent
::
__construct
(
'MassGlobalBlock'
,
'globalblock'
);
$this
->
permissionManager
=
$permissionManager
;
$this
->
userIdentityLookup
=
$userIdentityLookup
;
$this
->
globalBlockManager
=
$globalBlockManager
;
$this
->
globalBlockLookup
=
$globalBlockLookup
;
$this
->
globalBlockingLinkBuilder
=
$globalBlockingLinkBuilder
;
$this
->
globalBlockDetailsRenderer
=
$globalBlockDetailsRenderer
;
$this
->
globalBlockingConnectionProvider
=
$globalBlockingConnectionProvider
;
$this
->
globalBlockingExpirySelectorBuilder
=
$globalBlockingExpirySelectorBuilder
;
}
/**
* @inheritDoc
* @codeCoverageIgnore Merely declarative
*/
public
function
doesWrites
():
bool
{
return
true
;
}
/**
* @inheritDoc
* @codeCoverageIgnore Merely declarative
*/
protected
function
getGroupName
()
{
return
'users'
;
}
/** @inheritDoc */
public
function
execute
(
$subPage
)
{
$this
->
checkReadOnly
();
parent
::
execute
(
$subPage
);
// Don't allow sitewide blocked users to use the form, to be consistent with Special:GlobalBlock.
$block
=
$this
->
getUser
()->
getBlock
();
if
(
$block
&&
$block
->
isSitewide
()
)
{
throw
new
UserBlockedError
(
$block
);
}
$this
->
addHelpLink
(
'Extension:GlobalBlocking'
);
$out
=
$this
->
getOutput
();
$out
->
addModules
(
'ext.globalBlocking'
);
$out
->
addModuleStyles
(
'ext.globalBlocking.styles'
);
$out
->
setSubtitle
(
$this
->
globalBlockingLinkBuilder
->
buildSubtitleLinks
(
$this
)
);
$request
=
$this
->
getRequest
();
// Parse the list of targets provided and store them for later use in ::createTable.
$targetsAsString
=
$request
->
getText
(
'wpTargets'
);
if
(
$targetsAsString
)
{
// We want to remove empty strings and duplicates, to avoid globally blocking the same user twice.
$targets
=
explode
(
"
\n
"
,
$targetsAsString
);
$targets
=
array_map
(
'trim'
,
$targets
);
$this
->
targetsForLookup
=
array_unique
(
array_filter
(
$targets
)
);
}
else
{
$this
->
targetsForLookup
=
[];
}
$this
->
targets
=
$request
->
getArray
(
'wpActionTarget'
,
[]
);
$blockFormAlsoShown
=
false
;
if
(
$request
->
wasPosted
()
)
{
$method
=
$request
->
getRawVal
(
'wpMethod'
)
??
''
;
if
(
$method
===
'search'
&&
count
(
$this
->
targetsForLookup
)
)
{
$this
->
showBlockForm
();
$blockFormAlsoShown
=
true
;
}
elseif
(
$method
===
'block'
)
{
$this
->
performGlobalBlockChanges
();
$this
->
showBlockForm
();
$blockFormAlsoShown
=
true
;
}
}
$this
->
showSearchForm
(
$blockFormAlsoShown
);
}
/**
* Adds to the output the form that allows a user to search for targets to globally block or unblock.
*
* @return void
*/
private
function
showSearchForm
(
bool
$blockFormAlsoShown
)
{
// The submit button is not the primary button if the block form is also shown.
$submitFlags
=
[
'progressive'
];
if
(
!
$blockFormAlsoShown
)
{
$submitFlags
[]
=
'primary'
;
}
$fields
=
[
'Targets'
=>
[
'type'
=>
'textarea'
,
'dir'
=>
'ltr'
,
'rows'
=>
20
,
'id'
=>
'mw-globalblock-addresslist'
,
'required'
=>
true
,
'autofocus'
=>
true
,
'placeholder'
=>
$this
->
msg
(
'globalblocking-mass-block-query-placeholder'
)->
text
(),
'default'
=>
$this
->
getRequest
()->
getText
(
'wpTargets'
),
],
'Method'
=>
[
'type'
=>
'hidden'
,
'default'
=>
'search'
,
],
'Submit'
=>
[
'type'
=>
'submit'
,
'buttonlabel-message'
=>
'globalblocking-mass-block-query-submit'
,
'id'
=>
'mw-globalblocking-mass-block-query-submit'
,
'name'
=>
'mw-globalblocking-mass-block-query-submit'
,
'flags'
=>
$submitFlags
,
],
];
HTMLForm
::
factory
(
'ooui'
,
$fields
,
$this
->
getContext
()
)
->
setWrapperLegendMsg
(
'globalblocking-mass-block-query-legend'
)
->
setId
(
'mw-globalblocking-mass-block-query'
)
->
suppressDefaultSubmit
()
->
setFormIdentifier
(
'mw-globalblocking-mass-block-query'
)
->
prepareForm
()
->
displayForm
(
false
);
}
/**
* Adds to the output the form that allows a user to perform the mass global blocks or unblocks.
*
* @return void
*/
private
function
showBlockForm
()
{
$getExpiry
=
$this
->
globalBlockingExpirySelectorBuilder
->
buildExpirySelector
(
$this
->
getContext
()
);
$fields
=
[
'Action'
=>
[
'type'
=>
'radio'
,
'default'
=>
'block'
,
'options-messages'
=>
[
'globalblocking-mass-block-block'
=>
'block'
,
'globalblocking-mass-block-unblock'
=>
'unblock'
,
]
],
'Expiry'
=>
[
'type'
=>
count
(
$getExpiry
)
?
'selectorother'
:
'text'
,
'label-message'
=>
'globalblocking-block-expiry'
,
'id'
=>
'mw-globalblocking-mass-block-expiry-selector'
,
'required'
=>
false
,
'options'
=>
$getExpiry
,
'other'
=>
$this
->
msg
(
'globalblocking-block-expiry-selector-other'
)->
text
(),
'hide-if'
=>
[
'!=='
,
'Action'
,
'block'
],
],
'Reason'
=>
[
'type'
=>
'selectandother'
,
'maxlength'
=>
CommentStore
::
COMMENT_CHARACTER_LIMIT
,
'label-message'
=>
'globalblocking-block-reason'
,
'id'
=>
'mw-globalblocking-mass-block-reason'
,
'options-message'
=>
'globalblocking-block-reason-dropdown'
,
],
'AnonOnly'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-ipbanononly'
,
'id'
=>
'mw-globalblocking-mass-block-anon-only'
,
'hide-if'
=>
[
'!=='
,
'Action'
,
'block'
],
],
'CreateAccount'
=>
[
'type'
=>
'check'
,
'id'
=>
'mw-globalblocking-mass-block-disable-account-creation'
,
'label-message'
=>
'globalblocking-block-disable-account-creation'
,
'default'
=>
true
,
'hide-if'
=>
[
'!=='
,
'Action'
,
'block'
],
],
'AutoBlock'
=>
[
'type'
=>
'check'
,
'label-message'
=>
[
'globalblocking-block-enable-autoblock'
,
Message
::
numParam
(
$this
->
getConfig
()->
get
(
'GlobalBlockingMaximumIPsToRetroactivelyAutoblock'
)
),
Message
::
durationParam
(
$this
->
getConfig
()->
get
(
'GlobalBlockingAutoblockExpiry'
)
),
],
'id'
=>
'mw-globalblocking-mass-block-enable-autoblock'
,
'default'
=>
true
,
'hide-if'
=>
[
'!=='
,
'Action'
,
'block'
],
],
];
if
(
$this
->
getUser
()->
isAllowed
(
'block'
)
)
{
$fields
+=
[
'AlsoLocal'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-also-local'
,
'id'
=>
'mw-globalblocking-mass-block-local'
,
'hide-if'
=>
[
'!=='
,
'Action'
,
'block'
],
],
'AlsoLocalTalk'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-also-local-talk'
,
'id'
=>
'mw-globalblocking-mass-block-local-talk'
,
'hide-if'
=>
[
'OR'
,
[
'!=='
,
'Action'
,
'block'
],
[
'!=='
,
'AlsoLocal'
,
'1'
]
],
],
'AlsoLocalEmail'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-also-local-email'
,
'id'
=>
'mw-globalblocking-mass-block-local-email'
,
'hide-if'
=>
[
'OR'
,
[
'!=='
,
'Action'
,
'block'
],
[
'!=='
,
'AlsoLocal'
,
'1'
]
],
],
'AlsoLocalSoft'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-also-local-soft'
,
'id'
=>
'mw-globalblocking-mass-block-local-soft'
,
'hide-if'
=>
[
'OR'
,
[
'!=='
,
'Action'
,
'block'
],
[
'!=='
,
'AlsoLocal'
,
'1'
]
],
'default'
=>
true
,
],
'AlsoLocalAccountCreation'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-also-local-disable-account-creation'
,
'id'
=>
'mw-globalblocking-mass-block-local-disable-account-creation'
,
'hide-if'
=>
[
'!=='
,
'AlsoLocal'
,
'1'
],
'default'
=>
true
,
]
];
}
$fields
+=
[
'MarkBot'
=>
[
'type'
=>
'check'
,
'label-message'
=>
'globalblocking-mass-block-bot'
,
'id'
=>
'mw-globalblocking-mass-block-bot'
,
],
'Method'
=>
[
'type'
=>
'hidden'
,
'default'
=>
'block'
,
],
'Targets'
=>
[
'type'
=>
'hidden'
,
'default'
=>
implode
(
"
\n
"
,
$this
->
targetsForLookup
),
],
];
$form
=
HTMLForm
::
factory
(
'ooui'
,
$fields
,
$this
->
getContext
()
);
$form
->
setMethod
()
->
setWrapperLegendMsg
(
'globalblocking-mass-block-legend'
)
->
setId
(
'mw-globalblocking-mass-block-form'
)
->
setSubmitID
(
'mw-globalblocking-mass-block-submit'
)
->
setSubmitName
(
'mw-globalblocking-mass-block-submit'
)
->
setSubmitDestructive
()
->
setFormIdentifier
(
'mw-globalblocking-mass-block'
)
->
addHeaderHtml
(
$this
->
createTable
()
)
->
prepareForm
()
->
displayForm
(
false
);
}
/**
* Creates the HTML of the table that shows information about the IPs, IP ranges, or accounts that the
* user may choose to globally block or unblock.
*
* @return string HTML element of the table
*/
private
function
createTable
():
string
{
$out
=
$this
->
getOutput
();
$out
->
addModuleStyles
(
'jquery.tablesorter.styles'
);
$out
->
addModules
(
'jquery.tablesorter'
);
$tableHeadings
=
[
Html
::
element
(
'th'
,
[
'class'
=>
'unsortable'
]
),
Html
::
element
(
'th'
,
[],
$this
->
msg
(
'globalblocking-list-table-heading-target'
)->
text
()
),
Html
::
element
(
'th'
,
[],
$this
->
msg
(
'globalblocking-mass-block-header-status'
)->
text
()
),
Html
::
element
(
'th'
,
[],
$this
->
msg
(
'globalblocking-list-table-heading-expiry'
)->
text
()
),
Html
::
element
(
'th'
,
[],
$this
->
msg
(
'globalblocking-list-table-heading-params'
)->
text
()
),
];
$tableHeaderHtml
=
Html
::
rawElement
(
'thead'
,
[],
Html
::
rawElement
(
'tr'
,
[],
implode
(
"
\n
"
,
$tableHeadings
)
)
);
$tableRows
=
[];
foreach
(
$this
->
targetsForLookup
as
$target
)
{
$tableRows
[]
=
$this
->
createTableRow
(
$target
);
}
$tableBodyHtml
=
Html
::
rawElement
(
'tbody'
,
[],
implode
(
"
\n
"
,
$tableRows
)
);
return
Html
::
rawElement
(
'table'
,
[
'class'
=>
'wikitable sortable'
,
'id'
=>
'mw-globalblocking-mass-block-table'
],
$tableHeaderHtml
.
$tableBodyHtml
);
}
/**
* Creates each row of IPs, with the info on whether it's blocked,
* and the block info if relevant.
*
* @param string $target Target which has not yet been validated.
* @return string HTML element of the row
*/
private
function
createTableRow
(
string
$target
):
string
{
$targetValidationStatus
=
$this
->
globalBlockManager
->
validateGlobalBlockTarget
(
$target
,
$this
->
getUser
()
);
if
(
!
$targetValidationStatus
->
isGood
()
)
{
return
Html
::
rawElement
(
'tr'
,
[],
Html
::
element
(
'td'
,
[
'colspan'
=>
5
,
'data-mw-globalblocking-target'
=>
$target
],
$this
->
msg
(
$targetValidationStatus
->
getMessages
()[
0
]
)->
text
()
)
);
}
$targetData
=
$targetValidationStatus
->
getValue
();
$globalBlockId
=
GlobalBlockLookup
::
isAGlobalBlockId
(
$target
);
if
(
!
$globalBlockId
)
{
$globalBlockId
=
$this
->
globalBlockLookup
->
getGlobalBlockId
(
$targetData
[
'targetForLookup'
]
);
}
$dbr
=
$this
->
globalBlockingConnectionProvider
->
getReplicaGlobalBlockingDatabase
();
$globalBlockRow
=
$dbr
->
newSelectQueryBuilder
()
->
select
(
GlobalBlockLookup
::
selectFields
()
)
->
from
(
'globalblocks'
)
->
where
(
[
'gb_id'
=>
$globalBlockId
]
)
->
caller
(
__METHOD__
)
->
fetchRow
();
// Make the checkbox checked if wpActionTargets has no items (which means on the first load
// all users will be selected), or select the targets which are in wpActionTargets to persist
// the checked state of the targets between attempts to submit.
$shouldTargetCheckboxBeChecked
=
!
count
(
$this
->
targets
)
||
in_array
(
$targetData
[
'targetForDisplay'
],
$this
->
targets
);
$checkboxAttribs
=
[];
if
(
$shouldTargetCheckboxBeChecked
)
{
$checkboxAttribs
[
'checked'
]
=
'checked'
;
}
$row
=
[
Html
::
rawElement
(
'td'
,
[],
Html
::
input
(
"wpActionTarget[]"
,
$target
,
'checkbox'
,
$checkboxAttribs
)
),
Html
::
rawElement
(
'td'
,
[],
$this
->
buildTargetForDisplay
(
$targetData
[
'targetForDisplay'
]
)
),
];
if
(
$globalBlockRow
)
{
$row
[]
=
Html
::
rawElement
(
'td'
,
[],
$this
->
getLinkRenderer
()->
makeKnownLink
(
SpecialPage
::
getTitleFor
(
'GlobalBlockList'
),
$this
->
msg
(
'globalblocking-mass-block-blocked'
)->
text
(),
[],
[
'target'
=>
"#{$globalBlockRow->gb_id}"
],
)
);
$row
[]
=
Html
::
rawElement
(
'td'
,
[],
$this
->
getLanguage
()->
formatExpiry
(
$globalBlockRow
->
gb_expiry
)
);
$options
=
$this
->
globalBlockDetailsRenderer
->
getBlockOptionsForDisplay
(
$globalBlockRow
,
$this
->
getContext
()
);
$optionsAsText
=
''
;
if
(
count
(
$options
)
)
{
$optionsAsText
=
$this
->
getLanguage
()->
commaList
(
$options
);
}
$row
[]
=
Html
::
rawElement
(
'td'
,
[],
$optionsAsText
);
}
else
{
$row
[]
=
Html
::
element
(
'td'
,
[],
$this
->
msg
(
'globalblocking-mass-block-not-blocked'
)->
text
()
);
$row
[]
=
Html
::
element
(
'td'
);
// @phan-suppress-next-line PhanPluginDuplicateAdjacentStatement
$row
[]
=
Html
::
element
(
'td'
);
}
return
Html
::
rawElement
(
'tr'
,
[
'data-mw-globalblocking-target'
=>
$targetData
[
'targetForDisplay'
]
],
implode
(
"
\n
"
,
$row
)
);
}
/**
* Builds the HTML used in the 'Target' column for a given $target username.
*
* @param string $target Can be an IP, IP range, username, or global block ID.
* @return string HTML
*/
private
function
buildTargetForDisplay
(
string
$target
):
string
{
$globalBlockId
=
GlobalBlockLookup
::
isAGlobalBlockId
(
$target
);
if
(
$globalBlockId
)
{
return
$this
->
msg
(
'globalblocking-global-block-id'
,
$globalBlockId
)->
text
();
}
$targetUserIdentity
=
$this
->
userIdentityLookup
->
getUserIdentityByName
(
$target
);
if
(
$targetUserIdentity
)
{
$targetUserId
=
$targetUserIdentity
->
getId
();
}
else
{
$targetUserId
=
0
;
}
return
Linker
::
userLink
(
$targetUserId
,
$target
);
}
/**
* Actually performs the mass global block or unblock on the selected targets.
*
* @return void
*/
private
function
performGlobalBlockChanges
()
{
// Check that the CSRF token is as expected.
if
(
!
$this
->
getContext
()->
getCsrfTokenSet
()->
matchTokenField
()
)
{
$this
->
getOutput
()->
addHTML
(
Html
::
errorBox
(
$this
->
msg
(
'globalblocking-mass-block-token-mismatch'
)->
parse
()
)
);
return
;
}
// If there are no targets to block, then return as we have nothing to do here.
if
(
!
count
(
$this
->
targets
)
)
{
return
;
}
// If we are blocking or unblocking too many targets at once, then show an error.
$request
=
$this
->
getRequest
();
$action
=
$request
->
getRawVal
(
'wpAction'
)
??
'block'
;
$maxTargets
=
$this
->
getConfig
()->
get
(
'GlobalBlockingMassGlobalBlockMaxTargets'
);
if
(
$maxTargets
<
count
(
$this
->
targets
)
)
{
// Generates:
// * globalblocking-mass-block-too-many-targets-to-block
// * globalblocking-mass-block-too-many-targets-to-unblock
$msgKey
=
'globalblocking-mass-block-too-many-targets-'
;
if
(
$action
===
'block'
)
{
$msgKey
.=
'to-block'
;
}
else
{
$msgKey
.=
'to-unblock'
;
}
$this
->
getOutput
()->
addHTML
(
Html
::
errorBox
(
$this
->
msg
(
$msgKey
,
$maxTargets
)->
parse
()
)
);
return
;
}
$performer
=
$this
->
getUser
();
$globalSuccess
=
[];
$globalFailure
=
[];
$localSuccess
=
[];
$localFailure
=
[];
// Make the user have the 'bot' right for the duration of this method if wpMarkBot is set.
if
(
$request
->
getCheck
(
'wpMarkBot'
)
)
{
$temporaryUserRightsScope
=
$this
->
permissionManager
->
addTemporaryUserRights
(
$performer
,
'bot'
);
}
// Construct the reason to use for the global blocks, unblocks, and/or local blocks
$reason
=
$request
->
getText
(
'wpReason'
);
$reasonDetail
=
$request
->
getText
(
'wpReason-other'
);
if
(
$reason
===
'other'
)
{
$reason
=
$reasonDetail
;
}
elseif
(
$reasonDetail
)
{
$reason
.=
$this
->
msg
(
'colon-separator'
)->
inContentLanguage
()->
text
()
.
$reasonDetail
;
}
if
(
$action
===
'block'
)
{
foreach
(
$this
->
targets
as
$target
)
{
// Validate that the target is valid for a global block. This also gets the type of target if
// this succeeds.
$targetDataStatus
=
$this
->
globalBlockManager
->
validateGlobalBlockTarget
(
$target
,
$performer
);
if
(
!
$targetDataStatus
->
isGood
()
)
{
$globalFailure
[]
=
$target
;
if
(
$request
->
getCheck
(
'wpAlsoLocal'
)
)
{
$localFailure
[]
=
$target
;
}
continue
;
}
$targetData
=
$targetDataStatus
->
getValue
();
// Generate the global block options based on the form submission and also whether the option is
// relevant for the given $target.
$options
=
[
'modify'
];
if
(
$request
->
getCheck
(
'wpAnonOnly'
)
&&
IPUtils
::
isIPAddress
(
$targetData
[
'target'
]
)
)
{
$options
[]
=
'anon-only'
;
}
if
(
!
$request
->
getCheck
(
'wpCreateAccount'
)
)
{
$options
[]
=
'allow-account-creation'
;
}
if
(
$request
->
getCheck
(
'wpAutoBlock'
)
&&
$targetData
[
'targetCentralId'
]
!==
0
)
{
$options
[]
=
'enable-autoblock'
;
}
$alsoLocal
=
$request
->
getCheck
(
'wpAlsoLocal'
);
if
(
$alsoLocal
)
{
$localOptions
=
[
'isCreateAccountBlocked'
=>
$request
->
getCheck
(
'wpAlsoLocalAccountCreation'
),
'isEmailBlocked'
=>
$request
->
getCheck
(
'wpAlsoLocalEmail'
),
'isUserTalkEditBlocked'
=>
$request
->
getCheck
(
'wpAlsoLocalTalk'
),
'isHardBlock'
=>
!
$request
->
getCheck
(
'wpAlsoLocalSoft'
),
'isAutoblocking'
=>
true
,
];
}
else
{
$localOptions
=
null
;
}
$globalBlockStatus
=
$this
->
globalBlockManager
->
block
(
$target
,
$reason
,
$request
->
getVal
(
'wpExpiry'
),
$performer
,
$options
,
$localOptions
);
if
(
$globalBlockStatus
->
isGlobalBlockOK
()
)
{
$globalSuccess
[]
=
$target
;
}
else
{
$globalFailure
[]
=
$target
;
}
if
(
$alsoLocal
)
{
if
(
$globalBlockStatus
->
isLocalBlockOK
()
)
{
$localSuccess
[]
=
$target
;
}
else
{
$localFailure
[]
=
$target
;
}
}
}
$this
->
showSuccessBox
(
$globalSuccess
,
'globalblocking-mass-block-success-block'
);
$this
->
showSuccessBox
(
$localSuccess
,
'globalblocking-mass-block-success-local'
);
$this
->
showErrorBox
(
$globalFailure
,
'globalblocking-mass-block-failure-block'
);
$this
->
showErrorBox
(
$localFailure
,
'globalblocking-mass-block-failure-local'
);
}
elseif
(
$action
===
'unblock'
)
{
foreach
(
$this
->
targets
as
$target
)
{
$globalUnblockStatus
=
$this
->
globalBlockManager
->
unblock
(
$target
,
$reason
,
$performer
);
if
(
$globalUnblockStatus
->
isOK
()
)
{
$globalSuccess
[]
=
$target
;
}
else
{
$globalFailure
[]
=
$target
;
}
}
$this
->
showSuccessBox
(
$globalSuccess
,
'globalblocking-mass-block-success-unblock'
);
$this
->
showErrorBox
(
$globalFailure
,
'globalblocking-mass-block-failure-unblock'
);
}
ScopedCallback
::
consume
(
$temporaryUserRightsScope
);
}
/**
* Adds a success box to the output to indicate targets that were successfully globally blocked, locally blocked,
* or globally unblocked
*
* @param array $relevantTargets The array of targets (usernames, IPs, global block IDs) that were successfully
* blocked/unblocked. If the array is empty, then no box is added.
* @param string $messageKey The message key to use for the success box
* @return void
*/
private
function
showSuccessBox
(
array
$relevantTargets
,
string
$messageKey
)
{
if
(
count
(
$relevantTargets
)
)
{
$relevantTargetsAsString
=
implode
(
$this
->
msg
(
'comma-separator'
)->
escaped
(),
$relevantTargets
);
$this
->
getOutput
()->
addHTML
(
Html
::
successBox
(
$this
->
msg
(
$messageKey
,
$relevantTargetsAsString
)->
parse
()
)
);
}
}
/**
* Adds a error box to the output to indicate targets that were failed to be globally blocked, locally blocked,
* or globally unblocked
*
* @param array $relevantTargets The array of targets (usernames, IPs, global block IDs) that were failed to
* be blocked/unblocked. If the array is empty, then no box is added.
* @param string $messageKey The message key to use for the error box
* @return void
*/
private
function
showErrorBox
(
array
$relevantTargets
,
string
$messageKey
)
{
if
(
count
(
$relevantTargets
)
)
{
$relevantTargetsAsString
=
implode
(
$this
->
msg
(
'comma-separator'
)->
escaped
(),
$relevantTargets
);
$this
->
getOutput
()->
addHTML
(
Html
::
errorBox
(
$this
->
msg
(
$messageKey
,
$relevantTargetsAsString
)->
parse
()
)
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Aug 18 2026, 05:04 (8 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
75/ab/0e8ed3af5a5a30e21dd831362a53
Default Alt Text
SpecialMassGlobalBlock.php (21 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment