X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryUsers.php;h=4fd256fe305655238e112dd5aa8af4c5344db2d9;hb=685ef510eeead335039dceff2e65ab666744240d;hp=7f4c60cfb05e3ebfd7a8a1fd3fe022feba772975;hpb=1040ce28e4ea559758f4ba4237420fbc4bb195fd;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryUsers.php b/includes/api/ApiQueryUsers.php index 7f4c60cfb0..4fd256fe30 100644 --- a/includes/api/ApiQueryUsers.php +++ b/includes/api/ApiQueryUsers.php @@ -1,11 +1,11 @@ .@home.nl + * Copyright © 2007 Roan Kattouw .@home.nl * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,13 +19,13 @@ * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html */ -if (!defined('MEDIAWIKI')) { +if ( !defined( 'MEDIAWIKI' ) ) { // Eclipse helper - will be ignored in production - require_once ('ApiQueryBase.php'); + require_once( 'ApiQueryBase.php' ); } /** @@ -33,132 +33,250 @@ if (!defined('MEDIAWIKI')) { * * @ingroup API */ - class ApiQueryUsers extends ApiQueryBase { - public function __construct($query, $moduleName) { - parent :: __construct($query, $moduleName, 'us'); + public function __construct( $query, $moduleName ) { + parent::__construct( $query, $moduleName, 'us' ); + } + + /** + * Get an array mapping token names to their handler functions. + * The prototype for a token function is func($user) + * it should return a token or false (permission denied) + * @return array(tokenname => function) + */ + protected function getTokenFunctions() { + // Don't call the hooks twice + if ( isset( $this->tokenFunctions ) ) { + return $this->tokenFunctions; + } + + // If we're in JSON callback mode, no tokens can be obtained + if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) { + return array(); + } + + $this->tokenFunctions = array( + 'userrights' => array( 'ApiQueryUsers', 'getUserrightsToken' ), + ); + wfRunHooks( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) ); + return $this->tokenFunctions; + } + + public static function getUserrightsToken( $user ) { + global $wgUser; + // Since the permissions check for userrights is non-trivial, + // don't bother with it here + return $wgUser->editToken( $user->getName() ); } public function execute() { $params = $this->extractRequestParams(); $result = $this->getResult(); - $r = array(); - if (!is_null($params['prop'])) { - $this->prop = array_flip($params['prop']); + if ( !is_null( $params['prop'] ) ) { + $this->prop = array_flip( $params['prop'] ); } else { $this->prop = array(); } - if(is_array($params['users'])) { - $r = $this->getOtherUsersInfo($params['users']); - $result->setIndexedTagName($r, 'user'); - } - $result->addValue("query", $this->getModuleName(), $r); - } - - protected function getOtherUsersInfo($users) { - $goodNames = $retval = array(); + $users = (array)$params['users']; + $goodNames = $done = array(); + $result = $this->getResult(); // Canonicalize user names - foreach($users as $u) { - $n = User::getCanonicalName($u); - if($n === false || $n === '') - $retval[] = array('name' => $u, 'invalid' => ''); - else + foreach ( $users as $u ) { + $n = User::getCanonicalName( $u ); + if ( $n === false || $n === '' ) { + $vals = array( 'name' => $u, 'invalid' => '' ); + $fit = $result->addValue( array( 'query', $this->getModuleName() ), + null, $vals ); + if ( !$fit ) { + $this->setContinueEnumParameter( 'users', + implode( '|', array_diff( $users, $done ) ) ); + $goodNames = array(); + break; + } + $done[] = $u; + } else { $goodNames[] = $n; + } } - if(!count($goodNames)) - return $retval; - - $db = $this->getDB(); - $this->addTables('user', 'u1'); - $this->addFields('u1.*'); - $this->addWhereFld('u1.user_name', $goodNames); - - if(isset($this->prop['groups'])) { - $this->addTables('user_groups'); - $this->addJoinConds(array('user_groups' => array('LEFT JOIN', 'ug_user=u1.user_id'))); - $this->addFields('ug_group'); - } - if(isset($this->prop['blockinfo'])) { - $this->addTables('ipblocks'); - $this->addTables('user', 'u2'); - $u2 = $this->getAliasedName('user', 'u2'); - $this->addJoinConds(array( - 'ipblocks' => array('LEFT JOIN', 'ipb_user=u1.user_id'), - $u2 => array('LEFT JOIN', 'ipb_by=u2.user_id'))); - $this->addFields(array('ipb_reason', 'u2.user_name blocker_name')); - } - $data = array(); - $res = $this->select(__METHOD__); - while(($r = $db->fetchObject($res))) { - $user = User::newFromRow($r); - $name = $user->getName(); - $data[$name]['name'] = $name; - if(isset($this->prop['editcount'])) - // No proper member function in User class for this - $data[$name]['editcount'] = $r->user_editcount; - if(isset($this->prop['registration'])) - // Nor for this one - $data[$name]['registration'] = wfTimestampOrNull(TS_ISO_8601, $r->user_registration); - if(isset($this->prop['groups'])) - // This row contains only one group, others will be added from other rows - if(!is_null($r->ug_group)) - $data[$name]['groups'][] = $r->ug_group; - if(isset($this->prop['blockinfo'])) - if(!is_null($r->blocker_name)) { - $data[$name]['blockedby'] = $r->blocker_name; - $data[$name]['blockreason'] = $r->ipb_reason; + if ( count( $goodNames ) ) { + $this->addTables( 'user', 'u1' ); + $this->addFields( 'u1.*' ); + $this->addWhereFld( 'u1.user_name', $goodNames ); + + if ( isset( $this->prop['groups'] ) ) { + $this->addTables( 'user_groups' ); + $this->addJoinConds( array( 'user_groups' => array( 'LEFT JOIN', 'ug_user=u1.user_id' ) ) ); + $this->addFields( 'ug_group' ); + } + if ( isset( $this->prop['blockinfo'] ) ) { + $this->addTables( 'ipblocks' ); + $this->addTables( 'user', 'u2' ); + $u2 = $this->getAliasedName( 'user', 'u2' ); + $this->addJoinConds( array( + 'ipblocks' => array( 'LEFT JOIN', 'ipb_user=u1.user_id' ), + $u2 => array( 'LEFT JOIN', 'ipb_by=u2.user_id' ) ) ); + $this->addFields( array( 'ipb_reason', 'u2.user_name AS blocker_name' ) ); + } + + $data = array(); + $res = $this->select( __METHOD__ ); + foreach ( $res as $row ) { + $user = User::newFromRow( $row ); + $name = $user->getName(); + $data[$name]['name'] = $name; + + if ( isset( $this->prop['editcount'] ) ) { + $data[$name]['editcount'] = intval( $user->getEditCount() ); + } + + if ( isset( $this->prop['registration'] ) ) { + $data[$name]['registration'] = wfTimestampOrNull( TS_ISO_8601, $user->getRegistration() ); + } + + if ( isset( $this->prop['groups'] ) && !is_null( $row->ug_group ) ) { + // This row contains only one group, others will be added from other rows + $data[$name]['groups'][] = $row->ug_group; } - if(isset($this->prop['canemail']) && $user->canReceiveEmail()) - $data[$name]['canemail'] = ''; - } + if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->blocker_name ) ) { + $data[$name]['blockedby'] = $row->blocker_name; + $data[$name]['blockreason'] = $row->ipb_reason; + } + + if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() ) { + $data[$name]['emailable'] = ''; + } + + if ( isset( $this->prop['gender'] ) ) { + $gender = $user->getOption( 'gender' ); + if ( strval( $gender ) === '' ) { + $gender = 'unknown'; + } + $data[$name]['gender'] = $gender; + } + + if ( !is_null( $params['token'] ) ) { + $tokenFunctions = $this->getTokenFunctions(); + foreach ( $params['token'] as $t ) { + $val = call_user_func( $tokenFunctions[$t], $user ); + if ( $val === false ) { + $this->setWarning( "Action '$t' is not allowed for the current user" ); + } else { + $data[$name][$t . 'token'] = $val; + } + } + } + } + } // Second pass: add result data to $retval - foreach($goodNames as $u) { - if(!isset($data[$u])) - $retval[] = array('name' => $u, 'missing' => ''); - else { - if(isset($this->prop['groups']) && isset($data[$u]['groups'])) - $this->getResult()->setIndexedTagName($data[$u]['groups'], 'g'); - $retval[] = $data[$u]; + foreach ( $goodNames as $u ) { + if ( !isset( $data[$u] ) ) { + $data[$u] = array( 'name' => $u ); + $urPage = new UserrightsPage; + $iwUser = $urPage->fetchUser( $u ); + + if ( $iwUser instanceof UserRightsProxy ) { + $data[$u]['interwiki'] = ''; + + if ( !is_null( $params['token'] ) ) { + $tokenFunctions = $this->getTokenFunctions(); + + foreach ( $params['token'] as $t ) { + $val = call_user_func( $tokenFunctions[$t], $iwUser ); + if ( $val === false ) { + $this->setWarning( "Action '$t' is not allowed for the current user" ); + } else { + $data[$u][$t . 'token'] = $val; + } + } + } + } else { + $data[$u]['missing'] = ''; + } + } else { + if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) { + $autolist = ApiQueryUsers::getAutoGroups( User::newFromName( $u ) ); + + $data[$u]['groups'] = array_merge( $autolist, $data[$u]['groups'] ); + + $this->getResult()->setIndexedTagName( $data[$u]['groups'], 'g' ); + } + } + $fit = $result->addValue( array( 'query', $this->getModuleName() ), + null, $data[$u] ); + if ( !$fit ) { + $this->setContinueEnumParameter( 'users', + implode( '|', array_diff( $users, $done ) ) ); + break; } + $done[] = $u; + } + return $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' ); + } + + /** + * Gets all the groups that a user is automatically a member of + * @return array + */ + public static function getAutoGroups( $user ) { + $groups = array( '*' ); + + if ( !$user->isAnon() ) { + $groups[] = 'user'; + } + + return array_merge( $groups, Autopromote::getAutopromoteGroups( $user ) ); + } + + public function getCacheMode( $params ) { + if ( isset( $params['token'] ) ) { + return 'private'; + } else { + return 'public'; } - return $retval; } public function getAllowedParams() { - return array ( - 'prop' => array ( - ApiBase :: PARAM_DFLT => NULL, - ApiBase :: PARAM_ISMULTI => true, - ApiBase :: PARAM_TYPE => array ( + return array( + 'prop' => array( + ApiBase::PARAM_DFLT => null, + ApiBase::PARAM_ISMULTI => true, + ApiBase::PARAM_TYPE => array( 'blockinfo', 'groups', 'editcount', 'registration', - 'canemail', + 'emailable', + 'gender', ) ), 'users' => array( - ApiBase :: PARAM_ISMULTI => true - ) + ApiBase::PARAM_ISMULTI => true + ), + 'token' => array( + ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() ), + ApiBase::PARAM_ISMULTI => true + ), ); } public function getParamDescription() { - return array ( + return array( 'prop' => array( 'What pieces of information to include', ' blockinfo - tags if the user is blocked, by whom, and for what reason', ' groups - lists all the groups the user belongs to', ' editcount - adds the user\'s edit count', ' registration - adds the user\'s registration timestamp', - ' canemail - tags if the user can and wants to receive e-mail through [[Special:Emailuser]]', + ' emailable - tags if the user can and wants to receive e-mail through [[Special:Emailuser]]', + ' gender - tags the gender of the user. Returns "male", "female", or "unknown"', ), - 'users' => 'A list of users to obtain the same information for' + 'users' => 'A list of users to obtain the same information for', + 'token' => 'Which tokens to obtain for each user', ); } @@ -167,7 +285,7 @@ if (!defined('MEDIAWIKI')) { } protected function getExamples() { - return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount'; + return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender'; } public function getVersion() {