MediaWiki
REL1_23
|
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 00062 return $this->tokenFunctions; 00063 } 00064 00069 public static function getUserrightsToken( $user ) { 00070 global $wgUser; 00071 00072 // Since the permissions check for userrights is non-trivial, 00073 // don't bother with it here 00074 return $wgUser->getEditToken( $user->getName() ); 00075 } 00076 00077 public function execute() { 00078 $params = $this->extractRequestParams(); 00079 00080 if ( !is_null( $params['prop'] ) ) { 00081 $this->prop = array_flip( $params['prop'] ); 00082 } else { 00083 $this->prop = array(); 00084 } 00085 00086 $users = (array)$params['users']; 00087 $goodNames = $done = array(); 00088 $result = $this->getResult(); 00089 // Canonicalize user names 00090 foreach ( $users as $u ) { 00091 $n = User::getCanonicalName( $u ); 00092 if ( $n === false || $n === '' ) { 00093 $vals = array( 'name' => $u, 'invalid' => '' ); 00094 $fit = $result->addValue( array( 'query', $this->getModuleName() ), 00095 null, $vals ); 00096 if ( !$fit ) { 00097 $this->setContinueEnumParameter( 'users', 00098 implode( '|', array_diff( $users, $done ) ) ); 00099 $goodNames = array(); 00100 break; 00101 } 00102 $done[] = $u; 00103 } else { 00104 $goodNames[] = $n; 00105 } 00106 } 00107 00108 $result = $this->getResult(); 00109 00110 if ( count( $goodNames ) ) { 00111 $this->addTables( 'user' ); 00112 $this->addFields( User::selectFields() ); 00113 $this->addWhereFld( 'user_name', $goodNames ); 00114 00115 $this->showHiddenUsersAddBlockInfo( isset( $this->prop['blockinfo'] ) ); 00116 00117 $data = array(); 00118 $res = $this->select( __METHOD__ ); 00119 $this->resetQueryParams(); 00120 00121 // get user groups if needed 00122 if ( isset( $this->prop['groups'] ) || isset( $this->prop['rights'] ) ) { 00123 $userGroups = array(); 00124 00125 $this->addTables( 'user' ); 00126 $this->addWhereFld( 'user_name', $goodNames ); 00127 $this->addTables( 'user_groups' ); 00128 $this->addJoinConds( array( 'user_groups' => array( 'INNER JOIN', 'ug_user=user_id' ) ) ); 00129 $this->addFields( array( 'user_name', 'ug_group' ) ); 00130 $userGroupsRes = $this->select( __METHOD__ ); 00131 00132 foreach ( $userGroupsRes as $row ) { 00133 $userGroups[$row->user_name][] = $row->ug_group; 00134 } 00135 } 00136 00137 foreach ( $res as $row ) { 00138 // create user object and pass along $userGroups if set 00139 // that reduces the number of database queries needed in User dramatically 00140 if ( !isset( $userGroups ) ) { 00141 $user = User::newFromRow( $row ); 00142 } else { 00143 if ( !isset( $userGroups[$row->user_name] ) || !is_array( $userGroups[$row->user_name] ) ) { 00144 $userGroups[$row->user_name] = array(); 00145 } 00146 $user = User::newFromRow( $row, array( 'user_groups' => $userGroups[$row->user_name] ) ); 00147 } 00148 $name = $user->getName(); 00149 00150 $data[$name]['userid'] = $user->getId(); 00151 $data[$name]['name'] = $name; 00152 00153 if ( isset( $this->prop['editcount'] ) ) { 00154 $data[$name]['editcount'] = $user->getEditCount(); 00155 } 00156 00157 if ( isset( $this->prop['registration'] ) ) { 00158 $data[$name]['registration'] = wfTimestampOrNull( TS_ISO_8601, $user->getRegistration() ); 00159 } 00160 00161 if ( isset( $this->prop['groups'] ) ) { 00162 $data[$name]['groups'] = $user->getEffectiveGroups(); 00163 } 00164 00165 if ( isset( $this->prop['implicitgroups'] ) ) { 00166 $data[$name]['implicitgroups'] = $user->getAutomaticGroups(); 00167 } 00168 00169 if ( isset( $this->prop['rights'] ) ) { 00170 $data[$name]['rights'] = $user->getRights(); 00171 } 00172 if ( $row->ipb_deleted ) { 00173 $data[$name]['hidden'] = ''; 00174 } 00175 if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->ipb_by_text ) ) { 00176 $data[$name]['blockid'] = $row->ipb_id; 00177 $data[$name]['blockedby'] = $row->ipb_by_text; 00178 $data[$name]['blockedbyid'] = $row->ipb_by; 00179 $data[$name]['blockreason'] = $row->ipb_reason; 00180 $data[$name]['blockexpiry'] = $row->ipb_expiry; 00181 } 00182 00183 if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() ) { 00184 $data[$name]['emailable'] = ''; 00185 } 00186 00187 if ( isset( $this->prop['gender'] ) ) { 00188 $gender = $user->getOption( 'gender' ); 00189 if ( strval( $gender ) === '' ) { 00190 $gender = 'unknown'; 00191 } 00192 $data[$name]['gender'] = $gender; 00193 } 00194 00195 if ( !is_null( $params['token'] ) ) { 00196 $tokenFunctions = $this->getTokenFunctions(); 00197 foreach ( $params['token'] as $t ) { 00198 $val = call_user_func( $tokenFunctions[$t], $user ); 00199 if ( $val === false ) { 00200 $this->setWarning( "Action '$t' is not allowed for the current user" ); 00201 } else { 00202 $data[$name][$t . 'token'] = $val; 00203 } 00204 } 00205 } 00206 } 00207 } 00208 00209 $context = $this->getContext(); 00210 // Second pass: add result data to $retval 00211 foreach ( $goodNames as $u ) { 00212 if ( !isset( $data[$u] ) ) { 00213 $data[$u] = array( 'name' => $u ); 00214 $urPage = new UserrightsPage; 00215 $urPage->setContext( $context ); 00216 $iwUser = $urPage->fetchUser( $u ); 00217 00218 if ( $iwUser instanceof UserRightsProxy ) { 00219 $data[$u]['interwiki'] = ''; 00220 00221 if ( !is_null( $params['token'] ) ) { 00222 $tokenFunctions = $this->getTokenFunctions(); 00223 00224 foreach ( $params['token'] as $t ) { 00225 $val = call_user_func( $tokenFunctions[$t], $iwUser ); 00226 if ( $val === false ) { 00227 $this->setWarning( "Action '$t' is not allowed for the current user" ); 00228 } else { 00229 $data[$u][$t . 'token'] = $val; 00230 } 00231 } 00232 } 00233 } else { 00234 $data[$u]['missing'] = ''; 00235 } 00236 } else { 00237 if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) { 00238 $result->setIndexedTagName( $data[$u]['groups'], 'g' ); 00239 } 00240 if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) { 00241 $result->setIndexedTagName( $data[$u]['implicitgroups'], 'g' ); 00242 } 00243 if ( isset( $this->prop['rights'] ) && isset( $data[$u]['rights'] ) ) { 00244 $result->setIndexedTagName( $data[$u]['rights'], 'r' ); 00245 } 00246 } 00247 00248 $fit = $result->addValue( array( 'query', $this->getModuleName() ), 00249 null, $data[$u] ); 00250 if ( !$fit ) { 00251 $this->setContinueEnumParameter( 'users', 00252 implode( '|', array_diff( $users, $done ) ) ); 00253 break; 00254 } 00255 $done[] = $u; 00256 } 00257 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' ); 00258 } 00259 00267 public static function getAutoGroups( $user ) { 00268 wfDeprecated( __METHOD__, '1.20' ); 00269 00270 return $user->getAutomaticGroups(); 00271 } 00272 00273 public function getCacheMode( $params ) { 00274 return isset( $params['token'] ) ? 'private' : 'anon-public-user-private'; 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 ' . 00314 'email through [[Special:Emailuser]]', 00315 ' gender - Tags the gender of the user. Returns "male", "female", or "unknown"', 00316 ), 00317 'users' => 'A list of users to obtain the same information for', 00318 'token' => 'Which tokens to obtain for each user', 00319 ); 00320 } 00321 00322 public function getResultProperties() { 00323 $props = array( 00324 '' => array( 00325 'userid' => array( 00326 ApiBase::PROP_TYPE => 'integer', 00327 ApiBase::PROP_NULLABLE => true 00328 ), 00329 'name' => 'string', 00330 'invalid' => 'boolean', 00331 'hidden' => 'boolean', 00332 'interwiki' => 'boolean', 00333 'missing' => 'boolean' 00334 ), 00335 'editcount' => array( 00336 'editcount' => array( 00337 ApiBase::PROP_TYPE => 'integer', 00338 ApiBase::PROP_NULLABLE => true 00339 ) 00340 ), 00341 'registration' => array( 00342 'registration' => array( 00343 ApiBase::PROP_TYPE => 'timestamp', 00344 ApiBase::PROP_NULLABLE => true 00345 ) 00346 ), 00347 'blockinfo' => array( 00348 'blockid' => array( 00349 ApiBase::PROP_TYPE => 'integer', 00350 ApiBase::PROP_NULLABLE => true 00351 ), 00352 'blockedby' => array( 00353 ApiBase::PROP_TYPE => 'string', 00354 ApiBase::PROP_NULLABLE => true 00355 ), 00356 'blockedbyid' => array( 00357 ApiBase::PROP_TYPE => 'integer', 00358 ApiBase::PROP_NULLABLE => true 00359 ), 00360 'blockedreason' => array( 00361 ApiBase::PROP_TYPE => 'string', 00362 ApiBase::PROP_NULLABLE => true 00363 ), 00364 'blockedexpiry' => array( 00365 ApiBase::PROP_TYPE => 'timestamp', 00366 ApiBase::PROP_NULLABLE => true 00367 ) 00368 ), 00369 'emailable' => array( 00370 'emailable' => 'boolean' 00371 ), 00372 'gender' => array( 00373 'gender' => array( 00374 ApiBase::PROP_TYPE => array( 00375 'male', 00376 'female', 00377 'unknown' 00378 ), 00379 ApiBase::PROP_NULLABLE => true 00380 ) 00381 ) 00382 ); 00383 00384 self::addTokenProperties( $props, $this->getTokenFunctions() ); 00385 00386 return $props; 00387 } 00388 00389 public function getDescription() { 00390 return 'Get information about a list of users.'; 00391 } 00392 00393 public function getExamples() { 00394 return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender'; 00395 } 00396 00397 public function getHelpUrls() { 00398 return 'https://www.mediawiki.org/wiki/API:Users'; 00399 } 00400 }