MediaWiki
REL1_22
|
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'] = $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 $context = $this->getContext(); 00208 // Second pass: add result data to $retval 00209 foreach ( $goodNames as $u ) { 00210 if ( !isset( $data[$u] ) ) { 00211 $data[$u] = array( 'name' => $u ); 00212 $urPage = new UserrightsPage; 00213 $urPage->setContext( $context ); 00214 $iwUser = $urPage->fetchUser( $u ); 00215 00216 if ( $iwUser instanceof UserRightsProxy ) { 00217 $data[$u]['interwiki'] = ''; 00218 00219 if ( !is_null( $params['token'] ) ) { 00220 $tokenFunctions = $this->getTokenFunctions(); 00221 00222 foreach ( $params['token'] as $t ) { 00223 $val = call_user_func( $tokenFunctions[$t], $iwUser ); 00224 if ( $val === false ) { 00225 $this->setWarning( "Action '$t' is not allowed for the current user" ); 00226 } else { 00227 $data[$u][$t . 'token'] = $val; 00228 } 00229 } 00230 } 00231 } else { 00232 $data[$u]['missing'] = ''; 00233 } 00234 } else { 00235 if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) { 00236 $result->setIndexedTagName( $data[$u]['groups'], 'g' ); 00237 } 00238 if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) { 00239 $result->setIndexedTagName( $data[$u]['implicitgroups'], 'g' ); 00240 } 00241 if ( isset( $this->prop['rights'] ) && isset( $data[$u]['rights'] ) ) { 00242 $result->setIndexedTagName( $data[$u]['rights'], 'r' ); 00243 } 00244 } 00245 00246 $fit = $result->addValue( array( 'query', $this->getModuleName() ), 00247 null, $data[$u] ); 00248 if ( !$fit ) { 00249 $this->setContinueEnumParameter( 'users', 00250 implode( '|', array_diff( $users, $done ) ) ); 00251 break; 00252 } 00253 $done[] = $u; 00254 } 00255 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' ); 00256 } 00257 00265 public static function getAutoGroups( $user ) { 00266 wfDeprecated( __METHOD__, '1.20' ); 00267 00268 return $user->getAutomaticGroups(); 00269 } 00270 00271 public function getCacheMode( $params ) { 00272 if ( isset( $params['token'] ) ) { 00273 return 'private'; 00274 } else { 00275 return 'anon-public-user-private'; 00276 } 00277 } 00278 00279 public function getAllowedParams() { 00280 return array( 00281 'prop' => array( 00282 ApiBase::PARAM_DFLT => null, 00283 ApiBase::PARAM_ISMULTI => true, 00284 ApiBase::PARAM_TYPE => array( 00285 'blockinfo', 00286 'groups', 00287 'implicitgroups', 00288 'rights', 00289 'editcount', 00290 'registration', 00291 'emailable', 00292 'gender', 00293 ) 00294 ), 00295 'users' => array( 00296 ApiBase::PARAM_ISMULTI => true 00297 ), 00298 'token' => array( 00299 ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() ), 00300 ApiBase::PARAM_ISMULTI => true 00301 ), 00302 ); 00303 } 00304 00305 public function getParamDescription() { 00306 return array( 00307 'prop' => array( 00308 'What pieces of information to include', 00309 ' blockinfo - Tags if the user is blocked, by whom, and for what reason', 00310 ' groups - Lists all the groups the user(s) belongs to', 00311 ' implicitgroups - Lists all the groups a user is automatically a member of', 00312 ' rights - Lists all the rights the user(s) has', 00313 ' editcount - Adds the user\'s edit count', 00314 ' registration - Adds the user\'s registration timestamp', 00315 ' emailable - Tags if the user can and wants to receive email through [[Special:Emailuser]]', 00316 ' gender - Tags the gender of the user. Returns "male", "female", or "unknown"', 00317 ), 00318 'users' => 'A list of users to obtain the same information for', 00319 'token' => 'Which tokens to obtain for each user', 00320 ); 00321 } 00322 00323 public function getResultProperties() { 00324 $props = array( 00325 '' => array( 00326 'userid' => array( 00327 ApiBase::PROP_TYPE => 'integer', 00328 ApiBase::PROP_NULLABLE => true 00329 ), 00330 'name' => 'string', 00331 'invalid' => 'boolean', 00332 'hidden' => 'boolean', 00333 'interwiki' => 'boolean', 00334 'missing' => 'boolean' 00335 ), 00336 'editcount' => array( 00337 'editcount' => array( 00338 ApiBase::PROP_TYPE => 'integer', 00339 ApiBase::PROP_NULLABLE => true 00340 ) 00341 ), 00342 'registration' => array( 00343 'registration' => array( 00344 ApiBase::PROP_TYPE => 'timestamp', 00345 ApiBase::PROP_NULLABLE => true 00346 ) 00347 ), 00348 'blockinfo' => array( 00349 'blockid' => array( 00350 ApiBase::PROP_TYPE => 'integer', 00351 ApiBase::PROP_NULLABLE => true 00352 ), 00353 'blockedby' => array( 00354 ApiBase::PROP_TYPE => 'string', 00355 ApiBase::PROP_NULLABLE => true 00356 ), 00357 'blockedbyid' => array( 00358 ApiBase::PROP_TYPE => 'integer', 00359 ApiBase::PROP_NULLABLE => true 00360 ), 00361 'blockedreason' => array( 00362 ApiBase::PROP_TYPE => 'string', 00363 ApiBase::PROP_NULLABLE => true 00364 ), 00365 'blockedexpiry' => array( 00366 ApiBase::PROP_TYPE => 'timestamp', 00367 ApiBase::PROP_NULLABLE => true 00368 ) 00369 ), 00370 'emailable' => array( 00371 'emailable' => 'boolean' 00372 ), 00373 'gender' => array( 00374 'gender' => array( 00375 ApiBase::PROP_TYPE => array( 00376 'male', 00377 'female', 00378 'unknown' 00379 ), 00380 ApiBase::PROP_NULLABLE => true 00381 ) 00382 ) 00383 ); 00384 00385 self::addTokenProperties( $props, $this->getTokenFunctions() ); 00386 00387 return $props; 00388 } 00389 00390 public function getDescription() { 00391 return 'Get information about a list of users'; 00392 } 00393 00394 public function getExamples() { 00395 return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender'; 00396 } 00397 00398 public function getHelpUrls() { 00399 return 'https://www.mediawiki.org/wiki/API:Users'; 00400 } 00401 }