[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/specials/ -> SpecialUserrights.php (source)

   1  <?php
   2  /**
   3   * Implements Special:Userrights
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @ingroup SpecialPage
  22   */
  23  
  24  /**
  25   * Special page to allow managing user group membership
  26   *
  27   * @ingroup SpecialPage
  28   */
  29  class UserrightsPage extends SpecialPage {
  30      # The target of the local right-adjuster's interest.  Can be gotten from
  31      # either a GET parameter or a subpage-style parameter, so have a member
  32      # variable for it.
  33      protected $mTarget;
  34      protected $isself = false;
  35  
  36  	public function __construct() {
  37          parent::__construct( 'Userrights' );
  38      }
  39  
  40  	public function isRestricted() {
  41          return true;
  42      }
  43  
  44  	public function userCanExecute( User $user ) {
  45          return $this->userCanChangeRights( $user, false );
  46      }
  47  
  48      /**
  49       * @param User $user
  50       * @param bool $checkIfSelf
  51       * @return bool
  52       */
  53  	public function userCanChangeRights( $user, $checkIfSelf = true ) {
  54          $available = $this->changeableGroups();
  55          if ( $user->getId() == 0 ) {
  56              return false;
  57          }
  58  
  59          return !empty( $available['add'] )
  60              || !empty( $available['remove'] )
  61              || ( ( $this->isself || !$checkIfSelf ) &&
  62                  ( !empty( $available['add-self'] )
  63                      || !empty( $available['remove-self'] ) ) );
  64      }
  65  
  66      /**
  67       * Manage forms to be shown according to posted data.
  68       * Depending on the submit button used, call a form or a save function.
  69       *
  70       * @param string|null $par String if any subpage provided, else null
  71       * @throws UserBlockedError|PermissionsError
  72       */
  73  	public function execute( $par ) {
  74          // If the visitor doesn't have permissions to assign or remove
  75          // any groups, it's a bit silly to give them the user search prompt.
  76  
  77          $user = $this->getUser();
  78  
  79          /*
  80           * If the user is blocked and they only have "partial" access
  81           * (e.g. they don't have the userrights permission), then don't
  82           * allow them to use Special:UserRights.
  83           */
  84          if ( $user->isBlocked() && !$user->isAllowed( 'userrights' ) ) {
  85              throw new UserBlockedError( $user->getBlock() );
  86          }
  87  
  88          $request = $this->getRequest();
  89  
  90          if ( $par !== null ) {
  91              $this->mTarget = $par;
  92          } else {
  93              $this->mTarget = $request->getVal( 'user' );
  94          }
  95  
  96          $available = $this->changeableGroups();
  97  
  98          if ( $this->mTarget === null ) {
  99              /*
 100               * If the user specified no target, and they can only
 101               * edit their own groups, automatically set them as the
 102               * target.
 103               */
 104              if ( !count( $available['add'] ) && !count( $available['remove'] ) ) {
 105                  $this->mTarget = $user->getName();
 106              }
 107          }
 108  
 109          if ( User::getCanonicalName( $this->mTarget ) == $user->getName() ) {
 110              $this->isself = true;
 111          }
 112  
 113          if ( !$this->userCanChangeRights( $user, true ) ) {
 114              if ( $this->isself && $request->getCheck( 'success' ) ) {
 115                  // bug 48609: if the user just removed its own rights, this would
 116                  // leads it in a "permissions error" page. In that case, show a
 117                  // message that it can't anymore use this page instead of an error
 118                  $this->setHeaders();
 119                  $out = $this->getOutput();
 120                  $out->wrapWikiMsg( "<div class=\"successbox\">\n$1\n</div>", 'userrights-removed-self' );
 121                  $out->returnToMain();
 122  
 123                  return;
 124              }
 125  
 126              // @todo FIXME: There may be intermediate groups we can mention.
 127              $msg = $user->isAnon() ? 'userrights-nologin' : 'userrights-notallowed';
 128              throw new PermissionsError( null, array( array( $msg ) ) );
 129          }
 130  
 131          $this->checkReadOnly();
 132  
 133          $this->setHeaders();
 134          $this->outputHeader();
 135  
 136          $out = $this->getOutput();
 137          $out->addModuleStyles( 'mediawiki.special' );
 138  
 139          // show the general form
 140          if ( count( $available['add'] ) || count( $available['remove'] ) ) {
 141              $this->switchForm();
 142          }
 143  
 144          if (
 145              $request->wasPosted() &&
 146              $request->getCheck( 'saveusergroups' ) &&
 147              $user->matchEditToken( $request->getVal( 'wpEditToken' ), $this->mTarget )
 148          ) {
 149              // save settings
 150              $status = $this->fetchUser( $this->mTarget );
 151              if ( !$status->isOK() ) {
 152                  $this->getOutput()->addWikiText( $status->getWikiText() );
 153  
 154                  return;
 155              }
 156  
 157              $targetUser = $status->value;
 158              if ( $targetUser instanceof User ) { // UserRightsProxy doesn't have this method (bug 61252)
 159                  $targetUser->clearInstanceCache(); // bug 38989
 160              }
 161  
 162              if ( $request->getVal( 'conflictcheck-originalgroups' )
 163                  !== implode( ',', $targetUser->getGroups() )
 164              ) {
 165                  $out->addWikiMsg( 'userrights-conflict' );
 166              } else {
 167                  $this->saveUserGroups(
 168                      $this->mTarget,
 169                      $request->getVal( 'user-reason' ),
 170                      $targetUser
 171                  );
 172  
 173                  $out->redirect( $this->getSuccessURL() );
 174  
 175                  return;
 176              }
 177          }
 178  
 179          // show some more forms
 180          if ( $this->mTarget !== null ) {
 181              $this->editUserGroupsForm( $this->mTarget );
 182          }
 183      }
 184  
 185  	function getSuccessURL() {
 186          return $this->getPageTitle( $this->mTarget )->getFullURL( array( 'success' => 1 ) );
 187      }
 188  
 189      /**
 190       * Save user groups changes in the database.
 191       * Data comes from the editUserGroupsForm() form function
 192       *
 193       * @param string $username Username to apply changes to.
 194       * @param string $reason Reason for group change
 195       * @param User|UserRightsProxy $user Target user object.
 196       * @return null
 197       */
 198  	function saveUserGroups( $username, $reason, $user ) {
 199          $allgroups = $this->getAllGroups();
 200          $addgroup = array();
 201          $removegroup = array();
 202  
 203          // This could possibly create a highly unlikely race condition if permissions are changed between
 204          //  when the form is loaded and when the form is saved. Ignoring it for the moment.
 205          foreach ( $allgroups as $group ) {
 206              // We'll tell it to remove all unchecked groups, and add all checked groups.
 207              // Later on, this gets filtered for what can actually be removed
 208              if ( $this->getRequest()->getCheck( "wpGroup-$group" ) ) {
 209                  $addgroup[] = $group;
 210              } else {
 211                  $removegroup[] = $group;
 212              }
 213          }
 214  
 215          $this->doSaveUserGroups( $user, $addgroup, $removegroup, $reason );
 216      }
 217  
 218      /**
 219       * Save user groups changes in the database.
 220       *
 221       * @param User $user
 222       * @param array $add Array of groups to add
 223       * @param array $remove Array of groups to remove
 224       * @param string $reason Reason for group change
 225       * @return array Tuple of added, then removed groups
 226       */
 227  	function doSaveUserGroups( $user, $add, $remove, $reason = '' ) {
 228          global $wgAuth;
 229  
 230          // Validate input set...
 231          $isself = ( $user->getName() == $this->getUser()->getName() );
 232          $groups = $user->getGroups();
 233          $changeable = $this->changeableGroups();
 234          $addable = array_merge( $changeable['add'], $isself ? $changeable['add-self'] : array() );
 235          $removable = array_merge( $changeable['remove'], $isself ? $changeable['remove-self'] : array() );
 236  
 237          $remove = array_unique(
 238              array_intersect( (array)$remove, $removable, $groups ) );
 239          $add = array_unique( array_diff(
 240              array_intersect( (array)$add, $addable ),
 241              $groups )
 242          );
 243  
 244          $oldGroups = $user->getGroups();
 245          $newGroups = $oldGroups;
 246  
 247          // remove then add groups
 248          if ( $remove ) {
 249              $newGroups = array_diff( $newGroups, $remove );
 250              foreach ( $remove as $group ) {
 251                  $user->removeGroup( $group );
 252              }
 253          }
 254          if ( $add ) {
 255              $newGroups = array_merge( $newGroups, $add );
 256              foreach ( $add as $group ) {
 257                  $user->addGroup( $group );
 258              }
 259          }
 260          $newGroups = array_unique( $newGroups );
 261  
 262          // Ensure that caches are cleared
 263          $user->invalidateCache();
 264  
 265          // update groups in external authentication database
 266          $wgAuth->updateExternalDBGroups( $user, $add, $remove );
 267  
 268          wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) . "\n" );
 269          wfDebug( 'newGroups: ' . print_r( $newGroups, true ) . "\n" );
 270          wfRunHooks( 'UserRights', array( &$user, $add, $remove ) );
 271  
 272          if ( $newGroups != $oldGroups ) {
 273              $this->addLogEntry( $user, $oldGroups, $newGroups, $reason );
 274          }
 275  
 276          return array( $add, $remove );
 277      }
 278  
 279      /**
 280       * Add a rights log entry for an action.
 281       * @param User $user
 282       * @param array $oldGroups
 283       * @param array $newGroups
 284       * @param array $reason
 285       */
 286  	function addLogEntry( $user, $oldGroups, $newGroups, $reason ) {
 287          $logEntry = new ManualLogEntry( 'rights', 'rights' );
 288          $logEntry->setPerformer( $this->getUser() );
 289          $logEntry->setTarget( $user->getUserPage() );
 290          $logEntry->setComment( $reason );
 291          $logEntry->setParameters( array(
 292              '4::oldgroups' => $oldGroups,
 293              '5::newgroups' => $newGroups,
 294          ) );
 295          $logid = $logEntry->insert();
 296          $logEntry->publish( $logid );
 297      }
 298  
 299      /**
 300       * Edit user groups membership
 301       * @param string $username Name of the user.
 302       */
 303  	function editUserGroupsForm( $username ) {
 304          $status = $this->fetchUser( $username );
 305          if ( !$status->isOK() ) {
 306              $this->getOutput()->addWikiText( $status->getWikiText() );
 307  
 308              return;
 309          } else {
 310              $user = $status->value;
 311          }
 312  
 313          $groups = $user->getGroups();
 314  
 315          $this->showEditUserGroupsForm( $user, $groups );
 316  
 317          // This isn't really ideal logging behavior, but let's not hide the
 318          // interwiki logs if we're using them as is.
 319          $this->showLogFragment( $user, $this->getOutput() );
 320      }
 321  
 322      /**
 323       * Normalize the input username, which may be local or remote, and
 324       * return a user (or proxy) object for manipulating it.
 325       *
 326       * Side effects: error output for invalid access
 327       * @param string $username
 328       * @return Status
 329       */
 330  	public function fetchUser( $username ) {
 331          $parts = explode( $this->getConfig()->get( 'UserrightsInterwikiDelimiter' ), $username );
 332          if ( count( $parts ) < 2 ) {
 333              $name = trim( $username );
 334              $database = '';
 335          } else {
 336              list( $name, $database ) = array_map( 'trim', $parts );
 337  
 338              if ( $database == wfWikiID() ) {
 339                  $database = '';
 340              } else {
 341                  if ( !$this->getUser()->isAllowed( 'userrights-interwiki' ) ) {
 342                      return Status::newFatal( 'userrights-no-interwiki' );
 343                  }
 344                  if ( !UserRightsProxy::validDatabase( $database ) ) {
 345                      return Status::newFatal( 'userrights-nodatabase', $database );
 346                  }
 347              }
 348          }
 349  
 350          if ( $name === '' ) {
 351              return Status::newFatal( 'nouserspecified' );
 352          }
 353  
 354          if ( $name[0] == '#' ) {
 355              // Numeric ID can be specified...
 356              // We'll do a lookup for the name internally.
 357              $id = intval( substr( $name, 1 ) );
 358  
 359              if ( $database == '' ) {
 360                  $name = User::whoIs( $id );
 361              } else {
 362                  $name = UserRightsProxy::whoIs( $database, $id );
 363              }
 364  
 365              if ( !$name ) {
 366                  return Status::newFatal( 'noname' );
 367              }
 368          } else {
 369              $name = User::getCanonicalName( $name );
 370              if ( $name === false ) {
 371                  // invalid name
 372                  return Status::newFatal( 'nosuchusershort', $username );
 373              }
 374          }
 375  
 376          if ( $database == '' ) {
 377              $user = User::newFromName( $name );
 378          } else {
 379              $user = UserRightsProxy::newFromName( $database, $name );
 380          }
 381  
 382          if ( !$user || $user->isAnon() ) {
 383              return Status::newFatal( 'nosuchusershort', $username );
 384          }
 385  
 386          return Status::newGood( $user );
 387      }
 388  
 389  	function makeGroupNameList( $ids ) {
 390          if ( empty( $ids ) ) {
 391              return $this->msg( 'rightsnone' )->inContentLanguage()->text();
 392          } else {
 393              return implode( ', ', $ids );
 394          }
 395      }
 396  
 397      /**
 398       * Make a list of group names to be stored as parameter for log entries
 399       *
 400       * @deprecated since 1.21; use LogFormatter instead.
 401       * @param array $ids
 402       * @return string
 403       */
 404  	function makeGroupNameListForLog( $ids ) {
 405          wfDeprecated( __METHOD__, '1.21' );
 406  
 407          if ( empty( $ids ) ) {
 408              return '';
 409          } else {
 410              return $this->makeGroupNameList( $ids );
 411          }
 412      }
 413  
 414      /**
 415       * Output a form to allow searching for a user
 416       */
 417  	function switchForm() {
 418          $this->getOutput()->addHTML(
 419              Html::openElement(
 420                  'form',
 421                  array(
 422                      'method' => 'get',
 423                      'action' => wfScript(),
 424                      'name' => 'uluser',
 425                      'id' => 'mw-userrights-form1'
 426                  )
 427              ) .
 428              Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) .
 429              Xml::fieldset( $this->msg( 'userrights-lookup-user' )->text() ) .
 430              Xml::inputLabel(
 431                  $this->msg( 'userrights-user-editname' )->text(),
 432                  'user',
 433                  'username',
 434                  30,
 435                  str_replace( '_', ' ', $this->mTarget ),
 436                  array( 'autofocus' => true )
 437              ) . ' ' .
 438              Xml::submitButton( $this->msg( 'editusergroup' )->text() ) .
 439              Html::closeElement( 'fieldset' ) .
 440              Html::closeElement( 'form' ) . "\n"
 441          );
 442      }
 443  
 444      /**
 445       * Go through used and available groups and return the ones that this
 446       * form will be able to manipulate based on the current user's system
 447       * permissions.
 448       *
 449       * @param array $groups List of groups the given user is in
 450       * @return array Tuple of addable, then removable groups
 451       */
 452  	protected function splitGroups( $groups ) {
 453          list( $addable, $removable, $addself, $removeself ) = array_values( $this->changeableGroups() );
 454  
 455          $removable = array_intersect(
 456              array_merge( $this->isself ? $removeself : array(), $removable ),
 457              $groups
 458          ); // Can't remove groups the user doesn't have
 459          $addable = array_diff(
 460              array_merge( $this->isself ? $addself : array(), $addable ),
 461              $groups
 462          ); // Can't add groups the user does have
 463  
 464          return array( $addable, $removable );
 465      }
 466  
 467      /**
 468       * Show the form to edit group memberships.
 469       *
 470       * @param User|UserRightsProxy $user User or UserRightsProxy you're editing
 471       * @param array $groups Array of groups the user is in
 472       */
 473  	protected function showEditUserGroupsForm( $user, $groups ) {
 474          $list = array();
 475          $membersList = array();
 476          foreach ( $groups as $group ) {
 477              $list[] = self::buildGroupLink( $group );
 478              $membersList[] = self::buildGroupMemberLink( $group );
 479          }
 480  
 481          $autoList = array();
 482          $autoMembersList = array();
 483          if ( $user instanceof User ) {
 484              foreach ( Autopromote::getAutopromoteGroups( $user ) as $group ) {
 485                  $autoList[] = self::buildGroupLink( $group );
 486                  $autoMembersList[] = self::buildGroupMemberLink( $group );
 487              }
 488          }
 489  
 490          $language = $this->getLanguage();
 491          $displayedList = $this->msg( 'userrights-groupsmember-type',
 492              $language->listToText( $list ),
 493              $language->listToText( $membersList )
 494          )->plain();
 495          $displayedAutolist = $this->msg( 'userrights-groupsmember-type',
 496              $language->listToText( $autoList ),
 497              $language->listToText( $autoMembersList )
 498          )->plain();
 499  
 500          $grouplist = '';
 501          $count = count( $list );
 502          if ( $count > 0 ) {
 503              $grouplist = $this->msg( 'userrights-groupsmember', $count, $user->getName() )->parse();
 504              $grouplist = '<p>' . $grouplist . ' ' . $displayedList . "</p>\n";
 505          }
 506  
 507          $count = count( $autoList );
 508          if ( $count > 0 ) {
 509              $autogrouplistintro = $this->msg( 'userrights-groupsmember-auto', $count, $user->getName() )
 510                  ->parse();
 511              $grouplist .= '<p>' . $autogrouplistintro . ' ' . $displayedAutolist . "</p>\n";
 512          }
 513  
 514          $userToolLinks = Linker::userToolLinks(
 515              $user->getId(),
 516              $user->getName(),
 517              false, /* default for redContribsWhenNoEdits */
 518              Linker::TOOL_LINKS_EMAIL /* Add "send e-mail" link */
 519          );
 520  
 521          $this->getOutput()->addHTML(
 522              Xml::openElement(
 523                  'form',
 524                  array(
 525                      'method' => 'post',
 526                      'action' => $this->getPageTitle()->getLocalURL(),
 527                      'name' => 'editGroup',
 528                      'id' => 'mw-userrights-form2'
 529                  )
 530              ) .
 531              Html::hidden( 'user', $this->mTarget ) .
 532              Html::hidden( 'wpEditToken', $this->getUser()->getEditToken( $this->mTarget ) ) .
 533              Html::hidden(
 534                  'conflictcheck-originalgroups',
 535                  implode( ',', $user->getGroups() )
 536              ) . // Conflict detection
 537              Xml::openElement( 'fieldset' ) .
 538              Xml::element(
 539                  'legend',
 540                  array(),
 541                  $this->msg( 'userrights-editusergroup', $user->getName() )->text()
 542              ) .
 543              $this->msg( 'editinguser' )->params( wfEscapeWikiText( $user->getName() ) )
 544                  ->rawParams( $userToolLinks )->parse() .
 545              $this->msg( 'userrights-groups-help', $user->getName() )->parse() .
 546              $grouplist .
 547              $this->groupCheckboxes( $groups, $user ) .
 548              Xml::openElement( 'table', array( 'id' => 'mw-userrights-table-outer' ) ) .
 549                  "<tr>
 550                      <td class='mw-label'>" .
 551                          Xml::label( $this->msg( 'userrights-reason' )->text(), 'wpReason' ) .
 552                      "</td>
 553                      <td class='mw-input'>" .
 554                          Xml::input( 'user-reason', 60, $this->getRequest()->getVal( 'user-reason', false ),
 555                              array( 'id' => 'wpReason', 'maxlength' => 255 ) ) .
 556                      "</td>
 557                  </tr>
 558                  <tr>
 559                      <td></td>
 560                      <td class='mw-submit'>" .
 561                          Xml::submitButton( $this->msg( 'saveusergroups' )->text(),
 562                              array( 'name' => 'saveusergroups' ) +
 563                                  Linker::tooltipAndAccesskeyAttribs( 'userrights-set' )
 564                          ) .
 565                      "</td>
 566                  </tr>" .
 567              Xml::closeElement( 'table' ) . "\n" .
 568              Xml::closeElement( 'fieldset' ) .
 569              Xml::closeElement( 'form' ) . "\n"
 570          );
 571      }
 572  
 573      /**
 574       * Format a link to a group description page
 575       *
 576       * @param string $group
 577       * @return string
 578       */
 579  	private static function buildGroupLink( $group ) {
 580          return User::makeGroupLinkHtml( $group, User::getGroupName( $group ) );
 581      }
 582  
 583      /**
 584       * Format a link to a group member description page
 585       *
 586       * @param string $group
 587       * @return string
 588       */
 589  	private static function buildGroupMemberLink( $group ) {
 590          return User::makeGroupLinkHtml( $group, User::getGroupMember( $group ) );
 591      }
 592  
 593      /**
 594       * Returns an array of all groups that may be edited
 595       * @return array Array of groups that may be edited.
 596       */
 597  	protected static function getAllGroups() {
 598          return User::getAllGroups();
 599      }
 600  
 601      /**
 602       * Adds a table with checkboxes where you can select what groups to add/remove
 603       *
 604       * @todo Just pass the username string?
 605       * @param array $usergroups Groups the user belongs to
 606       * @param User $user
 607       * @return string XHTML table element with checkboxes
 608       */
 609  	private function groupCheckboxes( $usergroups, $user ) {
 610          $allgroups = $this->getAllGroups();
 611          $ret = '';
 612  
 613          // Put all column info into an associative array so that extensions can
 614          // more easily manage it.
 615          $columns = array( 'unchangeable' => array(), 'changeable' => array() );
 616  
 617          foreach ( $allgroups as $group ) {
 618              $set = in_array( $group, $usergroups );
 619              // Should the checkbox be disabled?
 620              $disabled = !(
 621                  ( $set && $this->canRemove( $group ) ) ||
 622                  ( !$set && $this->canAdd( $group ) ) );
 623              // Do we need to point out that this action is irreversible?
 624              $irreversible = !$disabled && (
 625                  ( $set && !$this->canAdd( $group ) ) ||
 626                  ( !$set && !$this->canRemove( $group ) ) );
 627  
 628              $checkbox = array(
 629                  'set' => $set,
 630                  'disabled' => $disabled,
 631                  'irreversible' => $irreversible
 632              );
 633  
 634              if ( $disabled ) {
 635                  $columns['unchangeable'][$group] = $checkbox;
 636              } else {
 637                  $columns['changeable'][$group] = $checkbox;
 638              }
 639          }
 640  
 641          // Build the HTML table
 642          $ret .= Xml::openElement( 'table', array( 'class' => 'mw-userrights-groups' ) ) .
 643              "<tr>\n";
 644          foreach ( $columns as $name => $column ) {
 645              if ( $column === array() ) {
 646                  continue;
 647              }
 648              // Messages: userrights-changeable-col, userrights-unchangeable-col
 649              $ret .= Xml::element(
 650                  'th',
 651                  null,
 652                  $this->msg( 'userrights-' . $name . '-col', count( $column ) )->text()
 653              );
 654          }
 655  
 656          $ret .= "</tr>\n<tr>\n";
 657          foreach ( $columns as $column ) {
 658              if ( $column === array() ) {
 659                  continue;
 660              }
 661              $ret .= "\t<td style='vertical-align:top;'>\n";
 662              foreach ( $column as $group => $checkbox ) {
 663                  $attr = $checkbox['disabled'] ? array( 'disabled' => 'disabled' ) : array();
 664  
 665                  $member = User::getGroupMember( $group, $user->getName() );
 666                  if ( $checkbox['irreversible'] ) {
 667                      $text = $this->msg( 'userrights-irreversible-marker', $member )->escaped();
 668                  } else {
 669                      $text = htmlspecialchars( $member );
 670                  }
 671                  $checkboxHtml = Xml::checkLabel( $text, "wpGroup-" . $group,
 672                      "wpGroup-" . $group, $checkbox['set'], $attr );
 673                  $ret .= "\t\t" . ( $checkbox['disabled']
 674                      ? Xml::tags( 'span', array( 'class' => 'mw-userrights-disabled' ), $checkboxHtml )
 675                      : $checkboxHtml
 676                  ) . "<br />\n";
 677              }
 678              $ret .= "\t</td>\n";
 679          }
 680          $ret .= Xml::closeElement( 'tr' ) . Xml::closeElement( 'table' );
 681  
 682          return $ret;
 683      }
 684  
 685      /**
 686       * @param string $group The name of the group to check
 687       * @return bool Can we remove the group?
 688       */
 689  	private function canRemove( $group ) {
 690          // $this->changeableGroups()['remove'] doesn't work, of course. Thanks, PHP.
 691          $groups = $this->changeableGroups();
 692  
 693          return in_array(
 694              $group,
 695              $groups['remove'] ) || ( $this->isself && in_array( $group, $groups['remove-self'] )
 696          );
 697      }
 698  
 699      /**
 700       * @param string $group The name of the group to check
 701       * @return bool Can we add the group?
 702       */
 703  	private function canAdd( $group ) {
 704          $groups = $this->changeableGroups();
 705  
 706          return in_array(
 707              $group,
 708              $groups['add'] ) || ( $this->isself && in_array( $group, $groups['add-self'] )
 709          );
 710      }
 711  
 712      /**
 713       * Returns $this->getUser()->changeableGroups()
 714       *
 715       * @return array Array(
 716       *   'add' => array( addablegroups ),
 717       *   'remove' => array( removablegroups ),
 718       *   'add-self' => array( addablegroups to self ),
 719       *   'remove-self' => array( removable groups from self )
 720       *  )
 721       */
 722  	function changeableGroups() {
 723          return $this->getUser()->changeableGroups();
 724      }
 725  
 726      /**
 727       * Show a rights log fragment for the specified user
 728       *
 729       * @param User $user User to show log for
 730       * @param OutputPage $output OutputPage to use
 731       */
 732  	protected function showLogFragment( $user, $output ) {
 733          $rightsLogPage = new LogPage( 'rights' );
 734          $output->addHTML( Xml::element( 'h2', null, $rightsLogPage->getName()->text() ) );
 735          LogEventsList::showLogExtract( $output, 'rights', $user->getUserPage() );
 736      }
 737  
 738  	protected function getGroupName() {
 739          return 'users';
 740      }
 741  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1