X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryAllUsers.php;h=0055ba42fcfaccf799fe1ea8fdd9d0d7d6c7ce0e;hb=d251f3ddd2001276564267a5d3a839c0334cf4b4;hp=837123c116c1321b8d729596daa9ccd4ea182929;hpb=ce91d949f78fe99126c161dd999e4ee398c1973c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryAllUsers.php b/includes/api/ApiQueryAllUsers.php index 837123c116..0055ba42fc 100644 --- a/includes/api/ApiQueryAllUsers.php +++ b/includes/api/ApiQueryAllUsers.php @@ -1,11 +1,10 @@ @gmail.com + * Created on July 7, 2007 + * + * Copyright © 2007 Yuri Astrakhan @gmail.com * * 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,24 +18,26 @@ * * 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 + * + * @file */ -if (!defined('MEDIAWIKI')) { +if ( !defined( 'MEDIAWIKI' ) ) { // Eclipse helper - will be ignored in production - require_once ('ApiQueryBase.php'); + require_once( 'ApiQueryBase.php' ); } /** * Query module to enumerate all registered users. - * - * @addtogroup API + * + * @ingroup API */ class ApiQueryAllUsers extends ApiQueryBase { - public function __construct($query, $moduleName) { - parent :: __construct($query, $moduleName, 'au'); + public function __construct( $query, $moduleName ) { + parent::__construct( $query, $moduleName, 'au' ); } public function execute() { @@ -44,156 +45,261 @@ class ApiQueryAllUsers extends ApiQueryBase { $params = $this->extractRequestParams(); $prop = $params['prop']; - if (!is_null($prop)) { - $prop = array_flip($prop); - $fld_editcount = isset($prop['editcount']); - $fld_groups = isset($prop['groups']); + if ( !is_null( $prop ) ) { + $prop = array_flip( $prop ); + $fld_blockinfo = isset( $prop['blockinfo'] ); + $fld_editcount = isset( $prop['editcount'] ); + $fld_groups = isset( $prop['groups'] ); + $fld_rights = isset( $prop['rights'] ); + $fld_registration = isset( $prop['registration'] ); } else { - $fld_editcount = $fld_groups = false; + $fld_blockinfo = $fld_editcount = $fld_groups = $fld_registration = false; } $limit = $params['limit']; - $tables = $db->tableName('user'); - - if (!is_null($params['from'])) - $this->addWhere('user_name>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from']))); + $this->addTables( 'user', 'u1' ); + $useIndex = true; + + if ( !is_null( $params['from'] ) ) { + $this->addWhere( 'u1.user_name >= ' . $db->addQuotes( $this->keyToTitle( $params['from'] ) ) ); + } + if ( !is_null( $params['to'] ) ) { + $this->addWhere( 'u1.user_name <= ' . $db->addQuotes( $this->keyToTitle( $params['to'] ) ) ); + } + + if ( !is_null( $params['prefix'] ) ) { + $this->addWhere( 'u1.user_name' . $db->buildLike( $this->keyToTitle( $params['prefix'] ), $db->anyString() ) ); + } + + if ( !is_null( $params['rights'] ) ) { + $groups = array(); + foreach( $params['rights'] as $r ) { + $groups = array_merge( $groups, User::getGroupsWithPermission( $r ) ); + } + + $groups = array_diff( array_unique( $groups ), User::getImplicitGroups() ); - if (isset($params['prefix'])) - $this->addWhere("user_name LIKE '" . $db->escapeLike(ApiQueryBase :: titleToKey($params['prefix'])) . "%'"); + if ( is_null( $params['group'] ) ) { + $params['group'] = $groups; + } else { + $params['group'] = array_unique( array_merge( $params['group'], $groups ) ); + } + } - if (!is_null($params['group'])) { + if ( !is_null( $params['group'] ) ) { + $useIndex = false; // Filter only users that belong to a given group - $tblName = $db->tableName('user_groups'); - $tables = "$tables INNER JOIN $tblName ug1 ON ug1.ug_user=user_id"; - $this->addWhereFld('ug1.ug_group', $params['group']); + $this->addTables( 'user_groups', 'ug1' ); + $ug1 = $this->getAliasedName( 'user_groups', 'ug1' ); + $this->addJoinConds( array( $ug1 => array( 'INNER JOIN', array( 'ug1.ug_user=u1.user_id', + 'ug1.ug_group' => $params['group'] ) ) ) ); } - if ($fld_groups) { + if ( $params['witheditsonly'] ) { + $this->addWhere( 'u1.user_editcount > 0' ); + } + + if ( $fld_groups || $fld_rights ) { // Show the groups the given users belong to // request more than needed to avoid not getting all rows that belong to one user - $groupCount = count(User::getAllGroups()); - $sqlLimit = $limit+$groupCount+1; + $groupCount = count( User::getAllGroups() ); + $sqlLimit = $limit + $groupCount + 1; - $tblName = $db->tableName('user_groups'); - $tables = "$tables LEFT JOIN $tblName ug2 ON ug2.ug_user=user_id"; - $this->addFields('ug2.ug_group ug_group2'); + $this->addTables( 'user_groups', 'ug2' ); + $tname = $this->getAliasedName( 'user_groups', 'ug2' ); + $this->addJoinConds( array( $tname => array( 'LEFT JOIN', 'ug2.ug_user=u1.user_id' ) ) ); + $this->addFields( 'ug2.ug_group ug_group2' ); } else { - $sqlLimit = $limit+1; + $sqlLimit = $limit + 1; } - $this->addOption('LIMIT', $sqlLimit); - $this->addTables($tables); + if ( $fld_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' ) ); + } - $this->addFields('user_name'); - $this->addFieldsIf('user_editcount', $fld_editcount); + $this->addOption( 'LIMIT', $sqlLimit ); - $this->addOption('ORDER BY', 'user_name'); + $this->addFields( array( + 'u1.user_name', + 'u1.user_id' + ) ); + $this->addFieldsIf( 'u1.user_editcount', $fld_editcount ); + $this->addFieldsIf( 'u1.user_registration', $fld_registration ); - $res = $this->select(__METHOD__); + $this->addOption( 'ORDER BY', 'u1.user_name' ); + if ( $useIndex ) { + $u1 = $this->getAliasedName( 'user', 'u1' ); + $this->addOption( 'USE INDEX', array( $u1 => 'user_name' ) ); + } + + $res = $this->select( __METHOD__ ); - $data = array (); $count = 0; $lastUserData = false; $lastUser = false; $result = $this->getResult(); - + // // This loop keeps track of the last entry. // For each new row, if the new row is for different user then the last, the last entry is added to results. // Otherwise, the group of the new row is appended to the last entry. // The setContinue... is more complex because of this, and takes into account the higher sql limit // to make sure all rows that belong to the same user are received. - // - while (true) { - - $row = $db->fetchObject($res); + + foreach ( $res as $row ) { $count++; - - if (!$row || $lastUser != $row->user_name) { + + if ( $lastUser !== $row->user_name ) { // Save the last pass's user data - if (is_array($lastUserData)) - $data[] = $lastUserData; - - // No more rows left - if (!$row) - break; + if ( is_array( $lastUserData ) ) { + $fit = $result->addValue( array( 'query', $this->getModuleName() ), + null, $lastUserData ); + + $lastUserData = null; + + if ( !$fit ) { + $this->setContinueEnumParameter( 'from', + $this->keyToTitle( $lastUserData['name'] ) ); + break; + } + } - if ($count > $limit) { + if ( $count > $limit ) { // We've reached the one extra which shows that there are additional pages to be had. Stop here... - $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->user_name)); + $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->user_name ) ); break; } // Record new user's data $lastUser = $row->user_name; - $lastUserData = array( 'name' => $lastUser ); - if ($fld_editcount) - $lastUserData['editcount'] = intval($row->user_editcount); - + $lastUserData = array( + 'name' => $lastUser, + 'userid' => $row->user_id, + ); + if ( $fld_blockinfo && !is_null( $row->blocker_name ) ) { + $lastUserData['blockedby'] = $row->blocker_name; + $lastUserData['blockreason'] = $row->ipb_reason; + } + if ( $fld_editcount ) { + $lastUserData['editcount'] = intval( $row->user_editcount ); + } + if ( $fld_registration ) { + $lastUserData['registration'] = $row->user_registration ? + wfTimestamp( TS_ISO_8601, $row->user_registration ) : ''; + } + } - - if ($sqlLimit == $count) { + + if ( $sqlLimit == $count ) { // BUG! database contains group name that User::getAllGroups() does not return // TODO: should handle this more gracefully - ApiBase :: dieDebug(__METHOD__, - 'MediaWiki configuration error: the database contains more user groups than known to User::getAllGroups() function'); + ApiBase::dieDebug( __METHOD__, + 'MediaWiki configuration error: the database contains more user groups than known to User::getAllGroups() function' ); } - + // Add user's group info - if ($fld_groups && !is_null($row->ug_group2)) { + if ( $fld_groups && !is_null( $row->ug_group2 ) ) { + if ( !isset( $lastUserData['groups'] ) ) { + $lastUserData['groups'] = ApiQueryUsers::getAutoGroups( User::newFromName( $lastUser ) ); + } + $lastUserData['groups'][] = $row->ug_group2; - $result->setIndexedTagName($lastUserData['groups'], 'g'); + $result->setIndexedTagName( $lastUserData['groups'], 'g' ); + } + + if ( $fld_rights && !is_null( $row->ug_group2 ) ) { + if ( !isset( $lastUserData['rights'] ) ) { + $lastUserData['rights'] = User::getGroupPermissions( User::getImplicitGroups() ); + } + + $lastUserData['rights'] = array_unique( array_merge( $lastUserData['rights'], + User::getGroupPermissions( array( $row->ug_group2 ) ) ) ); + $result->setIndexedTagName( $lastUserData['rights'], 'r' ); } } - - $db->freeResult($res); - $result->setIndexedTagName($data, 'u'); - $result->addValue('query', $this->getModuleName(), $data); + if ( is_array( $lastUserData ) ) { + $fit = $result->addValue( array( 'query', $this->getModuleName() ), + null, $lastUserData ); + if ( !$fit ) { + $this->setContinueEnumParameter( 'from', + $this->keyToTitle( $lastUserData['name'] ) ); + } + } + + $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'u' ); } - protected function getAllowedParams() { - return array ( + public function getCacheMode( $params ) { + return 'public'; + } + + public function getAllowedParams() { + return array( 'from' => null, + 'to' => null, 'prefix' => null, 'group' => array( - ApiBase :: PARAM_TYPE => User::getAllGroups() + ApiBase::PARAM_TYPE => User::getAllGroups(), + ApiBase::PARAM_ISMULTI => true, ), - 'prop' => array ( - ApiBase :: PARAM_ISMULTI => true, - ApiBase :: PARAM_TYPE => array ( - 'editcount', + 'rights' => array( + ApiBase::PARAM_TYPE => User::getAllRights(), + ApiBase::PARAM_ISMULTI => true, + ), + 'prop' => array( + ApiBase::PARAM_ISMULTI => true, + ApiBase::PARAM_TYPE => array( + 'blockinfo', 'groups', + 'rights', + 'editcount', + 'registration' ) ), - 'limit' => array ( - ApiBase :: PARAM_DFLT => 10, - ApiBase :: PARAM_TYPE => 'limit', - ApiBase :: PARAM_MIN => 1, - ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1, - ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 - ) + 'limit' => array( + ApiBase::PARAM_DFLT => 10, + ApiBase::PARAM_TYPE => 'limit', + ApiBase::PARAM_MIN => 1, + ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, + ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2 + ), + 'witheditsonly' => false, ); } - protected function getParamDescription() { - return array ( - 'from' => 'The user name to start enumerating from.', - 'prefix' => 'Search for all page titles that begin with this value.', - 'group' => 'Limit users to a given group name', + public function getParamDescription() { + return array( + 'from' => 'The user name to start enumerating from', + 'to' => 'The user name to stop enumerating at', + 'prefix' => 'Search for all users that begin with this value', + 'group' => 'Limit users to given group name(s)', + 'rights' => 'Limit users to given right(s)', 'prop' => array( 'What pieces of information to include.', - '`groups` property uses more server resources and may return fewer results than the limit.'), - 'limit' => 'How many total user names to return.', + ' blockinfo - Adds the information about a current block on the user', + ' groups - Lists groups that the user is in. This uses more server resources and may return fewer results than the limit', + ' rights - Lists rights that the user has', + ' editcount - Adds the edit count of the user', + ' registration - Adds the timestamp of when the user registered', + ), + 'limit' => 'How many total user names to return', + 'witheditsonly' => 'Only list users who have made edits', ); } - protected function getDescription() { + public function getDescription() { return 'Enumerate all registered users'; } protected function getExamples() { - return array ( + return array( 'api.php?action=query&list=allusers&aufrom=Y', ); }