[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/api/ -> ApiQueryUsers.php (source)

   1  <?php
   2  /**
   3   *
   4   *
   5   * Created on July 30, 2007
   6   *
   7   * Copyright © 2007 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
   8   *
   9   * This program is free software; you can redistribute it and/or modify
  10   * it under the terms of the GNU General Public License as published by
  11   * the Free Software Foundation; either version 2 of the License, or
  12   * (at your option) any later version.
  13   *
  14   * This program is distributed in the hope that it will be useful,
  15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17   * GNU General Public License for more details.
  18   *
  19   * You should have received a copy of the GNU General Public License along
  20   * with this program; if not, write to the Free Software Foundation, Inc.,
  21   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22   * http://www.gnu.org/copyleft/gpl.html
  23   *
  24   * @file
  25   */
  26  
  27  /**
  28   * Query module to get information about a list of users
  29   *
  30   * @ingroup API
  31   */
  32  class ApiQueryUsers extends ApiQueryBase {
  33  
  34      private $tokenFunctions, $prop;
  35  
  36      /**
  37       * Properties whose contents does not depend on who is looking at them. If the usprops field
  38       * contains anything not listed here, the cache mode will never be public for logged-in users.
  39       * @var array
  40       */
  41      protected static $publicProps = array(
  42          // everything except 'blockinfo' which might show hidden records if the user
  43          // making the request has the appropriate permissions
  44          'groups',
  45          'implicitgroups',
  46          'rights',
  47          'editcount',
  48          'registration',
  49          'emailable',
  50          'gender',
  51      );
  52  
  53  	public function __construct( ApiQuery $query, $moduleName ) {
  54          parent::__construct( $query, $moduleName, 'us' );
  55      }
  56  
  57      /**
  58       * Get an array mapping token names to their handler functions.
  59       * The prototype for a token function is func($user)
  60       * it should return a token or false (permission denied)
  61       * @deprecated since 1.24
  62       * @return array Array of tokenname => function
  63       */
  64  	protected function getTokenFunctions() {
  65          // Don't call the hooks twice
  66          if ( isset( $this->tokenFunctions ) ) {
  67              return $this->tokenFunctions;
  68          }
  69  
  70          // If we're in JSON callback mode, no tokens can be obtained
  71          if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
  72              return array();
  73          }
  74  
  75          $this->tokenFunctions = array(
  76              'userrights' => array( 'ApiQueryUsers', 'getUserrightsToken' ),
  77          );
  78          wfRunHooks( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
  79  
  80          return $this->tokenFunctions;
  81      }
  82  
  83      /**
  84       * @deprecated since 1.24
  85       * @param User $user
  86       * @return string
  87       */
  88  	public static function getUserrightsToken( $user ) {
  89          global $wgUser;
  90  
  91          // Since the permissions check for userrights is non-trivial,
  92          // don't bother with it here
  93          return $wgUser->getEditToken( $user->getName() );
  94      }
  95  
  96  	public function execute() {
  97          $params = $this->extractRequestParams();
  98  
  99          if ( !is_null( $params['prop'] ) ) {
 100              $this->prop = array_flip( $params['prop'] );
 101          } else {
 102              $this->prop = array();
 103          }
 104  
 105          $users = (array)$params['users'];
 106          $goodNames = $done = array();
 107          $result = $this->getResult();
 108          // Canonicalize user names
 109          foreach ( $users as $u ) {
 110              $n = User::getCanonicalName( $u );
 111              if ( $n === false || $n === '' ) {
 112                  $vals = array( 'name' => $u, 'invalid' => '' );
 113                  $fit = $result->addValue( array( 'query', $this->getModuleName() ),
 114                      null, $vals );
 115                  if ( !$fit ) {
 116                      $this->setContinueEnumParameter( 'users',
 117                          implode( '|', array_diff( $users, $done ) ) );
 118                      $goodNames = array();
 119                      break;
 120                  }
 121                  $done[] = $u;
 122              } else {
 123                  $goodNames[] = $n;
 124              }
 125          }
 126  
 127          $result = $this->getResult();
 128  
 129          if ( count( $goodNames ) ) {
 130              $this->addTables( 'user' );
 131              $this->addFields( User::selectFields() );
 132              $this->addWhereFld( 'user_name', $goodNames );
 133  
 134              $this->showHiddenUsersAddBlockInfo( isset( $this->prop['blockinfo'] ) );
 135  
 136              $data = array();
 137              $res = $this->select( __METHOD__ );
 138              $this->resetQueryParams();
 139  
 140              // get user groups if needed
 141              if ( isset( $this->prop['groups'] ) || isset( $this->prop['rights'] ) ) {
 142                  $userGroups = array();
 143  
 144                  $this->addTables( 'user' );
 145                  $this->addWhereFld( 'user_name', $goodNames );
 146                  $this->addTables( 'user_groups' );
 147                  $this->addJoinConds( array( 'user_groups' => array( 'INNER JOIN', 'ug_user=user_id' ) ) );
 148                  $this->addFields( array( 'user_name', 'ug_group' ) );
 149                  $userGroupsRes = $this->select( __METHOD__ );
 150  
 151                  foreach ( $userGroupsRes as $row ) {
 152                      $userGroups[$row->user_name][] = $row->ug_group;
 153                  }
 154              }
 155  
 156              foreach ( $res as $row ) {
 157                  // create user object and pass along $userGroups if set
 158                  // that reduces the number of database queries needed in User dramatically
 159                  if ( !isset( $userGroups ) ) {
 160                      $user = User::newFromRow( $row );
 161                  } else {
 162                      if ( !isset( $userGroups[$row->user_name] ) || !is_array( $userGroups[$row->user_name] ) ) {
 163                          $userGroups[$row->user_name] = array();
 164                      }
 165                      $user = User::newFromRow( $row, array( 'user_groups' => $userGroups[$row->user_name] ) );
 166                  }
 167                  $name = $user->getName();
 168  
 169                  $data[$name]['userid'] = $user->getId();
 170                  $data[$name]['name'] = $name;
 171  
 172                  if ( isset( $this->prop['editcount'] ) ) {
 173                      $data[$name]['editcount'] = $user->getEditCount();
 174                  }
 175  
 176                  if ( isset( $this->prop['registration'] ) ) {
 177                      $data[$name]['registration'] = wfTimestampOrNull( TS_ISO_8601, $user->getRegistration() );
 178                  }
 179  
 180                  if ( isset( $this->prop['groups'] ) ) {
 181                      $data[$name]['groups'] = $user->getEffectiveGroups();
 182                  }
 183  
 184                  if ( isset( $this->prop['implicitgroups'] ) ) {
 185                      $data[$name]['implicitgroups'] = $user->getAutomaticGroups();
 186                  }
 187  
 188                  if ( isset( $this->prop['rights'] ) ) {
 189                      $data[$name]['rights'] = $user->getRights();
 190                  }
 191                  if ( $row->ipb_deleted ) {
 192                      $data[$name]['hidden'] = '';
 193                  }
 194                  if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->ipb_by_text ) ) {
 195                      $data[$name]['blockid'] = $row->ipb_id;
 196                      $data[$name]['blockedby'] = $row->ipb_by_text;
 197                      $data[$name]['blockedbyid'] = $row->ipb_by;
 198                      $data[$name]['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
 199                      $data[$name]['blockreason'] = $row->ipb_reason;
 200                      $data[$name]['blockexpiry'] = $row->ipb_expiry;
 201                  }
 202  
 203                  if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() ) {
 204                      $data[$name]['emailable'] = '';
 205                  }
 206  
 207                  if ( isset( $this->prop['gender'] ) ) {
 208                      $gender = $user->getOption( 'gender' );
 209                      if ( strval( $gender ) === '' ) {
 210                          $gender = 'unknown';
 211                      }
 212                      $data[$name]['gender'] = $gender;
 213                  }
 214  
 215                  if ( !is_null( $params['token'] ) ) {
 216                      $tokenFunctions = $this->getTokenFunctions();
 217                      foreach ( $params['token'] as $t ) {
 218                          $val = call_user_func( $tokenFunctions[$t], $user );
 219                          if ( $val === false ) {
 220                              $this->setWarning( "Action '$t' is not allowed for the current user" );
 221                          } else {
 222                              $data[$name][$t . 'token'] = $val;
 223                          }
 224                      }
 225                  }
 226              }
 227          }
 228  
 229          $context = $this->getContext();
 230          // Second pass: add result data to $retval
 231          foreach ( $goodNames as $u ) {
 232              if ( !isset( $data[$u] ) ) {
 233                  $data[$u] = array( 'name' => $u );
 234                  $urPage = new UserrightsPage;
 235                  $urPage->setContext( $context );
 236                  $iwUser = $urPage->fetchUser( $u );
 237  
 238                  if ( $iwUser instanceof UserRightsProxy ) {
 239                      $data[$u]['interwiki'] = '';
 240  
 241                      if ( !is_null( $params['token'] ) ) {
 242                          $tokenFunctions = $this->getTokenFunctions();
 243  
 244                          foreach ( $params['token'] as $t ) {
 245                              $val = call_user_func( $tokenFunctions[$t], $iwUser );
 246                              if ( $val === false ) {
 247                                  $this->setWarning( "Action '$t' is not allowed for the current user" );
 248                              } else {
 249                                  $data[$u][$t . 'token'] = $val;
 250                              }
 251                          }
 252                      }
 253                  } else {
 254                      $data[$u]['missing'] = '';
 255                  }
 256              } else {
 257                  if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) {
 258                      $result->setIndexedTagName( $data[$u]['groups'], 'g' );
 259                  }
 260                  if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) {
 261                      $result->setIndexedTagName( $data[$u]['implicitgroups'], 'g' );
 262                  }
 263                  if ( isset( $this->prop['rights'] ) && isset( $data[$u]['rights'] ) ) {
 264                      $result->setIndexedTagName( $data[$u]['rights'], 'r' );
 265                  }
 266              }
 267  
 268              $fit = $result->addValue( array( 'query', $this->getModuleName() ),
 269                  null, $data[$u] );
 270              if ( !$fit ) {
 271                  $this->setContinueEnumParameter( 'users',
 272                      implode( '|', array_diff( $users, $done ) ) );
 273                  break;
 274              }
 275              $done[] = $u;
 276          }
 277          $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' );
 278      }
 279  
 280      /**
 281       * Gets all the groups that a user is automatically a member of (implicit groups)
 282       *
 283       * @deprecated since 1.20; call User::getAutomaticGroups() directly.
 284       * @param User $user
 285       * @return array
 286       */
 287  	public static function getAutoGroups( $user ) {
 288          wfDeprecated( __METHOD__, '1.20' );
 289  
 290          return $user->getAutomaticGroups();
 291      }
 292  
 293  	public function getCacheMode( $params ) {
 294          if ( isset( $params['token'] ) ) {
 295              return 'private';
 296          } elseif ( array_diff( (array)$params['prop'], static::$publicProps ) ) {
 297              return 'anon-public-user-private';
 298          } else {
 299              return 'public';
 300          }
 301      }
 302  
 303  	public function getAllowedParams() {
 304          return array(
 305              'prop' => array(
 306                  ApiBase::PARAM_DFLT => null,
 307                  ApiBase::PARAM_ISMULTI => true,
 308                  ApiBase::PARAM_TYPE => array(
 309                      'blockinfo',
 310                      'groups',
 311                      'implicitgroups',
 312                      'rights',
 313                      'editcount',
 314                      'registration',
 315                      'emailable',
 316                      'gender',
 317                  )
 318              ),
 319              'users' => array(
 320                  ApiBase::PARAM_ISMULTI => true
 321              ),
 322              'token' => array(
 323                  ApiBase::PARAM_DEPRECATED => true,
 324                  ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() ),
 325                  ApiBase::PARAM_ISMULTI => true
 326              ),
 327          );
 328      }
 329  
 330  	public function getParamDescription() {
 331          return array(
 332              'prop' => array(
 333                  'What pieces of information to include',
 334                  '  blockinfo      - Tags if the user is blocked, by whom, and for what reason',
 335                  '  groups         - Lists all the groups the user(s) belongs to',
 336                  '  implicitgroups - Lists all the groups a user is automatically a member of',
 337                  '  rights         - Lists all the rights the user(s) has',
 338                  '  editcount      - Adds the user\'s edit count',
 339                  '  registration   - Adds the user\'s registration timestamp',
 340                  '  emailable      - Tags if the user can and wants to receive ' .
 341                      'email through [[Special:Emailuser]]',
 342                  '  gender         - Tags the gender of the user. Returns "male", "female", or "unknown"',
 343              ),
 344              'users' => 'A list of users to obtain the same information for',
 345              'token' => 'Which tokens to obtain for each user',
 346          );
 347      }
 348  
 349  	public function getDescription() {
 350          return 'Get information about a list of users.';
 351      }
 352  
 353  	public function getExamples() {
 354          return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender';
 355      }
 356  
 357  	public function getHelpUrls() {
 358          return 'https://www.mediawiki.org/wiki/API:Users';
 359      }
 360  }


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