44 use Wikimedia\IPUtils;
58 private $blockPermissionCheckerFactory;
61 private $blockUserFactory;
64 private $userNameUtils;
67 private $userNamePrefixSearch;
70 private $blockActionInfo;
73 private $titleFormatter;
99 private $namespaceInfo;
121 parent::__construct(
'Block',
'block' );
123 $this->blockUtils = $blockUtils;
124 $this->blockPermissionCheckerFactory = $blockPermissionCheckerFactory;
125 $this->blockUserFactory = $blockUserFactory;
126 $this->userNameUtils = $userNameUtils;
127 $this->userNamePrefixSearch = $userNamePrefixSearch;
128 $this->blockActionInfo = $blockActionInfo;
129 $this->titleFormatter = $titleFormatter;
130 $this->namespaceInfo = $namespaceInfo;
144 parent::checkExecutePermissions( $user );
145 # T17810: blocked admins should have limited access here
146 $status = $this->blockPermissionCheckerFactory
147 ->newBlockPermissionChecker( $this->target, $user )
148 ->checkBlockPermissions();
149 if ( $status !==
true ) {
169 # Extract variables from the request. Try not to get into a situation where we
170 # need to extract *every* variable from the form just for processing here, but
171 # there are legitimate uses for some variables
175 # Set the 'relevant user' in the skin, so it displays links like Contributions,
176 # User logs, UserRights, etc.
177 $this->
getSkin()->setRelevantUser( $this->target );
181 ->parseBlockTarget( $request->getVal(
'wpPreviousTarget' ) );
182 $this->requestedHideUser = $request->getBool(
'wpHideUser' );
194 $msg = $this->alreadyBlocked ?
'ipb-change-block' :
'ipbsubmit';
199 # Don't need to do anything if the form has been posted
200 if ( !$this->
getRequest()->wasPosted() && $this->preErrors ) {
201 # Mimic error messages normally generated by the form
203 new OOUI\Widget( [] ),
206 'errors' => array_map(
function ( $errMsg ) {
208 return new OOUI\HtmlSnippet( $this->
msg( ...$errMsg )->parse() );
225 $blockAllowsUTEdit = $conf->get( MainConfigNames::BlockAllowsUTEdit );
236 'type' =>
'usersmultiselect',
240 'id' =>
'mw-bi-target',
244 'placeholder' => $this->
msg(
'block-target-placeholder' )->text(),
245 'validation-callback' =>
function ( $value, $alldata, $form ) {
246 $status = $this->blockUtils->validateTarget( $value );
247 if ( !$status->isOK() ) {
248 $errors = $status->getErrorsArray();
250 return $form->msg( ...$errors[0] );
254 'section' =>
'target',
257 $a[
'EditingRestriction'] = [
259 'cssclass' =>
'mw-block-editing-restriction',
260 'default' =>
'sitewide',
262 $this->
msg(
'ipb-sitewide' )->escaped() .
263 new \OOUI\LabelWidget( [
264 'classes' => [
'oo-ui-inline-help' ],
265 'label' =>
new \OOUI\HtmlSnippet( $this->
msg(
'ipb-sitewide-help' )->parse() ),
267 $this->
msg(
'ipb-partial' )->escaped() .
268 new \OOUI\LabelWidget( [
269 'classes' => [
'oo-ui-inline-help' ],
270 'label' => $this->
msg(
'ipb-partial-help' )->text(),
273 'section' =>
'actions',
276 $a[
'PageRestrictions'] = [
277 'type' =>
'titlesmultiselect',
278 'label' => $this->
msg(
'ipb-pages-label' )->text(),
281 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction',
283 'showMissing' =>
false,
284 'excludeDynamicNamespaces' =>
true,
286 'autocomplete' => false
288 'section' =>
'actions',
291 $a[
'NamespaceRestrictions'] = [
292 'type' =>
'namespacesmultiselect',
293 'label' => $this->
msg(
'ipb-namespaces-label' )->text(),
295 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction',
298 'autocomplete' => false
300 'section' =>
'actions',
303 if ( $conf->get( MainConfigNames::EnablePartialActionBlocks ) ) {
304 $blockActions = $this->blockActionInfo->getAllBlockActions();
305 $a[
'ActionRestrictions'] = [
306 'type' =>
'multiselect',
307 'cssclass' =>
'mw-htmlform-checkradio-indent mw-block-partial-restriction mw-block-action-restriction',
308 'options-messages' => array_combine(
309 array_map(
static function ( $action ) {
310 return "ipb-action-$action";
311 }, array_keys( $blockActions ) ),
314 'section' =>
'actions',
318 $a[
'CreateAccount'] = [
320 'cssclass' =>
'mw-block-restriction',
321 'label-message' =>
'ipbcreateaccount',
323 'section' =>
'details',
326 if ( $this->blockPermissionCheckerFactory
327 ->newBlockPermissionChecker(
null, $user )
328 ->checkEmailPermissions()
330 $a[
'DisableEmail'] = [
332 'cssclass' =>
'mw-block-restriction',
333 'label-message' =>
'ipbemailban',
334 'section' =>
'details',
338 if ( $blockAllowsUTEdit ) {
339 $a[
'DisableUTEdit'] = [
341 'cssclass' =>
'mw-block-restriction',
342 'label-message' =>
'ipb-disableusertalk',
344 'section' =>
'details',
348 $defaultExpiry = $this->
msg(
'ipb-default-expiry' )->inContentLanguage();
349 if ( $this->type === DatabaseBlock::TYPE_RANGE || $this->type === DatabaseBlock::TYPE_IP ) {
350 $defaultExpiryIP = $this->
msg(
'ipb-default-expiry-ip' )->inContentLanguage();
351 if ( !$defaultExpiryIP->isDisabled() ) {
352 $defaultExpiry = $defaultExpiryIP;
359 'options' => $suggestedDurations,
360 'default' => $defaultExpiry->text(),
361 'section' =>
'expiry',
365 'type' =>
'selectandother',
369 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
370 'maxlength-unit' =>
'codepoints',
371 'options-message' =>
'ipbreason-dropdown',
372 'section' =>
'reason',
378 'ipbenableautoblock',
382 'section' =>
'options',
385 # Allow some users to hide name from block log, blocklist and listusers
389 'label-message' =>
'ipbhidename',
390 'cssclass' =>
'mw-block-hideuser',
391 'section' =>
'options',
395 # Watchlist their user page? (Only if user is logged in)
396 if ( $user->isRegistered() ) {
399 'label-message' =>
'ipbwatchuser',
400 'section' =>
'options',
406 'label-message' =>
'ipb-hardblock',
408 'section' =>
'options',
411 # This is basically a copy of the Target field, but the user can't change it, so we
412 # can see if the warnings we maybe showed to the user before still apply
413 $a[
'PreviousTarget'] = [
418 # We'll turn this into a checkbox if we need to
422 'label-message' =>
'ipb-confirm',
423 'cssclass' =>
'mw-block-confirm',
429 $this->
getHookRunner()->onSpecialBlockModifyFormFields( $this, $a );
440 # This will be overwritten by request data
441 $fields[
'Target'][
'default'] = (string)$this->target;
443 if ( $this->target ) {
444 $status = $this->blockUtils->validateTarget( $this->target );
445 if ( !$status->isOK() ) {
446 $errors = $status->getErrorsArray();
447 $this->preErrors = array_merge( $this->preErrors, $errors );
452 $fields[
'PreviousTarget'][
'default'] = (string)$this->target;
454 $block = DatabaseBlock::newFromTarget( $this->target );
459 && ( $this->type != DatabaseBlock::TYPE_RANGE
460 || ( $this->target && $block->isBlocking( $this->target ) ) )
462 $fields[
'HardBlock'][
'default'] = $block->isHardblock();
463 $fields[
'CreateAccount'][
'default'] = $block->isCreateAccountBlocked();
464 $fields[
'AutoBlock'][
'default'] = $block->isAutoblocking();
466 if ( isset( $fields[
'DisableEmail'] ) ) {
467 $fields[
'DisableEmail'][
'default'] = $block->isEmailBlocked();
470 if ( isset( $fields[
'HideUser'] ) ) {
471 $fields[
'HideUser'][
'default'] = $block->getHideName();
474 if ( isset( $fields[
'DisableUTEdit'] ) ) {
475 $fields[
'DisableUTEdit'][
'default'] = !$block->isUsertalkEditAllowed();
480 if ( !$block->getHideName() || $this->getAuthority()->isAllowed(
'hideuser' ) ) {
481 $fields[
'Reason'][
'default'] = $block->getReasonComment()->text;
483 $fields[
'Reason'][
'default'] =
'';
487 # Ok, so we got a POST submission asking us to reblock a user. So show the
488 # confirm checkbox; the user will only see it if they haven't previously
489 $fields[
'Confirm'][
'type'] =
'check';
491 # We got a target, but it wasn't a POST request, so the user must have gone
492 # to a link like [[Special:Block/User]]. We don't need to show the checkbox
493 # as long as they go ahead and block *that* user
494 $fields[
'Confirm'][
'default'] = 1;
497 if ( $block->getExpiry() ==
'infinity' ) {
498 $fields[
'Expiry'][
'default'] =
'infinite';
500 $fields[
'Expiry'][
'default'] =
wfTimestamp( TS_RFC2822, $block->getExpiry() );
503 if ( !$block->isSitewide() ) {
504 $fields[
'EditingRestriction'][
'default'] =
'partial';
506 $pageRestrictions = [];
507 $namespaceRestrictions = [];
508 foreach ( $block->getRestrictions() as $restriction ) {
510 $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
512 $this->namespaceInfo->exists( $restriction->getValue() )
514 $namespaceRestrictions[] = $restriction->getValue();
519 sort( $pageRestrictions );
520 $fields[
'PageRestrictions'][
'default'] = implode(
"\n", $pageRestrictions );
521 sort( $namespaceRestrictions );
522 $fields[
'NamespaceRestrictions'][
'default'] = implode(
"\n", $namespaceRestrictions );
524 if ( $this->
getConfig()->
get( MainConfigNames::EnablePartialActionBlocks ) ) {
525 $actionRestrictions = [];
526 foreach ( $block->getRestrictions() as $restriction ) {
528 $actionRestrictions[] = $restriction->getValue();
531 $fields[
'ActionRestrictions'][
'default'] = $actionRestrictions;
535 $this->alreadyBlocked =
true;
536 $this->preErrors[] = [
'ipb-needreblock',
wfEscapeWikiText( $block->getTargetName() ) ];
539 if ( $this->alreadyBlocked || $this->
getRequest()->wasPosted()
540 || $this->
getRequest()->getCheck(
'wpCreateAccount' )
542 $this->
getOutput()->addJsConfigVars(
'wgCreateAccountDirty',
true );
545 # We always need confirmation to do HideUser
546 if ( $this->requestedHideUser ) {
547 $fields[
'Confirm'][
'type'] =
'check';
548 unset( $fields[
'Confirm'][
'default'] );
549 $this->preErrors[] = [
'ipb-confirmhideuser',
'ipb-confirmaction' ];
552 # Or if the user is trying to block themselves
554 $fields[
'Confirm'][
'type'] =
'check';
555 unset( $fields[
'Confirm'][
'default'] );
556 $this->preErrors[] = [
'ipb-blockingself',
'ipb-confirmaction' ];
565 $this->
getOutput()->addModuleStyles( [
'mediawiki.special' ] );
566 $this->
getOutput()->addModules( [
'mediawiki.special.block' ] );
568 $blockCIDRLimit = $this->
getConfig()->get( MainConfigNames::BlockCIDRLimit );
569 $text = $this->
msg(
'blockiptext', $blockCIDRLimit[
'IPv4'], $blockCIDRLimit[
'IPv6'] )->parse();
571 $otherBlockMessages = [];
572 if ( $this->target !==
null ) {
575 $targetName = $this->target->
getName();
577 # Get other blocks, i.e. from GlobalBlocking or TorBlock extension
579 $otherBlockMessages, $targetName );
581 if ( count( $otherBlockMessages ) ) {
582 $s = Html::rawElement(
585 $this->
msg(
'ipb-otherblocks-header', count( $otherBlockMessages ) )->parse()
590 foreach ( $otherBlockMessages as $link ) {
591 $list .= Html::rawElement(
'li', [], $link ) .
"\n";
594 $s .= Html::rawElement(
596 [
'class' =>
'mw-blockip-alreadyblocked' ],
614 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
617 # Link to the user's contributions, if applicable
620 $links[] = $linkRenderer->makeLink(
622 $this->
msg(
'ipb-blocklist-contribs', $this->target->getName() )->text()
626 # Link to unblock the specified user, or to a blank unblock form
628 $message = $this->
msg(
634 $message = $this->
msg(
'ipb-unblock' )->parse();
637 $links[] = $linkRenderer->makeKnownLink(
642 # Link to the block list
643 $links[] = $linkRenderer->makeKnownLink(
645 $this->
msg(
'ipb-blocklist' )->text()
648 # Link to edit the block dropdown reasons, if applicable
649 if ( $this->
getAuthority()->isAllowed(
'editinterface' ) ) {
650 $links[] = $linkRenderer->makeKnownLink(
651 $this->
msg(
'ipbreason-dropdown' )->inContentLanguage()->
getTitle(),
652 $this->
msg(
'ipb-edit-dropdown' )->text(),
654 [
'action' =>
'edit' ]
658 $text = Html::rawElement(
660 [
'class' =>
'mw-ipb-conveniencelinks' ],
666 # Get relevant extracts from the block and suppression logs, if possible
678 $this->titleFormatter->getText( $userPage ),
680 'showIfEmpty' =>
false
685 # Add suppression block entries if allowed
686 if ( $this->
getAuthority()->isAllowed(
'suppressionlog' ) ) {
694 'conds' => [
'log_action' => [
'block',
'reblock',
'unblock' ] ],
696 'blocklog-showsuppresslog',
697 $this->titleFormatter->getText( $userPage ),
699 'showIfEmpty' =>
false
743 return MediaWikiServices::getInstance()->getBlockUtils()->parseBlockTarget( $par );
747 $request->getVal(
'wpTarget',
null ),
749 $request->getVal(
'ip',
null ),
751 $request->getVal(
'wpBlockAddress',
null ),
753 foreach ( $possibleTargets as $possibleTarget ) {
754 $targetAndType = MediaWikiServices::getInstance()
756 ->parseBlockTarget( $possibleTarget );
758 if ( $targetAndType[ 1 ] !==
null ) {
762 return $targetAndType;
774 $services = MediaWikiServices::getInstance();
775 return self::processFormInternal(
778 $services->getBlockUserFactory(),
779 $services->getBlockUtils()
793 private static function processFormInternal(
800 $enablePartialActionBlocks = MediaWikiServices::getInstance()
801 ->getMainConfig()->get( MainConfigNames::EnablePartialActionBlocks );
803 $isPartialBlock = isset( $data[
'EditingRestriction'] ) &&
804 $data[
'EditingRestriction'] ===
'partial';
806 # This might have been a hidden field or a checkbox, so interesting data
808 $data[
'Confirm'] = !in_array( $data[
'Confirm'], [
'',
'0',
null,
false ],
true );
810 # If the user has done the form 'properly', they won't even have been given the
811 # option to suppress-block unless they have the 'hideuser' permission
812 if ( !isset( $data[
'HideUser'] ) ) {
813 $data[
'HideUser'] =
false;
818 if (
$type == DatabaseBlock::TYPE_USER ) {
819 $target = $target->getName();
821 # Give admins a heads-up before they go and block themselves. Much messier
822 # to do this for IPs, but it's pretty unlikely they'd ever get the 'block'
823 # permission anyway, although the code does allow for it.
824 # Note: Important to use $target instead of $data['Target']
825 # since both $data['PreviousTarget'] and $target are normalized
826 # but $data['target'] gets overridden by (non-normalized) request variable
827 # from previous request.
828 if ( $target === $performer->
getUser()->getName() &&
829 ( $data[
'PreviousTarget'] !== $target || !$data[
'Confirm'] )
831 return [
'ipb-blockingself',
'ipb-confirmaction' ];
834 if ( $data[
'HideUser'] && !$data[
'Confirm'] ) {
835 return [
'ipb-confirmhideuser',
'ipb-confirmaction' ];
837 } elseif (
$type == DatabaseBlock::TYPE_IP ) {
838 $target = $target->getName();
839 } elseif (
$type != DatabaseBlock::TYPE_RANGE ) {
840 # This should have been caught in the form field validation
841 return [
'badipaddress' ];
846 $blockReason = $data[
'Reason'][0] ??
'';
848 $pageRestrictions = [];
849 $namespaceRestrictions = [];
850 $actionRestrictions = [];
851 if ( $isPartialBlock ) {
852 if ( isset( $data[
'PageRestrictions'] ) && $data[
'PageRestrictions'] !==
'' ) {
853 $titles = explode(
"\n", $data[
'PageRestrictions'] );
854 foreach ( $titles as
$title ) {
855 $pageRestrictions[] = PageRestriction::newFromTitle(
$title );
858 if ( isset( $data[
'NamespaceRestrictions'] ) && $data[
'NamespaceRestrictions'] !==
'' ) {
859 $namespaceRestrictions = array_map(
static function ( $id ) {
861 }, explode(
"\n", $data[
'NamespaceRestrictions'] ) );
864 $enablePartialActionBlocks &&
865 isset( $data[
'ActionRestrictions'] ) &&
866 $data[
'ActionRestrictions'] !==
''
868 $actionRestrictions = array_map(
static function ( $id ) {
870 }, $data[
'ActionRestrictions'] );
873 $restrictions = array_merge( $pageRestrictions, $namespaceRestrictions, $actionRestrictions );
875 if ( !isset( $data[
'Tags'] ) ) {
880 'isCreateAccountBlocked' => $data[
'CreateAccount'],
881 'isHardBlock' => $data[
'HardBlock'],
882 'isAutoblocking' => $data[
'AutoBlock'],
883 'isHideUser' => $data[
'HideUser'],
884 'isPartial' => $isPartialBlock,
887 if ( isset( $data[
'DisableUTEdit'] ) ) {
888 $blockOptions[
'isUserTalkEditBlocked'] = $data[
'DisableUTEdit'];
890 if ( isset( $data[
'DisableEmail'] ) ) {
891 $blockOptions[
'isEmailBlocked'] = $data[
'DisableEmail'];
904 # Indicates whether the user is confirming the block and is aware of
905 # the conflict (did not change the block target in the meantime)
906 $blockNotConfirmed = !$data[
'Confirm'] || ( array_key_exists(
'PreviousTarget', $data )
907 && $data[
'PreviousTarget'] !== $target );
909 # Special case for API - T34434
910 $reblockNotAllowed = ( array_key_exists(
'Reblock', $data ) && !$data[
'Reblock'] );
912 $doReblock = !$blockNotConfirmed && !$reblockNotAllowed;
914 $status = $blockUser->placeBlock( $doReblock );
915 if ( !$status->isOK() ) {
921 $type != DatabaseBlock::TYPE_RANGE
926 && array_key_exists(
'Watch', $data )
929 MediaWikiServices::getInstance()->getWatchlistManager()->addWatchIgnoringRights(
931 Title::makeTitle(
NS_USER, $target )
949 $msg =
$lang ===
null
950 ?
wfMessage(
'ipboptions' )->inContentLanguage()->text()
959 if ( $a && $includeOther ) {
962 $a[
wfMessage(
'ipbother' )->text() ] =
'other';
978 return BlockUser::parseExpiryInput( $expiry );
989 return MediaWikiServices::getInstance()
990 ->getBlockPermissionCheckerFactory()
992 ->checkEmailPermissions();
1011 return MediaWikiServices::getInstance()
1012 ->getBlockPermissionCheckerFactory()
1013 ->newBlockPermissionChecker( $target, $performer )
1014 ->checkBlockPermissions();
1024 return self::processFormInternal(
1027 $this->blockUserFactory,
1037 $out = $this->getOutput();
1038 $out->setPageTitle( $this->msg(
'blockipsuccesssub' ) );
1039 $out->addWikiMsg(
'blockipsuccesstext',
wfEscapeWikiText( $this->target ) );
1051 $search = $this->userNameUtils->getCanonical( $search );
1057 return $this->userNamePrefixSearch
1058 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
An error page which can definitely be safely rendered using the OutputPage.
Special page which uses an HTMLForm to handle processing.
string null $par
The sub-page of the special page.
Marks HTML that shouldn't be escaped.
Base class for language-specific code.
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
A class containing constants representing the names of configuration variables.
static durationParam( $duration)
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
A special page that allows users with 'block' right to block users from editing pages and other actio...
int $type
DatabaseBlock::TYPE_ constant.
requiresUnblock()
We allow certain special cases where user is blocked.
static processForm(array $data, IContextSource $context)
Given the form data, actually implement a block.
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
static parseExpiryInput( $expiry)
Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute ("24 May 2034",...
bool $requestedHideUser
Whether the previous submission of the form asked for HideUser.
maybeAlterFormDefaults(&$fields)
If the user has already been blocked with similar settings, load that block and change the defaults f...
postHtml()
Add footer elements to the form.
getFormFields()
Get the HTMLForm descriptor array for the block form.
__construct(BlockUtils $blockUtils, BlockPermissionCheckerFactory $blockPermissionCheckerFactory, BlockUserFactory $blockUserFactory, UserNameUtils $userNameUtils, UserNamePrefixSearch $userNamePrefixSearch, BlockActionInfo $blockActionInfo, TitleFormatter $titleFormatter, NamespaceInfo $namespaceInfo)
static checkUnblockSelf( $target, Authority $performer)
T17810: Sitewide blocked admins should not be able to block/unblock others with one exception; they c...
getDisplayFormat()
Get display format for the form.
preHtml()
Add header elements like block log entries, etc.
setParameter( $par)
Handle some magic here.
User string $previousTarget
The previous block target.
checkExecutePermissions(User $user)
Checks that the user can unblock themselves if they are trying to do so.
alterForm(HTMLForm $form)
Customizes the HTMLForm a bit.
static getTargetUserTitle( $target)
Get a user page target for things like logs.
static canBlockEmail(UserIdentity $user)
Can we do an email block?
doesWrites()
Indicates whether this special page may perform database writes.
onSubmit(array $data, HTMLForm $form=null)
Process the form on POST submission.
static getSuggestedDurations(Language $lang=null, $includeOther=true)
Get an array of suggested block durations from MediaWiki:Ipboptions.
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
static getTargetAndType(?string $par, WebRequest $request=null)
Get the target and type, given the request and the subpage parameter.
UserIdentity string null $target
User to be blocked, as passed either by parameter (url?wpTarget=Foo) or as subpage (Special:Block/Foo...
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getName()
Get the name of this Special Page.
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
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,...
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
getLanguage()
Shortcut to get user's language.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static newFromIdentity(UserIdentity $identity)
Returns a User object corresponding to the given UserIdentity.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
static parseOptionsMessage(string $msg)
Parse labels and values out of a comma- and colon-separated list of options, such as is used for expi...
Interface for objects which can provide a MediaWiki context on request.
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
if(!isset( $args[0])) $lang