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