MediaWiki  REL1_21
ApiQueryUsers.php
Go to the documentation of this file.
00001 <?php
00032 class ApiQueryUsers extends ApiQueryBase {
00033 
00034         private $tokenFunctions, $prop;
00035 
00036         public function __construct( $query, $moduleName ) {
00037                 parent::__construct( $query, $moduleName, 'us' );
00038         }
00039 
00046         protected function getTokenFunctions() {
00047                 // Don't call the hooks twice
00048                 if ( isset( $this->tokenFunctions ) ) {
00049                         return $this->tokenFunctions;
00050                 }
00051 
00052                 // If we're in JSON callback mode, no tokens can be obtained
00053                 if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
00054                         return array();
00055                 }
00056 
00057                 $this->tokenFunctions = array(
00058                         'userrights' => array( 'ApiQueryUsers', 'getUserrightsToken' ),
00059                 );
00060                 wfRunHooks( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
00061                 return $this->tokenFunctions;
00062         }
00063 
00068         public static function getUserrightsToken( $user ) {
00069                 global $wgUser;
00070                 // Since the permissions check for userrights is non-trivial,
00071                 // don't bother with it here
00072                 return $wgUser->getEditToken( $user->getName() );
00073         }
00074 
00075         public function execute() {
00076                 $params = $this->extractRequestParams();
00077 
00078                 if ( !is_null( $params['prop'] ) ) {
00079                         $this->prop = array_flip( $params['prop'] );
00080                 } else {
00081                         $this->prop = array();
00082                 }
00083 
00084                 $users = (array)$params['users'];
00085                 $goodNames = $done = array();
00086                 $result = $this->getResult();
00087                 // Canonicalize user names
00088                 foreach ( $users as $u ) {
00089                         $n = User::getCanonicalName( $u );
00090                         if ( $n === false || $n === '' ) {
00091                                 $vals = array( 'name' => $u, 'invalid' => '' );
00092                                 $fit = $result->addValue( array( 'query', $this->getModuleName() ),
00093                                                 null, $vals );
00094                                 if ( !$fit ) {
00095                                         $this->setContinueEnumParameter( 'users',
00096                                                         implode( '|', array_diff( $users, $done ) ) );
00097                                         $goodNames = array();
00098                                         break;
00099                                 }
00100                                 $done[] = $u;
00101                         } else {
00102                                 $goodNames[] = $n;
00103                         }
00104                 }
00105 
00106                 $result = $this->getResult();
00107 
00108                 if ( count( $goodNames ) ) {
00109                         $this->addTables( 'user' );
00110                         $this->addFields( User::selectFields() );
00111                         $this->addWhereFld( 'user_name', $goodNames );
00112 
00113                         $this->showHiddenUsersAddBlockInfo( isset( $this->prop['blockinfo'] ) );
00114 
00115                         $data = array();
00116                         $res = $this->select( __METHOD__ );
00117                         $this->resetQueryParams();
00118 
00119                         // get user groups if needed
00120                         if ( isset( $this->prop['groups'] ) || isset( $this->prop['rights'] ) ) {
00121                                 $userGroups = array();
00122 
00123                                 $this->addTables( 'user' );
00124                                 $this->addWhereFld( 'user_name', $goodNames );
00125                                 $this->addTables( 'user_groups' );
00126                                 $this->addJoinConds( array( 'user_groups' => array( 'INNER JOIN', 'ug_user=user_id' ) ) );
00127                                 $this->addFields( array( 'user_name', 'ug_group' ) );
00128                                 $userGroupsRes = $this->select( __METHOD__ );
00129 
00130                                 foreach( $userGroupsRes as $row ) {
00131                                         $userGroups[$row->user_name][] = $row->ug_group;
00132                                 }
00133                         }
00134 
00135                         foreach ( $res as $row ) {
00136                                 // create user object and pass along $userGroups if set
00137                                 // that reduces the number of database queries needed in User dramatically
00138                                 if ( !isset( $userGroups ) ) {
00139                                         $user = User::newFromRow( $row );
00140                                 } else {
00141                                         if ( !isset( $userGroups[$row->user_name] ) || !is_array( $userGroups[$row->user_name] ) ) {
00142                                                 $userGroups[$row->user_name] = array();
00143                                         }
00144                                         $user = User::newFromRow( $row, array( 'user_groups' => $userGroups[$row->user_name] ) );
00145                                 }
00146                                 $name = $user->getName();
00147 
00148                                 $data[$name]['userid'] = $user->getId();
00149                                 $data[$name]['name'] = $name;
00150 
00151                                 if ( isset( $this->prop['editcount'] ) ) {
00152                                         $data[$name]['editcount'] = intval( $user->getEditCount() );
00153                                 }
00154 
00155                                 if ( isset( $this->prop['registration'] ) ) {
00156                                         $data[$name]['registration'] = wfTimestampOrNull( TS_ISO_8601, $user->getRegistration() );
00157                                 }
00158 
00159                                 if ( isset( $this->prop['groups'] ) ) {
00160                                         $data[$name]['groups'] = $user->getEffectiveGroups();
00161                                 }
00162 
00163                                 if ( isset( $this->prop['implicitgroups'] ) ) {
00164                                         $data[$name]['implicitgroups'] = $user->getAutomaticGroups();
00165                                 }
00166 
00167                                 if ( isset( $this->prop['rights'] ) ) {
00168                                         $data[$name]['rights'] = $user->getRights();
00169                                 }
00170                                 if ( $row->ipb_deleted ) {
00171                                         $data[$name]['hidden'] = '';
00172                                 }
00173                                 if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->ipb_by_text ) ) {
00174                                         $data[$name]['blockid'] = $row->ipb_id;
00175                                         $data[$name]['blockedby'] = $row->ipb_by_text;
00176                                         $data[$name]['blockedbyid'] = $row->ipb_by;
00177                                         $data[$name]['blockreason'] = $row->ipb_reason;
00178                                         $data[$name]['blockexpiry'] = $row->ipb_expiry;
00179                                 }
00180 
00181                                 if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() ) {
00182                                         $data[$name]['emailable'] = '';
00183                                 }
00184 
00185                                 if ( isset( $this->prop['gender'] ) ) {
00186                                         $gender = $user->getOption( 'gender' );
00187                                         if ( strval( $gender ) === '' ) {
00188                                                 $gender = 'unknown';
00189                                         }
00190                                         $data[$name]['gender'] = $gender;
00191                                 }
00192 
00193                                 if ( !is_null( $params['token'] ) ) {
00194                                         $tokenFunctions = $this->getTokenFunctions();
00195                                         foreach ( $params['token'] as $t ) {
00196                                                 $val = call_user_func( $tokenFunctions[$t], $user );
00197                                                 if ( $val === false ) {
00198                                                         $this->setWarning( "Action '$t' is not allowed for the current user" );
00199                                                 } else {
00200                                                         $data[$name][$t . 'token'] = $val;
00201                                                 }
00202                                         }
00203                                 }
00204                         }
00205                 }
00206 
00207                 // Second pass: add result data to $retval
00208                 foreach ( $goodNames as $u ) {
00209                         if ( !isset( $data[$u] ) ) {
00210                                 $data[$u] = array( 'name' => $u );
00211                                 $urPage = new UserrightsPage;
00212                                 $iwUser = $urPage->fetchUser( $u );
00213 
00214                                 if ( $iwUser instanceof UserRightsProxy ) {
00215                                         $data[$u]['interwiki'] = '';
00216 
00217                                         if ( !is_null( $params['token'] ) ) {
00218                                                 $tokenFunctions = $this->getTokenFunctions();
00219 
00220                                                 foreach ( $params['token'] as $t ) {
00221                                                         $val = call_user_func( $tokenFunctions[$t], $iwUser );
00222                                                         if ( $val === false ) {
00223                                                                 $this->setWarning( "Action '$t' is not allowed for the current user" );
00224                                                         } else {
00225                                                                 $data[$u][$t . 'token'] = $val;
00226                                                         }
00227                                                 }
00228                                         }
00229                                 } else {
00230                                         $data[$u]['missing'] = '';
00231                                 }
00232                         } else {
00233                                 if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) {
00234                                         $result->setIndexedTagName( $data[$u]['groups'], 'g' );
00235                                 }
00236                                 if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) {
00237                                         $result->setIndexedTagName( $data[$u]['implicitgroups'], 'g' );
00238                                 }
00239                                 if ( isset( $this->prop['rights'] ) && isset( $data[$u]['rights'] ) ) {
00240                                         $result->setIndexedTagName( $data[$u]['rights'], 'r' );
00241                                 }
00242                         }
00243 
00244                         $fit = $result->addValue( array( 'query', $this->getModuleName() ),
00245                                         null, $data[$u] );
00246                         if ( !$fit ) {
00247                                 $this->setContinueEnumParameter( 'users',
00248                                                 implode( '|', array_diff( $users, $done ) ) );
00249                                 break;
00250                         }
00251                         $done[] = $u;
00252                 }
00253                 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' );
00254         }
00255 
00263         public static function getAutoGroups( $user ) {
00264                 wfDeprecated( __METHOD__, '1.20' );
00265 
00266                 return $user->getAutomaticGroups();
00267         }
00268 
00269         public function getCacheMode( $params ) {
00270                 if ( isset( $params['token'] ) ) {
00271                         return 'private';
00272                 } else {
00273                         return 'anon-public-user-private';
00274                 }
00275         }
00276 
00277         public function getAllowedParams() {
00278                 return array(
00279                         'prop' => array(
00280                                 ApiBase::PARAM_DFLT => null,
00281                                 ApiBase::PARAM_ISMULTI => true,
00282                                 ApiBase::PARAM_TYPE => array(
00283                                         'blockinfo',
00284                                         'groups',
00285                                         'implicitgroups',
00286                                         'rights',
00287                                         'editcount',
00288                                         'registration',
00289                                         'emailable',
00290                                         'gender',
00291                                 )
00292                         ),
00293                         'users' => array(
00294                                 ApiBase::PARAM_ISMULTI => true
00295                         ),
00296                         'token' => array(
00297                                 ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() ),
00298                                 ApiBase::PARAM_ISMULTI => true
00299                         ),
00300                 );
00301         }
00302 
00303         public function getParamDescription() {
00304                 return array(
00305                         'prop' => array(
00306                                 'What pieces of information to include',
00307                                 '  blockinfo      - Tags if the user is blocked, by whom, and for what reason',
00308                                 '  groups         - Lists all the groups the user(s) belongs to',
00309                                 '  implicitgroups - Lists all the groups a user is automatically a member of',
00310                                 '  rights         - Lists all the rights the user(s) has',
00311                                 '  editcount      - Adds the user\'s edit count',
00312                                 '  registration   - Adds the user\'s registration timestamp',
00313                                 '  emailable      - Tags if the user can and wants to receive email through [[Special:Emailuser]]',
00314                                 '  gender         - Tags the gender of the user. Returns "male", "female", or "unknown"',
00315                         ),
00316                         'users' => 'A list of users to obtain the same information for',
00317                         'token' => 'Which tokens to obtain for each user',
00318                 );
00319         }
00320 
00321         public function getResultProperties() {
00322                 $props = array(
00323                         '' => array(
00324                                 'userid' => array(
00325                                         ApiBase::PROP_TYPE => 'integer',
00326                                         ApiBase::PROP_NULLABLE => true
00327                                 ),
00328                                 'name' => 'string',
00329                                 'invalid' => 'boolean',
00330                                 'hidden' => 'boolean',
00331                                 'interwiki' => 'boolean',
00332                                 'missing' => 'boolean'
00333                         ),
00334                         'editcount' => array(
00335                                 'editcount' => array(
00336                                         ApiBase::PROP_TYPE => 'integer',
00337                                         ApiBase::PROP_NULLABLE => true
00338                                 )
00339                         ),
00340                         'registration' => array(
00341                                 'registration' => array(
00342                                         ApiBase::PROP_TYPE => 'timestamp',
00343                                         ApiBase::PROP_NULLABLE => true
00344                                 )
00345                         ),
00346                         'blockinfo' => array(
00347                                 'blockid' => array(
00348                                         ApiBase::PROP_TYPE => 'integer',
00349                                         ApiBase::PROP_NULLABLE => true
00350                                 ),
00351                                 'blockedby' => array(
00352                                         ApiBase::PROP_TYPE => 'string',
00353                                         ApiBase::PROP_NULLABLE => true
00354                                 ),
00355                                 'blockedbyid' => array(
00356                                         ApiBase::PROP_TYPE => 'integer',
00357                                         ApiBase::PROP_NULLABLE => true
00358                                 ),
00359                                 'blockedreason' => array(
00360                                         ApiBase::PROP_TYPE => 'string',
00361                                         ApiBase::PROP_NULLABLE => true
00362                                 ),
00363                                 'blockedexpiry' => array(
00364                                         ApiBase::PROP_TYPE => 'timestamp',
00365                                         ApiBase::PROP_NULLABLE => true
00366                                 )
00367                         ),
00368                         'emailable' => array(
00369                                 'emailable' => 'boolean'
00370                         ),
00371                         'gender' => array(
00372                                 'gender' => array(
00373                                         ApiBase::PROP_TYPE => array(
00374                                                 'male',
00375                                                 'female',
00376                                                 'unknown'
00377                                         ),
00378                                         ApiBase::PROP_NULLABLE => true
00379                                 )
00380                         )
00381                 );
00382 
00383                 self::addTokenProperties( $props, $this->getTokenFunctions() );
00384 
00385                 return $props;
00386         }
00387 
00388         public function getDescription() {
00389                 return 'Get information about a list of users';
00390         }
00391 
00392         public function getExamples() {
00393                 return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender';
00394         }
00395 
00396         public function getHelpUrls() {
00397                 return 'https://www.mediawiki.org/wiki/API:Users';
00398         }
00399 }