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 $out->addModuleStyles(
'mediawiki.codex.messagebox.styles' );
227 $this->
addHelpLink(
'Help:Assigning permissions' );
232 $request->wasPosted() &&
233 $request->getCheck(
'saveusergroups' ) &&
234 $this->mTarget !==
null &&
235 $user->matchEditToken( $request->getVal(
'wpEditToken' ), $this->mTarget )
242 if ( !$this->
getAuthority()->isAllowed(
'userrights' ) ) {
243 $block = $user->getBlock();
244 if ( $block && $block->isSitewide() ) {
257 if ( !$fetchedStatus->isOK() ) {
258 $this->
getOutput()->addWikiTextAsInterface(
259 $fetchedStatus->getWikiText(
false,
false, $this->getLanguage() )
266 $conflictCheck = $request->getVal(
'conflictcheck-originalgroups' );
267 $conflictCheck = ( $conflictCheck ===
'' ) ? [] : explode(
',', $conflictCheck );
268 $userGroups = $this->userGroupManager->getUserGroups( $targetUser, IDBAccessObject::READ_LATEST );
270 if ( $userGroups !== $conflictCheck ) {
271 $out->addHTML( Html::errorBox(
272 $this->
msg(
'userrights-conflict' )->parse()
276 $request->getText(
'user-reason' ),
280 if ( $status->isOK() ) {
282 $session->set(
'specialUserrightsSaveSuccess', 1 );
284 $out->redirect( $this->getSuccessURL() );
288 foreach ( $status->getMessages() as $msg ) {
289 $out->addHTML( Html::errorBox(
290 $this->
msg( $msg )->parse()
298 if ( $this->mTarget !==
null ) {
299 $this->editUserGroupsForm( $this->mTarget );
303 private function getSuccessURL() {
304 return $this->
getPageTitle( $this->mTarget )->getFullURL();
331 $unix = strtotime( $expiry );
333 if ( !$unix || $unix === -1 ) {
351 if ( $this->userNameUtils->isTemp( $user->
getName() ) ) {
352 return Status::newFatal(
'userrights-no-tempuser' );
357 $user->
getWikiId() !== UserIdentity::LOCAL &&
358 !$this->tempUserConfig->isKnown() &&
359 $this->tempUserConfig->isReservedName( $user->
getName() )
361 return Status::newFatal(
'userrights-cross-wiki-assignment-for-reserved-name' );
364 $allgroups = $this->userGroupManager->listAllGroups();
368 $existingUGMs = $this->userGroupManager->getUserGroupMemberships( $user );
372 foreach ( $allgroups as $group ) {
375 if ( $this->
getRequest()->getCheck(
"wpGroup-$group" ) ) {
376 $addgroup[] = $group;
380 $expiryDropdown = $this->
getRequest()->getVal(
"wpExpiry-$group" );
381 if ( $expiryDropdown ===
'existing' ) {
385 if ( $expiryDropdown ===
'other' ) {
386 $expiryValue = $this->
getRequest()->getVal(
"wpExpiry-$group-other" );
388 $expiryValue = $expiryDropdown;
394 if ( $groupExpiries[$group] ===
false ) {
395 return Status::newFatal(
'userrights-invalid-expiry', $group );
399 if ( $groupExpiries[$group] && $groupExpiries[$group] <
wfTimestampNow() ) {
400 return Status::newFatal(
'userrights-expiry-in-past', $group );
405 if ( !$this->canRemove( $group ) &&
406 isset( $existingUGMs[$group] ) &&
407 ( $existingUGMs[$group]->getExpiry() ?:
'infinity' ) >
408 ( $groupExpiries[$group] ?:
'infinity' )
410 return Status::newFatal(
'userrights-cannot-shorten-expiry', $group );
414 $removegroup[] = $group;
418 $this->
doSaveUserGroups( $user, $addgroup, $removegroup, $reason, [], $groupExpiries );
420 if ( $user->
getWikiId() === UserIdentity::LOCAL && $this->getRequest()->getCheck(
'wpWatch' ) ) {
421 $this->watchlistManager->addWatchIgnoringRights(
427 return Status::newGood();
446 array $tags = [], array $groupExpiries = []
450 if ( $this->userGroupManager !==
null ) {
452 $userGroupManager = $this->userGroupManager;
455 $userGroupManager = $this->userGroupManagerFactory
456 ->getUserGroupManager( $user->
getWikiId() );
461 $addable = array_merge( $changeable[
'add'],
$isself ? $changeable[
'add-self'] : [] );
462 $removable = array_merge( $changeable[
'remove'],
$isself ? $changeable[
'remove-self'] : [] );
464 $remove = array_unique( array_intersect( $remove, $removable, $groups ) );
465 $add = array_intersect( $add, $addable );
470 $add = array_filter( $add,
471 static function ( $group ) use ( $groups, $groupExpiries, $removable, $ugms ) {
472 if ( isset( $groupExpiries[$group] ) &&
473 !in_array( $group, $removable ) &&
474 isset( $ugms[$group] ) &&
475 ( $ugms[$group]->getExpiry() ?:
'infinity' ) >
476 ( $groupExpiries[$group] ?:
'infinity' )
480 return !in_array( $group, $groups ) || array_key_exists( $group, $groupExpiries );
483 if ( $user->
getWikiId() === UserIdentity::LOCAL ) {
485 $hookUser = $this->userFactory->newFromUserIdentity( $user );
492 $oldGroups = $groups;
494 $newGroups = $oldGroups;
498 foreach ( $remove as $index => $group ) {
500 unset( $remove[$index] );
503 $newGroups = array_diff( $newGroups, $remove );
506 foreach ( $add as $index => $group ) {
507 $expiry = $groupExpiries[$group] ??
null;
508 if ( !$userGroupManager->
addUserToGroup( $user, $group, $expiry,
true ) ) {
509 unset( $add[$index] );
512 $newGroups = array_merge( $newGroups, $add );
514 $newGroups = array_unique( $newGroups );
518 $this->userFactory->invalidateCache( $user );
521 $this->
getHookRunner()->onUserGroupsChanged( $hookUser, $add, $remove,
522 $this->
getUser(), $reason, $oldUGMs, $newUGMs );
524 wfDebug(
'oldGroups: ' . print_r( $oldGroups,
true ) );
525 wfDebug(
'newGroups: ' . print_r( $newGroups,
true ) );
526 wfDebug(
'oldUGMs: ' . print_r( $oldUGMs,
true ) );
527 wfDebug(
'newUGMs: ' . print_r( $newUGMs,
true ) );
530 if ( $newGroups != $oldGroups || $newUGMs != $oldUGMs ) {
531 $this->
addLogEntry( $user, $oldGroups, $newGroups, $reason, $tags, $oldUGMs, $newUGMs );
534 return [ $add, $remove ];
548 return [
'expiry' => $ugm->getExpiry() ];
561 protected function addLogEntry( $user, array $oldGroups, array $newGroups,
string $reason,
562 array $tags, array $oldUGMs, array $newUGMs
566 $oldUGMs = array_map(
static function ( $group ) use ( $oldUGMs ) {
567 return isset( $oldUGMs[$group] ) ?
571 $newUGMs = array_map(
static function ( $group ) use ( $newUGMs ) {
572 return isset( $newUGMs[$group] ) ?
578 $logEntry->setPerformer( $this->
getUser() );
579 $logEntry->setTarget( Title::makeTitle(
NS_USER, $this->getDisplayUsername( $user ) ) );
580 $logEntry->setComment( $reason );
581 $logEntry->setParameters( [
582 '4::oldgroups' => $oldGroups,
583 '5::newgroups' => $newGroups,
584 'oldmetadata' => $oldUGMs,
585 'newmetadata' => $newUGMs,
587 $logid = $logEntry->insert();
588 if ( count( $tags ) ) {
589 $logEntry->addTags( $tags );
591 $logEntry->publish( $logid );
598 private function editUserGroupsForm( $username ) {
599 $status = $this->
fetchUser( $username,
true );
600 if ( !$status->isOK() ) {
601 $this->
getOutput()->addWikiTextAsInterface(
602 $status->getWikiText(
false,
false, $this->getLanguage() )
609 $user = $status->value;
610 '@phan-var UserIdentity $user';
612 $groups = $this->userGroupManager->getUserGroups( $user );
613 $groupMemberships = $this->userGroupManager->getUserGroupMemberships( $user );
630 public function fetchUser( $username, $writing =
true ) {
633 if ( count( $parts ) < 2 ) {
634 $name = trim( $username );
635 $wikiId = UserIdentity::LOCAL;
637 [ $name, $wikiId ] = array_map(
'trim', $parts );
639 if ( WikiMap::isCurrentWikiId( $wikiId ) ) {
640 $wikiId = UserIdentity::LOCAL;
643 !$this->
getAuthority()->isAllowed(
'userrights-interwiki' )
645 return Status::newFatal(
'userrights-no-interwiki' );
648 if ( !in_array( $wikiId, $localDatabases ) ) {
649 return Status::newFatal(
'userrights-nodatabase', $wikiId );
654 if ( $name ===
'' ) {
655 return Status::newFatal(
'nouserspecified' );
658 $userIdentityLookup = $this->actorStoreFactory->getUserIdentityLookup( $wikiId );
659 if ( $name[0] ==
'#' ) {
661 $id = intval( substr( $name, 1 ) );
663 $user = $userIdentityLookup->getUserIdentityByUserId( $id );
666 return Status::newFatal(
'noname' );
670 $name = $this->userNameUtils->getCanonical( $name );
671 if ( $name ===
false ) {
673 return Status::newFatal(
'nosuchusershort', $username );
675 $user = $userIdentityLookup->getUserIdentityByName( $name );
678 if ( $this->userNameUtils->isTemp( $name ) ) {
679 return Status::newFatal(
'userrights-no-group' );
683 return Status::newFatal(
'nosuchusershort', $username );
689 $user->
getWikiId() !== UserIdentity::LOCAL &&
690 !$this->tempUserConfig->isKnown() &&
691 $this->tempUserConfig->isReservedName( $name )
693 return Status::newFatal(
'userrights-no-group' );
696 if ( $user->
getWikiId() === UserIdentity::LOCAL &&
697 $this->userFactory->newFromUserIdentity( $user )->isHidden() &&
698 !$this->getAuthority()->isAllowed(
'hideuser' )
701 return Status::newFatal(
'nosuchusershort', $username );
704 return Status::newGood( $user );
716 return $this->
msg(
'rightsnone' )->inContentLanguage()->text();
718 return implode(
', ', $ids );
728 'class' => HTMLUserTextField::class,
729 'label-message' =>
'userrights-user-editname',
733 'excludetemp' =>
true,
734 'autofocus' => $this->mFetchedUser ===
null,
739 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor, $this->
getContext() );
743 ->setName(
'uluser' )
745 ->setWrapperLegendMsg(
'userrights-lookup-user' )
746 ->setId(
'mw-userrights-form1' )
747 ->setSubmitTextMsg(
'editusergroup' )
749 ->displayForm(
true );
762 $list = $membersList = $tempList = $tempMembersList = [];
763 foreach ( $groupMemberships as $ugm ) {
764 $linkG = UserGroupMembership::getLinkHTML( $ugm, $this->
getContext() );
765 $linkM = UserGroupMembership::getLinkHTML( $ugm, $this->
getContext(), $user->
getName() );
766 if ( $ugm->getExpiry() ) {
767 $tempList[] = $linkG;
768 $tempMembersList[] = $linkM;
771 $membersList[] = $linkM;
777 $autoMembersList = [];
779 if ( $user->
getWikiId() === UserIdentity::LOCAL ) {
781 foreach ( $this->userGroupManager->getUserAutopromoteGroups( $user ) as $group ) {
782 $autoList[] = UserGroupMembership::getLinkHTML( $group, $this->
getContext() );
783 $autoMembersList[] = UserGroupMembership::getLinkHTML( $group, $this->
getContext(), $user->
getName() );
788 $displayedList = $this->
msg(
'userrights-groupsmember-type' )
790 $language->commaList( array_merge( $tempList, $list ) ),
791 $language->commaList( array_merge( $tempMembersList, $membersList ) )
793 $displayedAutolist = $this->
msg(
'userrights-groupsmember-type' )
795 $language->commaList( $autoList ),
796 $language->commaList( $autoMembersList )
800 $count = count( $list ) + count( $tempList );
802 $grouplist = $this->
msg(
'userrights-groupsmember' )
803 ->numParams( $count )
806 $grouplist =
'<p>' . $grouplist .
' ' . $displayedList .
"</p>\n";
809 $count = count( $autoList );
811 $autogrouplistintro = $this->
msg(
'userrights-groupsmember-auto' )
812 ->numParams( $count )
815 $grouplist .=
'<p>' . $autogrouplistintro .
' ' . $displayedAutolist .
"</p>\n";
818 $systemUser = $user->
getWikiId() === UserIdentity::LOCAL
819 && $this->userFactory->newFromUserIdentity( $user )->isSystemUser();
821 $systemusernote = $this->
msg(
'userrights-systemuser' )
824 $grouplist .=
'<p>' . $systemusernote .
"</p>\n";
828 $flags = $systemUser ? 0 : Linker::TOOL_LINKS_EMAIL;
829 $userToolLinks = Linker::userToolLinks(
831 $this->getDisplayUsername( $user ),
836 [ $groupCheckboxes, $canChangeAny ] =
837 $this->groupCheckboxes( $groupMemberships, $user );
844 'name' =>
'editGroup',
845 'id' =>
'mw-userrights-form2'
848 Html::hidden(
'user', $this->mTarget ) .
849 Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken( $this->mTarget ) ) .
851 'conflictcheck-originalgroups',
852 implode(
',', $this->userGroupManager->getUserGroups( $user ) )
854 Html::openElement(
'fieldset' ) .
859 $canChangeAny ?
'userrights-editusergroup' :
'userrights-viewusergroup',
864 $canChangeAny ?
'editinguser' :
'viewinguserrights'
866 ->rawParams( $userToolLinks )->parse()
868 if ( $canChangeAny ) {
870 $this->
msg(
'userrights-groups-help', $user->
getName() )->parse() .
873 Html::openElement(
'table', [
'id' =>
'mw-userrights-table-outer' ] ) .
875 <td class='mw-label'>" .
876 Html::label( $this->msg(
'userrights-reason' )->text(),
'wpReason' ) .
878 <td class='mw-input'>" .
879 Xml::input(
'user-reason', 60, $this->getRequest()->getVal(
'user-reason' ) ??
false, [
884 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT,
890 <td class='mw-submit'>" .
891 Html::submitButton( $this->msg(
'saveusergroups', $user->
getName() )->text(),
892 [
'name' =>
'saveusergroups' ] +
893 Linker::tooltipAndAccesskeyAttribs(
'userrights-set' )
899 <td class='mw-input'>" .
900 Html::check(
'wpWatch',
false, [
'id' =>
'wpWatch' ] ) .
901 ' ' . Html::label( $this->msg(
'userrights-watchuser' )->text(),
'wpWatch' ) .
907 $this->
getOutput()->addHTML( $grouplist );
924 private function groupCheckboxes( $usergroups,
UserIdentity $user ) {
925 $allgroups = $this->userGroupManager->listAllGroups();
929 $expiryOptionsMsg = $this->
msg(
'userrights-expiry-options' )->inContentLanguage();
930 $expiryOptions = $expiryOptionsMsg->isDisabled()
932 : XmlSelect::parseOptionsMessage( $expiryOptionsMsg->text() );
936 $columns = [
'unchangeable' => [],
'changeable' => [] ];
938 foreach ( $allgroups as $group ) {
939 $set = isset( $usergroups[$group] );
943 $canOnlyLengthenExpiry = ( $set && $this->canAdd( $group ) &&
944 !$this->canRemove( $group ) && $usergroups[$group]->getExpiry() );
946 $disabledCheckbox = !(
947 ( $set && $this->canRemove( $group ) ) ||
948 ( !$set && $this->canAdd( $group ) ) );
950 $disabledExpiry = $disabledCheckbox && !$canOnlyLengthenExpiry;
952 $irreversible = !$disabledCheckbox && (
953 ( $set && !$this->canAdd( $group ) ) ||
954 ( !$set && !$this->canRemove( $group ) ) );
958 'disabled' => $disabledCheckbox,
959 'disabled-expiry' => $disabledExpiry,
960 'irreversible' => $irreversible
963 if ( $disabledCheckbox && $disabledExpiry ) {
964 $columns[
'unchangeable'][$group] = $checkbox;
966 $columns[
'changeable'][$group] = $checkbox;
971 $ret .=
Xml::openElement(
'table', [
'class' =>
'mw-userrights-groups' ] ) .
973 foreach ( $columns as $name => $column ) {
974 if ( $column === [] ) {
981 $this->
msg(
'userrights-' . $name .
'-col', count( $column ) )->text()
985 $ret .=
"</tr>\n<tr>\n";
988 foreach ( $columns as $column ) {
989 if ( $column === [] ) {
992 $ret .=
"\t<td style='vertical-align:top;'>\n";
993 foreach ( $column as $group => $checkbox ) {
994 $member = $uiLanguage->getGroupMemberName( $group, $userName );
995 if ( $checkbox[
'irreversible'] ) {
996 $text = $this->
msg(
'userrights-irreversible-marker', $member )->text();
997 } elseif ( $checkbox[
'disabled'] && !$checkbox[
'disabled-expiry'] ) {
998 $text = $this->
msg(
'userrights-no-shorten-expiry-marker', $member )->text();
1003 'type' =>
'checkbox',
'name' =>
"wpGroup-$group",
'value' =>
'1',
1004 'id' =>
"wpGroup-$group",
'checked' => $checkbox[
'set'],
1005 'class' =>
'mw-userrights-groupcheckbox',
1006 'disabled' => $checkbox[
'disabled'],
1007 ] ) .
' ' . Html::label( $text,
"wpGroup-$group" );
1012 $currentExpiry = isset( $usergroups[$group] ) ?
1013 $usergroups[$group]->getExpiry() :
1018 if ( $checkbox[
'set'] &&
1019 ( $checkbox[
'irreversible'] || $checkbox[
'disabled-expiry'] )
1021 if ( $currentExpiry ) {
1022 $expiryFormatted = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser );
1023 $expiryFormattedD = $uiLanguage->userDate( $currentExpiry, $uiUser );
1024 $expiryFormattedT = $uiLanguage->userTime( $currentExpiry, $uiUser );
1026 $this->
msg(
'userrights-expiry-current' )->params(
1027 $expiryFormatted, $expiryFormattedD, $expiryFormattedT )->text() );
1030 $this->
msg(
'userrights-expiry-none' )->text() );
1034 $expiryHtml .= Html::hidden(
"wpExpiry-$group",
1035 $currentExpiry ?
'existing' :
'infinite' );
1036 $expiryHtml .=
"<br />\n";
1039 $this->
msg(
'userrights-expiry' )->text() );
1040 $expiryHtml .= Html::openElement(
'span' );
1043 $expiryFormOptions =
new XmlSelect(
1045 "mw-input-wpExpiry-$group",
1046 $currentExpiry ?
'existing' :
'infinite'
1048 if ( $checkbox[
'disabled-expiry'] ) {
1049 $expiryFormOptions->setAttribute(
'disabled',
'disabled' );
1052 if ( $currentExpiry ) {
1053 $timestamp = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser );
1054 $d = $uiLanguage->userDate( $currentExpiry, $uiUser );
1055 $t = $uiLanguage->userTime( $currentExpiry, $uiUser );
1056 $existingExpiryMessage = $this->
msg(
'userrights-expiry-existing',
1057 $timestamp, $d, $t );
1058 $expiryFormOptions->addOption( $existingExpiryMessage->text(),
'existing' );
1061 $expiryFormOptions->addOption(
1062 $this->
msg(
'userrights-expiry-none' )->text(),
1065 $expiryFormOptions->addOption(
1066 $this->
msg(
'userrights-expiry-othertime' )->text(),
1070 $expiryFormOptions->addOptions( $expiryOptions );
1073 $expiryHtml .= $expiryFormOptions->getHTML() .
'<br />';
1077 'name' =>
"wpExpiry-$group-other",
'size' => 30,
'value' =>
'',
1078 'id' =>
"mw-input-wpExpiry-$group-other",
1079 'class' =>
'mw-userrights-expiryfield',
1080 'disabled' => $checkbox[
'disabled-expiry'],
1085 if ( $checkbox[
'set'] && $checkbox[
'disabled'] ) {
1086 $expiryHtml .= Html::hidden(
"wpGroup-$group", 1 );
1089 $expiryHtml .= Html::closeElement(
'span' );
1093 'id' =>
"mw-userrights-nested-wpGroup-$group",
1094 'class' =>
'mw-userrights-nested',
1096 $checkboxHtml .=
"\t\t\t" . Html::rawElement(
'div', $divAttribs, $expiryHtml ) .
"\n";
1098 $ret .=
"\t\t" . ( ( $checkbox[
'disabled'] && $checkbox[
'disabled-expiry'] )
1099 ? Html::rawElement(
'div', [
'class' =>
'mw-userrights-disabled' ], $checkboxHtml )
1100 : Html::rawElement(
'div', [], $checkboxHtml )
1103 $ret .=
"\t</td>\n";
1105 $ret .= Html::closeElement(
'tr' ) . Html::closeElement(
'table' );
1107 return [ $ret, (bool)$columns[
'changeable'] ];
1114 private function canRemove( $group ) {
1119 $groups[
'remove'] ) || ( $this->isself && in_array( $group, $groups[
'remove-self'] )
1127 private function canAdd( $group ) {
1132 $groups[
'add'] ) || ( $this->isself && in_array( $group, $groups[
'add-self'] )
1157 private function getDisplayUsername(
UserIdentity $user ) {
1159 if ( $user->
getWikiId() !== UserIdentity::LOCAL ) {
1173 $rightsLogPage =
new LogPage(
'rights' );
1174 $output->addHTML(
Html::element(
'h2', [], $rightsLogPage->getName()->text() ) );
1175 LogEventsList::showLogExtract( $output,
'rights',
1176 Title::makeTitle(
NS_USER, $this->getDisplayUsername( $user ) ) );
1188 $search = $this->userNameUtils->getCanonical( $search );
1194 return $this->userNamePrefixSearch
1207class_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.