Index: trunk/phase3/docs/hooks.txt
===================================================================
--- trunk/phase3/docs/hooks.txt (revision 39367)
+++ trunk/phase3/docs/hooks.txt (revision 39368)
@@ -1343,6 +1343,18 @@
$add : Array of strings corresponding to groups added
$remove: Array of strings corresponding to groups removed
+'UserrightsChangeableGroups': allows modification of the groups a user may add or remove via Special:UserRights
+$userrights : UserrightsPage object
+$user : User object of the current user
+$addergroups : Array of groups that the user is in
+&$groups : Array of groups that can be added or removed. In format of
+ array(
+ 'add' => array( addablegroups ),
+ 'remove' => array( removablegroups ),
+ 'add-self' => array( addablegroups to self ),
+ 'remove-self' => array( removable groups from self )
+ )
+
'UserRetrieveNewTalks': called when retrieving "You have new messages!" message(s)
$user: user retrieving new talks messages
$talks: array of new talks page(s)
Index: trunk/phase3/includes/specials/SpecialUserrights.php
===================================================================
--- trunk/phase3/includes/specials/SpecialUserrights.php (revision 39367)
+++ trunk/phase3/includes/specials/SpecialUserrights.php (revision 39368)
@@ -141,13 +141,8 @@
// Validate input set...
$changeable = $this->changeableGroups();
- if ($wgUser->getId() != 0 && $wgUser->getId() == $user->getId()) {
- $addable = array_merge($changeable['add'], $wgGroupsAddToSelf);
- $removable = array_merge($changeable['remove'], $wgGroupsRemoveFromSelf);
- } else {
- $addable = $changeable['add'];
- $removable = $changeable['remove'];
- }
+ $addable = array_merge( $changeable['add'], $this->isself ? $changeable['add-self'] : array() );
+ $removable = array_merge( $changeable['remove'], $this->isself ? $changeable['remove-self'] : array() );
$removegroup = array_unique(
array_intersect( (array)$removegroup, $removable ) );
@@ -329,14 +324,13 @@
* @return Array: Tuple of addable, then removable groups
*/
protected function splitGroups( $groups ) {
- global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
- list($addable, $removable) = array_values( $this->changeableGroups() );
+ list($addable, $removable, $addself, $removeself) = array_values( $this->changeableGroups() );
$removable = array_intersect(
- array_merge($this->isself ? $wgGroupsRemoveFromSelf : array(), $removable),
+ array_merge( $this->isself ? $removeself : array(), $removable ),
$groups ); // Can't remove groups the user doesn't have
$addable = array_diff(
- array_merge($this->isself ? $wgGroupsAddToSelf : array(), $addable),
+ array_merge( $this->isself ? $addself : array(), $addable ),
$groups ); // Can't add groups the user does have
return array( $addable, $removable );
@@ -510,10 +504,10 @@
/**
* Returns an array of the groups that the user can add/remove.
*
- * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) )
+ * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) )
*/
function changeableGroups() {
- global $wgUser, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
+ global $wgUser;
if( $wgUser->isAllowed( 'userrights' ) ) {
// This group gives the right to modify everything (reverse-
@@ -533,8 +527,8 @@
$groups = array(
'add' => array(),
'remove' => array(),
- 'add-self' => $wgGroupsAddToSelf,
- 'remove-self' => $wgGroupsRemoveFromSelf);
+ 'add-self' => array(),
+ 'remove-self' => array() );
$addergroups = $wgUser->getEffectiveGroups();
foreach ($addergroups as $addergroup) {
@@ -543,7 +537,13 @@
);
$groups['add'] = array_unique( $groups['add'] );
$groups['remove'] = array_unique( $groups['remove'] );
+ $groups['add-self'] = array_unique( $groups['add-self'] );
+ $groups['remove-self'] = array_unique( $groups['remove-self'] );
}
+
+ // Run a hook because we can
+ wfRunHooks( 'UserrightsChangeableGroups', array( $this, $wgUser, $addergroups, &$groups ) );
+
return $groups;
}
@@ -551,12 +551,12 @@
* Returns an array of the groups that a particular group can add/remove.
*
* @param $group String: the group to check for whether it can add/remove
- * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) )
+ * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) )
*/
private function changeableByGroup( $group ) {
- global $wgAddGroups, $wgRemoveGroups;
+ global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
- $groups = array( 'add' => array(), 'remove' => array() );
+ $groups = array( 'add' => array(), 'remove' => array(), 'add-self' => array(), 'remove-self' => array() );
if( empty($wgAddGroups[$group]) ) {
// Don't add anything to $groups
} elseif( $wgAddGroups[$group] === true ) {
@@ -573,6 +573,40 @@
} elseif( is_array($wgRemoveGroups[$group]) ) {
$groups['remove'] = $wgRemoveGroups[$group];
}
+
+ // Re-map numeric keys of AddToSelf/RemoveFromSelf to the 'user' key for backwards compatibility
+ if( empty($wgGroupsAddToSelf['user']) || $wgGroupsAddToSelf['user'] !== true ) {
+ foreach($wgGroupsAddToSelf as $key => $value) {
+ if( is_int($key) ) {
+ $wgGroupsAddToSelf['user'][] = $value;
+ }
+ }
+ }
+
+ if( empty($wgGroupsRemoveFromSelf['user']) || $wgGroupsRemoveFromSelf['user'] !== true ) {
+ foreach($wgGroupsRemoveFromSelf as $key => $value) {
+ if( is_int($key) ) {
+ $wgGroupsRemoveFromSelf['user'][] = $value;
+ }
+ }
+ }
+
+ // Now figure out what groups the user can add to him/herself
+ if( empty($wgGroupsAddToSelf[$group]) ) {
+ } elseif( $wgGroupsAddToSelf[$group] === true ) {
+ // No idea WHY this would be used, but it's there
+ $groups['add-self'] = User::getAllGroups();
+ } elseif( is_array($wgGroupsAddToSelf[$group]) ) {
+ $groups['add-self'] = $wgGroupsAddToSelf[$group];
+ }
+
+ if( empty($wgGroupsRemoveFromSelf[$group]) ) {
+ } elseif( $wgGroupsRemoveFromSelf[$group] === true ) {
+ $groups['remove-self'] = User::getAllGroups();
+ } elseif( is_array($wgGroupsRemoveFromSelf[$group]) ) {
+ $groups['remove-self'] = $wgGroupsRemoveFromSelf[$group];
+ }
+
return $groups;
}
Index: trunk/phase3/RELEASE-NOTES
===================================================================
--- trunk/phase3/RELEASE-NOTES (revision 39367)
+++ trunk/phase3/RELEASE-NOTES (revision 39368)
@@ -31,7 +31,11 @@
* $wgSQLiteDataDirMode has been introduced as the default directory mode for
SQLite data directories on creation. Note this setting is separate from
$wgDirectoryMode, which applies to all normal directories created by MediaWiki.
-
+* $wgGroupsAddToSelf and $wgGroupsRemoveFromSelf now work more like
+ $wgAddGroups and $wgRemoveGroups, where the user must belong to a specified
+ group in order to add or remove those groups from themselves.
+ Backwards compatibility is maintained.
+
=== New features in 1.14 ===
* New URL syntaxes for Special:ListUsers - 'Special:ListUsers/USER' and
@@ -80,7 +84,9 @@
option enabled on Special:ProtectedPages
* (bug 15157) Special:Watchlist has the same options as Special:Watchlist:
Show/Hide logged in users, Show/Hide anonymous, Invert namespace selection
-
+* Added hook 'UserrightsChangeableGroups' to allow modification of what
+ groups may be added or removed via the Special:UserRights interface.
+
=== Bug fixes in 1.14 ===
* (bug 14907) DatabasePostgres::fieldType now defined.