Index: trunk/phase3/docs/hooks.txt |
— | — | @@ -1343,6 +1343,18 @@ |
1344 | 1344 | $add : Array of strings corresponding to groups added |
1345 | 1345 | $remove: Array of strings corresponding to groups removed |
1346 | 1346 | |
| 1347 | +'UserrightsChangeableGroups': allows modification of the groups a user may add or remove via Special:UserRights |
| 1348 | +$userrights : UserrightsPage object |
| 1349 | +$user : User object of the current user |
| 1350 | +$addergroups : Array of groups that the user is in |
| 1351 | +&$groups : Array of groups that can be added or removed. In format of |
| 1352 | + array( |
| 1353 | + 'add' => array( addablegroups ), |
| 1354 | + 'remove' => array( removablegroups ), |
| 1355 | + 'add-self' => array( addablegroups to self ), |
| 1356 | + 'remove-self' => array( removable groups from self ) |
| 1357 | + ) |
| 1358 | + |
1347 | 1359 | 'UserRetrieveNewTalks': called when retrieving "You have new messages!" message(s) |
1348 | 1360 | $user: user retrieving new talks messages |
1349 | 1361 | $talks: array of new talks page(s) |
Index: trunk/phase3/includes/specials/SpecialUserrights.php |
— | — | @@ -141,13 +141,8 @@ |
142 | 142 | |
143 | 143 | // Validate input set... |
144 | 144 | $changeable = $this->changeableGroups(); |
145 | | - if ($wgUser->getId() != 0 && $wgUser->getId() == $user->getId()) { |
146 | | - $addable = array_merge($changeable['add'], $wgGroupsAddToSelf); |
147 | | - $removable = array_merge($changeable['remove'], $wgGroupsRemoveFromSelf); |
148 | | - } else { |
149 | | - $addable = $changeable['add']; |
150 | | - $removable = $changeable['remove']; |
151 | | - } |
| 145 | + $addable = array_merge( $changeable['add'], $this->isself ? $changeable['add-self'] : array() ); |
| 146 | + $removable = array_merge( $changeable['remove'], $this->isself ? $changeable['remove-self'] : array() ); |
152 | 147 | |
153 | 148 | $removegroup = array_unique( |
154 | 149 | array_intersect( (array)$removegroup, $removable ) ); |
— | — | @@ -329,14 +324,13 @@ |
330 | 325 | * @return Array: Tuple of addable, then removable groups |
331 | 326 | */ |
332 | 327 | protected function splitGroups( $groups ) { |
333 | | - global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; |
334 | | - list($addable, $removable) = array_values( $this->changeableGroups() ); |
| 328 | + list($addable, $removable, $addself, $removeself) = array_values( $this->changeableGroups() ); |
335 | 329 | |
336 | 330 | $removable = array_intersect( |
337 | | - array_merge($this->isself ? $wgGroupsRemoveFromSelf : array(), $removable), |
| 331 | + array_merge( $this->isself ? $removeself : array(), $removable ), |
338 | 332 | $groups ); // Can't remove groups the user doesn't have |
339 | 333 | $addable = array_diff( |
340 | | - array_merge($this->isself ? $wgGroupsAddToSelf : array(), $addable), |
| 334 | + array_merge( $this->isself ? $addself : array(), $addable ), |
341 | 335 | $groups ); // Can't add groups the user does have |
342 | 336 | |
343 | 337 | return array( $addable, $removable ); |
— | — | @@ -510,10 +504,10 @@ |
511 | 505 | /** |
512 | 506 | * Returns an array of the groups that the user can add/remove. |
513 | 507 | * |
514 | | - * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) ) |
| 508 | + * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) ) |
515 | 509 | */ |
516 | 510 | function changeableGroups() { |
517 | | - global $wgUser, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; |
| 511 | + global $wgUser; |
518 | 512 | |
519 | 513 | if( $wgUser->isAllowed( 'userrights' ) ) { |
520 | 514 | // This group gives the right to modify everything (reverse- |
— | — | @@ -533,8 +527,8 @@ |
534 | 528 | $groups = array( |
535 | 529 | 'add' => array(), |
536 | 530 | 'remove' => array(), |
537 | | - 'add-self' => $wgGroupsAddToSelf, |
538 | | - 'remove-self' => $wgGroupsRemoveFromSelf); |
| 531 | + 'add-self' => array(), |
| 532 | + 'remove-self' => array() ); |
539 | 533 | $addergroups = $wgUser->getEffectiveGroups(); |
540 | 534 | |
541 | 535 | foreach ($addergroups as $addergroup) { |
— | — | @@ -543,7 +537,13 @@ |
544 | 538 | ); |
545 | 539 | $groups['add'] = array_unique( $groups['add'] ); |
546 | 540 | $groups['remove'] = array_unique( $groups['remove'] ); |
| 541 | + $groups['add-self'] = array_unique( $groups['add-self'] ); |
| 542 | + $groups['remove-self'] = array_unique( $groups['remove-self'] ); |
547 | 543 | } |
| 544 | + |
| 545 | + // Run a hook because we can |
| 546 | + wfRunHooks( 'UserrightsChangeableGroups', array( $this, $wgUser, $addergroups, &$groups ) ); |
| 547 | + |
548 | 548 | return $groups; |
549 | 549 | } |
550 | 550 | |
— | — | @@ -551,12 +551,12 @@ |
552 | 552 | * Returns an array of the groups that a particular group can add/remove. |
553 | 553 | * |
554 | 554 | * @param $group String: the group to check for whether it can add/remove |
555 | | - * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) ) |
| 555 | + * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) ) |
556 | 556 | */ |
557 | 557 | private function changeableByGroup( $group ) { |
558 | | - global $wgAddGroups, $wgRemoveGroups; |
| 558 | + global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; |
559 | 559 | |
560 | | - $groups = array( 'add' => array(), 'remove' => array() ); |
| 560 | + $groups = array( 'add' => array(), 'remove' => array(), 'add-self' => array(), 'remove-self' => array() ); |
561 | 561 | if( empty($wgAddGroups[$group]) ) { |
562 | 562 | // Don't add anything to $groups |
563 | 563 | } elseif( $wgAddGroups[$group] === true ) { |
— | — | @@ -573,6 +573,40 @@ |
574 | 574 | } elseif( is_array($wgRemoveGroups[$group]) ) { |
575 | 575 | $groups['remove'] = $wgRemoveGroups[$group]; |
576 | 576 | } |
| 577 | + |
| 578 | + // Re-map numeric keys of AddToSelf/RemoveFromSelf to the 'user' key for backwards compatibility |
| 579 | + if( empty($wgGroupsAddToSelf['user']) || $wgGroupsAddToSelf['user'] !== true ) { |
| 580 | + foreach($wgGroupsAddToSelf as $key => $value) { |
| 581 | + if( is_int($key) ) { |
| 582 | + $wgGroupsAddToSelf['user'][] = $value; |
| 583 | + } |
| 584 | + } |
| 585 | + } |
| 586 | + |
| 587 | + if( empty($wgGroupsRemoveFromSelf['user']) || $wgGroupsRemoveFromSelf['user'] !== true ) { |
| 588 | + foreach($wgGroupsRemoveFromSelf as $key => $value) { |
| 589 | + if( is_int($key) ) { |
| 590 | + $wgGroupsRemoveFromSelf['user'][] = $value; |
| 591 | + } |
| 592 | + } |
| 593 | + } |
| 594 | + |
| 595 | + // Now figure out what groups the user can add to him/herself |
| 596 | + if( empty($wgGroupsAddToSelf[$group]) ) { |
| 597 | + } elseif( $wgGroupsAddToSelf[$group] === true ) { |
| 598 | + // No idea WHY this would be used, but it's there |
| 599 | + $groups['add-self'] = User::getAllGroups(); |
| 600 | + } elseif( is_array($wgGroupsAddToSelf[$group]) ) { |
| 601 | + $groups['add-self'] = $wgGroupsAddToSelf[$group]; |
| 602 | + } |
| 603 | + |
| 604 | + if( empty($wgGroupsRemoveFromSelf[$group]) ) { |
| 605 | + } elseif( $wgGroupsRemoveFromSelf[$group] === true ) { |
| 606 | + $groups['remove-self'] = User::getAllGroups(); |
| 607 | + } elseif( is_array($wgGroupsRemoveFromSelf[$group]) ) { |
| 608 | + $groups['remove-self'] = $wgGroupsRemoveFromSelf[$group]; |
| 609 | + } |
| 610 | + |
577 | 611 | return $groups; |
578 | 612 | } |
579 | 613 | |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -31,7 +31,11 @@ |
32 | 32 | * $wgSQLiteDataDirMode has been introduced as the default directory mode for |
33 | 33 | SQLite data directories on creation. Note this setting is separate from |
34 | 34 | $wgDirectoryMode, which applies to all normal directories created by MediaWiki. |
35 | | - |
| 35 | +* $wgGroupsAddToSelf and $wgGroupsRemoveFromSelf now work more like |
| 36 | + $wgAddGroups and $wgRemoveGroups, where the user must belong to a specified |
| 37 | + group in order to add or remove those groups from themselves. |
| 38 | + Backwards compatibility is maintained. |
| 39 | + |
36 | 40 | === New features in 1.14 === |
37 | 41 | |
38 | 42 | * New URL syntaxes for Special:ListUsers - 'Special:ListUsers/USER' and |
— | — | @@ -80,7 +84,9 @@ |
81 | 85 | option enabled on Special:ProtectedPages |
82 | 86 | * (bug 15157) Special:Watchlist has the same options as Special:Watchlist: |
83 | 87 | Show/Hide logged in users, Show/Hide anonymous, Invert namespace selection |
84 | | - |
| 88 | +* Added hook 'UserrightsChangeableGroups' to allow modification of what |
| 89 | + groups may be added or removed via the Special:UserRights interface. |
| 90 | + |
85 | 91 | === Bug fixes in 1.14 === |
86 | 92 | |
87 | 93 | * (bug 14907) DatabasePostgres::fieldType now defined. |