diff options
Diffstat (limited to 'includes/SpecialUserrights.php')
-rw-r--r-- | includes/SpecialUserrights.php | 225 |
1 files changed, 213 insertions, 12 deletions
diff --git a/includes/SpecialUserrights.php b/includes/SpecialUserrights.php index d12a9cc4..b97e5168 100644 --- a/includes/SpecialUserrights.php +++ b/includes/SpecialUserrights.php @@ -27,7 +27,7 @@ class UserrightsForm extends HTMLForm { var $action; /** Constructor*/ - function UserrightsForm ( &$request ) { + public function __construct( &$request ) { $this->mPosted = $request->wasPosted(); $this->mRequest =& $request; $this->mName = 'userrights'; @@ -74,7 +74,7 @@ class UserrightsForm extends HTMLForm { * @param string $reason Reason for group change * */ - function saveUserGroups( $username, $removegroup, $addgroup, $reason ) { + function saveUserGroups( $username, $removegroup, $addgroup, $reason = '' ) { global $wgOut; $u = User::newFromName($username); @@ -94,13 +94,17 @@ class UserrightsForm extends HTMLForm { if(isset($removegroup)) { $newGroups = array_diff($newGroups, $removegroup); foreach( $removegroup as $group ) { - $u->removeGroup( $group ); + if ( $this->canRemove( $group ) ) { + $u->removeGroup( $group ); + } } } if(isset($addgroup)) { $newGroups = array_merge($newGroups, $addgroup); foreach( $addgroup as $group ) { - $u->addGroup( $group ); + if ( $this->canAdd( $group ) ) { + $u->addGroup( $group ); + } } } $newGroups = array_unique( $newGroups ); @@ -139,7 +143,7 @@ class UserrightsForm extends HTMLForm { */ function editUserGroupsForm($username) { global $wgOut; - + $user = User::newFromName($username); if( is_null( $user ) ) { $wgOut->addWikiText( wfMsg( 'nouserspecified' ) ); @@ -149,12 +153,38 @@ class UserrightsForm extends HTMLForm { return; } - $groups = $user->getGroups(); - $this->showEditUserGroupsForm( $username, $groups ); + $this->showEditUserGroupsForm( $username, $user->getGroups() ); + $this->showLogFragment( $user, $wgOut ); } - function showEditUserGroupsForm( $username, $groups ) { + /** + * Go through used and available groups and return the ones that this + * form will be able to manipulate based on the current user's system + * permissions. + * + * @param $groups Array: list of groups the given user is in + * @return Array: Tuple of addable, then removable groups + */ + protected function splitGroups( $groups ) { + list($addable, $removable) = array_values( $this->changeableGroups() ); + $removable = array_intersect($removable, $groups ); // Can't remove groups the user doesn't have + $addable = array_diff( $addable, $groups ); // Can't add groups the user does have + + return array( $addable, $removable ); + } + + /** + * Show the form to edit group memberships. + * + * @todo make all CSS-y and semantic + * @param $username String: Name of user you're editing + * @param $groups Array: Array of groups the user is in + */ + protected function showEditUserGroupsForm( $username, $groups ) { global $wgOut, $wgUser; + + list( $addable, $removable ) = $this->splitGroups( $groups ); + $wgOut->addHTML( Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->action, 'name' => 'editGroup' ) ) . Xml::hidden( 'user-editname', $username ) . @@ -162,14 +192,15 @@ class UserrightsForm extends HTMLForm { Xml::openElement( 'fieldset' ) . Xml::element( 'legend', array(), wfMsg( 'userrights-editusergroup' ) ) . $wgOut->parse( wfMsg( 'editinguser', $username ) ) . + $this->explainRights() . "<table border='0'> <tr> <td></td> <td> <table width='400'> <tr> - <td width='50%'>" . HTMLSelectGroups( 'member', $this->mName.'-groupsmember', $groups, true, 6 ) . "</td> - <td width='50%'>" . HTMLSelectGroups( 'available', $this->mName.'-groupsavailable', $groups, true, 6, true) . "</td> + <td width='50%'>" . $this->removeSelect( $removable ) . "</td> + <td width='50%'>" . $this->addSelect( $addable ) . "</td> </tr> </table> </tr> @@ -197,5 +228,175 @@ class UserrightsForm extends HTMLForm { Xml::closeElement( 'form' ) . "\n" ); } -} // end class UserrightsForm -?> + + /** + * Prepare a list of groups the user is able to add and remove + * + * @return string + */ + private function explainRights() { + global $wgUser, $wgLang; + + $out = array(); + list( $add, $remove ) = array_values( $this->changeableGroups() ); + + if( count( $add ) > 0 ) + $out[] = wfMsgExt( 'userrights-available-add', 'parseinline', $wgLang->listToText( $add ) ); + if( count( $remove ) > 0 ) + $out[] = wfMsgExt( 'userrights-available-remove', 'parseinline', $wgLang->listToText( $remove ) ); + + return count( $out ) > 0 + ? implode( ' ', $out ) + : wfMsgExt( 'userrights-available-none', 'parseinline' ); + } + + /** + * Adds the <select> thingie where you can select what groups to remove + * + * @param array $groups The groups that can be removed + * @return string XHTML <select> element + */ + private function removeSelect( $groups ) { + return $this->doSelect( $groups, 'member' ); + } + + /** + * Adds the <select> thingie where you can select what groups to add + * + * @param array $groups The groups that can be added + * @return string XHTML <select> element + */ + private function addSelect( $groups ) { + return $this->doSelect( $groups, 'available' ); + } + + /** + * Adds the <select> thingie where you can select what groups to add/remove + * + * @param array $groups The groups that can be added/removed + * @param string $name 'member' or 'available' + * @return string XHTML <select> element + */ + private function doSelect( $groups, $name ) { + $ret = wfMsgHtml( "{$this->mName}-groups$name" ) . + Xml::openElement( 'select', array( + 'name' => "{$name}[]", + 'multiple' => 'multiple', + 'size' => '6', + 'style' => 'width: 100%;' + ) + ); + foreach ($groups as $group) { + $ret .= Xml::element( 'option', array( 'value' => $group ), User::getGroupName( $group ) ); + } + $ret .= Xml::closeElement( 'select' ); + return $ret; + } + + /** + * @param string $group The name of the group to check + * @return bool Can we remove the group? + */ + private function canRemove( $group ) { + // $this->changeableGroups()['remove'] doesn't work, of course. Thanks, + // PHP. + $groups = $this->changeableGroups(); + return in_array( $group, $groups['remove'] ); + } + + /** + * @param string $group The name of the group to check + * @return bool Can we add the group? + */ + private function canAdd( $group ) { + $groups = $this->changeableGroups(); + return in_array( $group, $groups['add'] ); + } + + /** + * Returns an array of the groups that the user can add/remove. + * + * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) ) + */ + private function changeableGroups() { + global $wgUser; + + $groups = array( 'add' => array(), 'remove' => array() ); + $addergroups = $wgUser->getEffectiveGroups(); + + foreach ($addergroups as $addergroup) { + $groups = array_merge_recursive( + $groups, $this->changeableByGroup($addergroup) + ); + $groups['add'] = array_unique( $groups['add'] ); + $groups['remove'] = array_unique( $groups['remove'] ); + } + return $groups; + } + + /** + * Returns an array of the groups that a particular group can add/remove. + * + * @param String $group The group to check for whether it can add/remove + * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) ) + */ + private function changeableByGroup( $group ) { + global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups; + + if( empty($wgGroupPermissions[$group]['userrights']) ) { + // This group doesn't give the right to modify anything + return array( 'add' => array(), 'remove' => array() ); + } + if( empty($wgAddGroups[$group]) and empty($wgRemoveGroups[$group]) ) { + // This group gives the right to modify everything (reverse- + // compatibility with old "userrights lets you change + // everything") + return array( + 'add' => User::getAllGroups(), + 'remove' => User::getAllGroups() + ); + } + + // Okay, it's not so simple, we have to go through the arrays + $groups = array( 'add' => array(), 'remove' => array() ); + if( empty($wgAddGroups[$group]) ) { + // Don't add anything to $groups + } elseif( $wgAddGroups[$group] === true ) { + // You get everything + $groups['add'] = User::getAllGroups(); + } elseif( is_array($wgAddGroups[$group]) ) { + $groups['add'] = $wgAddGroups[$group]; + } + + // Same thing for remove + if( empty($wgRemoveGroups[$group]) ) { + } elseif($wgRemoveGroups[$group] === true ) { + $groups['remove'] = User::getAllGroups(); + } elseif( is_array($wgRemoveGroups[$group]) ) { + $groups['remove'] = $wgRemoveGroups[$group]; + } + return $groups; + } + + /** + * Show a rights log fragment for the specified user + * + * @param User $user User to show log for + * @param OutputPage $output OutputPage to use + */ + protected function showLogFragment( $user, $output ) { + $viewer = new LogViewer( + new LogReader( + new FauxRequest( + array( + 'type' => 'rights', + 'page' => $user->getUserPage()->getPrefixedUrl(), + ) + ) + ) + ); + $output->addHtml( "<h2>" . htmlspecialchars( LogPage::logName( 'rights' ) ) . "</h2>\n" ); + $viewer->showList( $output ); + } + +}
\ No newline at end of file |