77 private $userGroupManager =
null;
104 parent::__construct(
'Userrights' );
107 $this->userNameUtils = $userNameUtils ?? $services->getUserNameUtils();
108 $this->userNamePrefixSearch = $userNamePrefixSearch ?? $services->getUserNamePrefixSearch();
109 $this->userFactory = $userFactory ?? $services->getUserFactory();
110 $this->userGroupManagerFactory = $userGroupManagerFactory ?? $services->getUserGroupManagerFactory();
111 $this->actorStoreFactory = $actorStoreFactory ?? $services->getActorStoreFactory();
112 $this->watchlistManager = $watchlistManager ?? $services->getWatchlistManager();
113 $this->tempUserConfig = $tempUserConfig ?? $services->getTempUserConfig();
134 $this->userNameUtils->isTemp( $targetUser->
getName() )
139 $userGroupManager = $this->userGroupManagerFactory
140 ->getUserGroupManager( $targetUser->
getWikiId() );
142 if ( $available[
'add'] || $available[
'remove'] ) {
148 if ( ( $available[
'add-self'] || $available[
'remove-self'] )
149 && (
$isself || !$checkIfSelf )
168 $session = $request->getSession();
171 $out->addModules( [
'mediawiki.special.userrights' ] );
173 $this->mTarget = $par ?? $request->getVal(
'user' );
174 if ( $this->mTarget ===
null ) {
175 $fetchedStatus = Status::newFatal(
'nouserspecified' );
178 $this->mTarget = trim( $this->mTarget );
180 if ( $this->userNameUtils->getCanonical( $this->mTarget ) === $user->
getName() ) {
181 $this->isself =
true;
184 $fetchedStatus = $this->
fetchUser( $this->mTarget,
true );
187 if ( $fetchedStatus->isOK() ) {
188 $this->mFetchedUser = $fetchedUser = $fetchedStatus->value;
190 '@phan-var UserIdentity $fetchedUser';
191 $wikiId = $fetchedUser->getWikiId();
192 if ( $wikiId === UserIdentity::LOCAL ) {
195 $this->
getSkin()->setRelevantUser( $this->mFetchedUser );
197 $this->userGroupManager = $this->userGroupManagerFactory
198 ->getUserGroupManager( $wikiId );
203 $session->get(
'specialUserrightsSaveSuccess' ) &&
204 $this->mFetchedUser !==
null
207 $session->remove(
'specialUserrightsSaveSuccess' );
209 $out->addModuleStyles(
'mediawiki.notification.convertmessagebox.styles' );
215 $this->
msg(
'savedrights', $this->getDisplayUsername( $this->mFetchedUser ) )->text()
225 $out->addModuleStyles(
'mediawiki.special' );
226 $this->
addHelpLink(
'Help:Assigning permissions' );
231 $request->wasPosted() &&
232 $request->getCheck(
'saveusergroups' ) &&
233 $this->mTarget !==
null &&
234 $user->matchEditToken( $request->getVal(
'wpEditToken' ), $this->mTarget )
241 if ( !$this->
getAuthority()->isAllowed(
'userrights' ) ) {
242 $block = $user->getBlock();
243 if ( $block && $block->isSitewide() ) {
256 if ( !$fetchedStatus->isOK() ) {
257 $this->
getOutput()->addWikiTextAsInterface(
258 $fetchedStatus->getWikiText(
false,
false, $this->getLanguage() )
265 $conflictCheck = $request->getVal(
'conflictcheck-originalgroups' );
266 $conflictCheck = ( $conflictCheck ===
'' ) ? [] : explode(
',', $conflictCheck );
267 $userGroups = $this->userGroupManager->getUserGroups( $targetUser, IDBAccessObject::READ_LATEST );
269 if ( $userGroups !== $conflictCheck ) {
270 $out->addHTML( Html::errorBox(
271 $this->
msg(
'userrights-conflict' )->parse()
275 $request->getText(
'user-reason' ),
279 if ( $status->isOK() ) {
281 $session->set(
'specialUserrightsSaveSuccess', 1 );
283 $out->redirect( $this->getSuccessURL() );
287 $out->wrapWikiTextAsInterface(
288 'error', $status->getWikiText(
false,
false, $this->getLanguage() )
295 if ( $this->mTarget !==
null ) {
296 $this->editUserGroupsForm( $this->mTarget );
300 private function getSuccessURL() {
301 return $this->
getPageTitle( $this->mTarget )->getFullURL();
328 $unix = strtotime( $expiry );
330 if ( !$unix || $unix === -1 ) {
348 if ( $this->userNameUtils->isTemp( $user->
getName() ) ) {
349 return Status::newFatal(
'userrights-no-tempuser' );
354 $user->
getWikiId() !== UserIdentity::LOCAL &&
355 !$this->tempUserConfig->isKnown() &&
356 $this->tempUserConfig->isReservedName( $user->
getName() )
358 return Status::newFatal(
'userrights-cross-wiki-assignment-for-reserved-name' );
361 $allgroups = $this->userGroupManager->listAllGroups();
365 $existingUGMs = $this->userGroupManager->getUserGroupMemberships( $user );
369 foreach ( $allgroups as $group ) {
372 if ( $this->
getRequest()->getCheck(
"wpGroup-$group" ) ) {
373 $addgroup[] = $group;
377 $expiryDropdown = $this->
getRequest()->getVal(
"wpExpiry-$group" );
378 if ( $expiryDropdown ===
'existing' ) {
382 if ( $expiryDropdown ===
'other' ) {
383 $expiryValue = $this->
getRequest()->getVal(
"wpExpiry-$group-other" );
385 $expiryValue = $expiryDropdown;
391 if ( $groupExpiries[$group] ===
false ) {
392 return Status::newFatal(
'userrights-invalid-expiry', $group );
396 if ( $groupExpiries[$group] && $groupExpiries[$group] <
wfTimestampNow() ) {
397 return Status::newFatal(
'userrights-expiry-in-past', $group );
402 if ( !$this->canRemove( $group ) &&
403 isset( $existingUGMs[$group] ) &&
404 ( $existingUGMs[$group]->getExpiry() ?:
'infinity' ) >
405 ( $groupExpiries[$group] ?:
'infinity' )
407 return Status::newFatal(
'userrights-cannot-shorten-expiry', $group );
411 $removegroup[] = $group;
415 $this->
doSaveUserGroups( $user, $addgroup, $removegroup, $reason, [], $groupExpiries );
417 if ( $user->
getWikiId() === UserIdentity::LOCAL && $this->getRequest()->getCheck(
'wpWatch' ) ) {
418 $this->watchlistManager->addWatchIgnoringRights(
424 return Status::newGood();
443 array $tags = [], array $groupExpiries = []
447 if ( $this->userGroupManager !==
null ) {
449 $userGroupManager = $this->userGroupManager;
452 $userGroupManager = $this->userGroupManagerFactory
453 ->getUserGroupManager( $user->
getWikiId() );
458 $addable = array_merge( $changeable[
'add'],
$isself ? $changeable[
'add-self'] : [] );
459 $removable = array_merge( $changeable[
'remove'],
$isself ? $changeable[
'remove-self'] : [] );
461 $remove = array_unique( array_intersect( $remove, $removable, $groups ) );
462 $add = array_intersect( $add, $addable );
467 $add = array_filter( $add,
468 static function ( $group ) use ( $groups, $groupExpiries, $removable, $ugms ) {
469 if ( isset( $groupExpiries[$group] ) &&
470 !in_array( $group, $removable ) &&
471 isset( $ugms[$group] ) &&
472 ( $ugms[$group]->getExpiry() ?:
'infinity' ) >
473 ( $groupExpiries[$group] ?:
'infinity' )
477 return !in_array( $group, $groups ) || array_key_exists( $group, $groupExpiries );
480 if ( $user->
getWikiId() === UserIdentity::LOCAL ) {
482 $hookUser = $this->userFactory->newFromUserIdentity( $user );
489 $oldGroups = $groups;
491 $newGroups = $oldGroups;
495 foreach ( $remove as $index => $group ) {
497 unset( $remove[$index] );
500 $newGroups = array_diff( $newGroups, $remove );
503 foreach ( $add as $index => $group ) {
504 $expiry = $groupExpiries[$group] ??
null;
505 if ( !$userGroupManager->
addUserToGroup( $user, $group, $expiry,
true ) ) {
506 unset( $add[$index] );
509 $newGroups = array_merge( $newGroups, $add );
511 $newGroups = array_unique( $newGroups );
515 $this->userFactory->invalidateCache( $user );
518 $this->
getHookRunner()->onUserGroupsChanged( $hookUser, $add, $remove,
519 $this->
getUser(), $reason, $oldUGMs, $newUGMs );
521 wfDebug(
'oldGroups: ' . print_r( $oldGroups,
true ) );
522 wfDebug(
'newGroups: ' . print_r( $newGroups,
true ) );
523 wfDebug(
'oldUGMs: ' . print_r( $oldUGMs,
true ) );
524 wfDebug(
'newUGMs: ' . print_r( $newUGMs,
true ) );
527 if ( $newGroups != $oldGroups || $newUGMs != $oldUGMs ) {
528 $this->
addLogEntry( $user, $oldGroups, $newGroups, $reason, $tags, $oldUGMs, $newUGMs );
531 return [ $add, $remove ];
545 return [
'expiry' => $ugm->getExpiry() ];
558 protected function addLogEntry( $user, array $oldGroups, array $newGroups,
string $reason,
559 array $tags, array $oldUGMs, array $newUGMs
563 $oldUGMs = array_map(
static function ( $group ) use ( $oldUGMs ) {
564 return isset( $oldUGMs[$group] ) ?
568 $newUGMs = array_map(
static function ( $group ) use ( $newUGMs ) {
569 return isset( $newUGMs[$group] ) ?
575 $logEntry->setPerformer( $this->
getUser() );
576 $logEntry->setTarget( Title::makeTitle(
NS_USER, $this->getDisplayUsername( $user ) ) );
577 $logEntry->setComment( $reason );
578 $logEntry->setParameters( [
579 '4::oldgroups' => $oldGroups,
580 '5::newgroups' => $newGroups,
581 'oldmetadata' => $oldUGMs,
582 'newmetadata' => $newUGMs,
584 $logid = $logEntry->insert();
585 if ( count( $tags ) ) {
586 $logEntry->addTags( $tags );
588 $logEntry->publish( $logid );
595 private function editUserGroupsForm( $username ) {
596 $status = $this->
fetchUser( $username,
true );
597 if ( !$status->isOK() ) {
598 $this->
getOutput()->addWikiTextAsInterface(
599 $status->getWikiText(
false,
false, $this->getLanguage() )
606 $user = $status->value;
607 '@phan-var UserIdentity $user';
609 $groups = $this->userGroupManager->getUserGroups( $user );
610 $groupMemberships = $this->userGroupManager->getUserGroupMemberships( $user );
627 public function fetchUser( $username, $writing =
true ) {
630 if ( count( $parts ) < 2 ) {
631 $name = trim( $username );
632 $wikiId = UserIdentity::LOCAL;
634 [ $name, $wikiId ] = array_map(
'trim', $parts );
636 if ( WikiMap::isCurrentWikiId( $wikiId ) ) {
637 $wikiId = UserIdentity::LOCAL;
640 !$this->
getAuthority()->isAllowed(
'userrights-interwiki' )
642 return Status::newFatal(
'userrights-no-interwiki' );
645 if ( !in_array( $wikiId, $localDatabases ) ) {
646 return Status::newFatal(
'userrights-nodatabase', $wikiId );
651 if ( $name ===
'' ) {
652 return Status::newFatal(
'nouserspecified' );
655 $userIdentityLookup = $this->actorStoreFactory->getUserIdentityLookup( $wikiId );
656 if ( $name[0] ==
'#' ) {
658 $id = intval( substr( $name, 1 ) );
660 $user = $userIdentityLookup->getUserIdentityByUserId( $id );
663 return Status::newFatal(
'noname' );
667 $name = $this->userNameUtils->getCanonical( $name );
668 if ( $name ===
false ) {
670 return Status::newFatal(
'nosuchusershort', $username );
672 $user = $userIdentityLookup->getUserIdentityByName( $name );
675 if ( $this->userNameUtils->isTemp( $name ) ) {
676 return Status::newFatal(
'userrights-no-group' );
680 return Status::newFatal(
'nosuchusershort', $username );
686 $user->
getWikiId() !== UserIdentity::LOCAL &&
687 !$this->tempUserConfig->isKnown() &&
688 $this->tempUserConfig->isReservedName( $name )
690 return Status::newFatal(
'userrights-no-group' );
693 if ( $user->
getWikiId() === UserIdentity::LOCAL &&
694 $this->userFactory->newFromUserIdentity( $user )->isHidden() &&
695 !$this->getAuthority()->isAllowed(
'hideuser' )
698 return Status::newFatal(
'nosuchusershort', $username );
701 return Status::newGood( $user );
713 return $this->
msg(
'rightsnone' )->inContentLanguage()->text();
715 return implode(
', ', $ids );
725 'class' => HTMLUserTextField::class,
726 'label-message' =>
'userrights-user-editname',
730 'excludetemp' =>
true,
731 'autofocus' => $this->mFetchedUser ===
null,
736 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor, $this->
getContext() );
740 ->setName(
'uluser' )
742 ->setWrapperLegendMsg(
'userrights-lookup-user' )
743 ->setId(
'mw-userrights-form1' )
744 ->setSubmitTextMsg(
'editusergroup' )
746 ->displayForm(
true );
759 $list = $membersList = $tempList = $tempMembersList = [];
760 foreach ( $groupMemberships as $ugm ) {
761 $linkG = UserGroupMembership::getLinkHTML( $ugm, $this->
getContext() );
762 $linkM = UserGroupMembership::getLinkHTML( $ugm, $this->
getContext(), $user->
getName() );
763 if ( $ugm->getExpiry() ) {
764 $tempList[] = $linkG;
765 $tempMembersList[] = $linkM;
768 $membersList[] = $linkM;
774 $autoMembersList = [];
776 if ( $user->
getWikiId() === UserIdentity::LOCAL ) {
778 foreach ( $this->userGroupManager->getUserAutopromoteGroups( $user ) as $group ) {
779 $autoList[] = UserGroupMembership::getLinkHTML( $group, $this->
getContext() );
780 $autoMembersList[] = UserGroupMembership::getLinkHTML( $group, $this->
getContext(), $user->
getName() );
785 $displayedList = $this->
msg(
'userrights-groupsmember-type' )
787 $language->commaList( array_merge( $tempList, $list ) ),
788 $language->commaList( array_merge( $tempMembersList, $membersList ) )
790 $displayedAutolist = $this->
msg(
'userrights-groupsmember-type' )
792 $language->commaList( $autoList ),
793 $language->commaList( $autoMembersList )
797 $count = count( $list ) + count( $tempList );
799 $grouplist = $this->
msg(
'userrights-groupsmember' )
800 ->numParams( $count )
803 $grouplist =
'<p>' . $grouplist .
' ' . $displayedList .
"</p>\n";
806 $count = count( $autoList );
808 $autogrouplistintro = $this->
msg(
'userrights-groupsmember-auto' )
809 ->numParams( $count )
812 $grouplist .=
'<p>' . $autogrouplistintro .
' ' . $displayedAutolist .
"</p>\n";
815 $systemUser = $user->
getWikiId() === UserIdentity::LOCAL
816 && $this->userFactory->newFromUserIdentity( $user )->isSystemUser();
818 $systemusernote = $this->
msg(
'userrights-systemuser' )
821 $grouplist .=
'<p>' . $systemusernote .
"</p>\n";
825 $flags = $systemUser ? 0 : Linker::TOOL_LINKS_EMAIL;
826 $userToolLinks = Linker::userToolLinks(
828 $this->getDisplayUsername( $user ),
833 [ $groupCheckboxes, $canChangeAny ] =
834 $this->groupCheckboxes( $groupMemberships, $user );
841 'name' =>
'editGroup',
842 'id' =>
'mw-userrights-form2'
845 Html::hidden(
'user', $this->mTarget ) .
846 Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken( $this->mTarget ) ) .
848 'conflictcheck-originalgroups',
849 implode(
',', $this->userGroupManager->getUserGroups( $user ) )
851 Html::openElement(
'fieldset' ) .
856 $canChangeAny ?
'userrights-editusergroup' :
'userrights-viewusergroup',
861 $canChangeAny ?
'editinguser' :
'viewinguserrights'
863 ->rawParams( $userToolLinks )->parse()
865 if ( $canChangeAny ) {
867 $this->
msg(
'userrights-groups-help', $user->
getName() )->parse() .
870 Html::openElement(
'table', [
'id' =>
'mw-userrights-table-outer' ] ) .
872 <td class='mw-label'>" .
873 Html::label( $this->msg(
'userrights-reason' )->text(),
'wpReason' ) .
875 <td class='mw-input'>" .
876 Xml::input(
'user-reason', 60, $this->getRequest()->getVal(
'user-reason' ) ??
false, [
881 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
887 <td class='mw-submit'>" .
888 Html::submitButton( $this->msg(
'saveusergroups', $user->
getName() )->text(),
889 [
'name' =>
'saveusergroups' ] +
890 Linker::tooltipAndAccesskeyAttribs(
'userrights-set' )
896 <td class='mw-input'>" .
897 Html::check(
'wpWatch',
false, [
'id' =>
'wpWatch' ] ) .
898 ' ' . Html::label( $this->msg(
'userrights-watchuser' )->text(),
'wpWatch' ) .
904 $this->
getOutput()->addHTML( $grouplist );
921 private function groupCheckboxes( $usergroups,
UserIdentity $user ) {
922 $allgroups = $this->userGroupManager->listAllGroups();
926 $expiryOptionsMsg = $this->
msg(
'userrights-expiry-options' )->inContentLanguage();
927 $expiryOptions = $expiryOptionsMsg->isDisabled()
929 : XmlSelect::parseOptionsMessage( $expiryOptionsMsg->text() );
933 $columns = [
'unchangeable' => [],
'changeable' => [] ];
935 foreach ( $allgroups as $group ) {
936 $set = isset( $usergroups[$group] );
940 $canOnlyLengthenExpiry = ( $set && $this->canAdd( $group ) &&
941 !$this->canRemove( $group ) && $usergroups[$group]->getExpiry() );
943 $disabledCheckbox = !(
944 ( $set && $this->canRemove( $group ) ) ||
945 ( !$set && $this->canAdd( $group ) ) );
947 $disabledExpiry = $disabledCheckbox && !$canOnlyLengthenExpiry;
949 $irreversible = !$disabledCheckbox && (
950 ( $set && !$this->canAdd( $group ) ) ||
951 ( !$set && !$this->canRemove( $group ) ) );
955 'disabled' => $disabledCheckbox,
956 'disabled-expiry' => $disabledExpiry,
957 'irreversible' => $irreversible
960 if ( $disabledCheckbox && $disabledExpiry ) {
961 $columns[
'unchangeable'][$group] = $checkbox;
963 $columns[
'changeable'][$group] = $checkbox;
968 $ret .=
Xml::openElement(
'table', [
'class' =>
'mw-userrights-groups' ] ) .
970 foreach ( $columns as $name => $column ) {
971 if ( $column === [] ) {
978 $this->
msg(
'userrights-' . $name .
'-col', count( $column ) )->text()
982 $ret .=
"</tr>\n<tr>\n";
985 foreach ( $columns as $column ) {
986 if ( $column === [] ) {
989 $ret .=
"\t<td style='vertical-align:top;'>\n";
990 foreach ( $column as $group => $checkbox ) {
991 $member = $uiLanguage->getGroupMemberName( $group, $userName );
992 if ( $checkbox[
'irreversible'] ) {
993 $text = $this->
msg(
'userrights-irreversible-marker', $member )->text();
994 } elseif ( $checkbox[
'disabled'] && !$checkbox[
'disabled-expiry'] ) {
995 $text = $this->
msg(
'userrights-no-shorten-expiry-marker', $member )->text();
1000 'type' =>
'checkbox',
'name' =>
"wpGroup-$group",
'value' =>
'1',
1001 'id' =>
"wpGroup-$group",
'checked' => $checkbox[
'set'],
1002 'class' =>
'mw-userrights-groupcheckbox',
1003 'disabled' => $checkbox[
'disabled'],
1004 ] ) .
' ' . Html::label( $text,
"wpGroup-$group" );
1009 $currentExpiry = isset( $usergroups[$group] ) ?
1010 $usergroups[$group]->getExpiry() :
1015 if ( $checkbox[
'set'] &&
1016 ( $checkbox[
'irreversible'] || $checkbox[
'disabled-expiry'] )
1018 if ( $currentExpiry ) {
1019 $expiryFormatted = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser );
1020 $expiryFormattedD = $uiLanguage->userDate( $currentExpiry, $uiUser );
1021 $expiryFormattedT = $uiLanguage->userTime( $currentExpiry, $uiUser );
1023 $this->
msg(
'userrights-expiry-current' )->params(
1024 $expiryFormatted, $expiryFormattedD, $expiryFormattedT )->text() );
1027 $this->
msg(
'userrights-expiry-none' )->text() );
1031 $expiryHtml .= Html::hidden(
"wpExpiry-$group",
1032 $currentExpiry ?
'existing' :
'infinite' );
1033 $expiryHtml .=
"<br />\n";
1036 $this->
msg(
'userrights-expiry' )->text() );
1037 $expiryHtml .= Html::openElement(
'span' );
1040 $expiryFormOptions =
new XmlSelect(
1042 "mw-input-wpExpiry-$group",
1043 $currentExpiry ?
'existing' :
'infinite'
1045 if ( $checkbox[
'disabled-expiry'] ) {
1046 $expiryFormOptions->setAttribute(
'disabled',
'disabled' );
1049 if ( $currentExpiry ) {
1050 $timestamp = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser );
1051 $d = $uiLanguage->userDate( $currentExpiry, $uiUser );
1052 $t = $uiLanguage->userTime( $currentExpiry, $uiUser );
1053 $existingExpiryMessage = $this->
msg(
'userrights-expiry-existing',
1054 $timestamp, $d, $t );
1055 $expiryFormOptions->addOption( $existingExpiryMessage->text(),
'existing' );
1058 $expiryFormOptions->addOption(
1059 $this->
msg(
'userrights-expiry-none' )->text(),
1062 $expiryFormOptions->addOption(
1063 $this->
msg(
'userrights-expiry-othertime' )->text(),
1067 $expiryFormOptions->addOptions( $expiryOptions );
1070 $expiryHtml .= $expiryFormOptions->getHTML() .
'<br />';
1074 'name' =>
"wpExpiry-$group-other",
'size' => 30,
'value' =>
'',
1075 'id' =>
"mw-input-wpExpiry-$group-other",
1076 'class' =>
'mw-userrights-expiryfield',
1077 'disabled' => $checkbox[
'disabled-expiry'],
1082 if ( $checkbox[
'set'] && $checkbox[
'disabled'] ) {
1083 $expiryHtml .= Html::hidden(
"wpGroup-$group", 1 );
1086 $expiryHtml .= Html::closeElement(
'span' );
1090 'id' =>
"mw-userrights-nested-wpGroup-$group",
1091 'class' =>
'mw-userrights-nested',
1093 $checkboxHtml .=
"\t\t\t" . Html::rawElement(
'div', $divAttribs, $expiryHtml ) .
"\n";
1095 $ret .=
"\t\t" . ( ( $checkbox[
'disabled'] && $checkbox[
'disabled-expiry'] )
1096 ? Html::rawElement(
'div', [
'class' =>
'mw-userrights-disabled' ], $checkboxHtml )
1097 : Html::rawElement(
'div', [], $checkboxHtml )
1100 $ret .=
"\t</td>\n";
1102 $ret .= Html::closeElement(
'tr' ) . Html::closeElement(
'table' );
1104 return [ $ret, (bool)$columns[
'changeable'] ];
1111 private function canRemove( $group ) {
1116 $groups[
'remove'] ) || ( $this->isself && in_array( $group, $groups[
'remove-self'] )
1124 private function canAdd( $group ) {
1129 $groups[
'add'] ) || ( $this->isself && in_array( $group, $groups[
'add-self'] )
1154 private function getDisplayUsername(
UserIdentity $user ) {
1156 if ( $user->
getWikiId() !== UserIdentity::LOCAL ) {
1170 $rightsLogPage =
new LogPage(
'rights' );
1171 $output->addHTML(
Html::element(
'h2', [], $rightsLogPage->getName()->text() ) );
1172 LogEventsList::showLogExtract( $output,
'rights',
1173 Title::makeTitle(
NS_USER, $this->getDisplayUsername( $user ) ) );
1185 $search = $this->userNameUtils->getCanonical( $search );
1191 return $this->userNamePrefixSearch
1204class_alias( SpecialUserRights::class,
'UserrightsPage' );
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
wfScript( $script='index')
Get the URL path to a MediaWiki entry point.
wfIsInfinity( $str)
Determine input string is represents as infinity.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Class to simplify the use of log pages.
Class for creating new log entries and inserting them into the database.
Implements a text input field for user names.
A class containing constants representing the names of configuration variables.
const LocalDatabases
Name constant for the LocalDatabases setting, for use with Config::get()
const UserrightsInterwikiDelimiter
Name constant for the UserrightsInterwikiDelimiter setting, for use with Config::get()
This is one of the Core classes and should be read at least once by any new developers.
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
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.
getPageTitle( $subpage=false)
Get a self-referential title object.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getConfig()
Shortcut to get main config object.
getContext()
Gets the context this SpecialPage is executed in.
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.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages By default the message key is the canonical name of...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Show an error when a user tries to do something they do not have the necessary permissions for.
Show an error when the user tries to do something whilst blocked.