65 parent::__construct( $query, $moduleName,
'au' );
79 $name = $this->contentLanguage->ucfirst( $name );
80 return strtr( $name,
'_',
' ' );
85 $activeUserDays = $this->
getConfig()->get( MainConfigNames::ActiveUserDays );
89 $prop = $params[
'prop'];
90 if ( $prop !==
null ) {
91 $prop = array_fill_keys( $prop,
true );
92 $fld_blockinfo = isset( $prop[
'blockinfo'] );
93 $fld_editcount = isset( $prop[
'editcount'] );
94 $fld_groups = isset( $prop[
'groups'] );
95 $fld_rights = isset( $prop[
'rights'] );
96 $fld_registration = isset( $prop[
'registration'] );
97 $fld_implicitgroups = isset( $prop[
'implicitgroups'] );
98 $fld_centralids = isset( $prop[
'centralids'] );
100 $fld_blockinfo = $fld_editcount = $fld_groups = $fld_registration =
101 $fld_rights = $fld_implicitgroups = $fld_centralids =
false;
104 $limit = $params[
'limit'];
108 $dir = ( $params[
'dir'] ==
'descending' ?
'older' :
'newer' );
112 # MySQL can't figure out that 'user_name' and 'qcc_title' are the same
113 # despite the JOIN condition, so manually sort on the correct one.
114 $userFieldToSort = $params[
'activeusers'] ?
'qcc_title' :
'user_name';
116 # Some of these subtable joins are going to give us duplicate rows, so
117 # calculate the maximum number of duplicates we might see.
118 $maxDuplicateRows = 1;
122 if ( $params[
'prefix'] !==
null ) {
124 $db->buildLike( $this->getCanonicalUserName( $params[
'prefix'] ), $db->anyString() ) );
127 if ( $params[
'rights'] !==
null && count( $params[
'rights'] ) ) {
129 foreach ( $params[
'rights'] as $r ) {
130 $groups = array_merge( $groups, $this->groupPermissionsLookup->getGroupsWithPermission( $r ) );
134 if ( $groups === [] ) {
140 $groups = array_unique( $groups );
142 if ( $params[
'group'] ===
null ) {
143 $params[
'group'] = $groups;
145 $params[
'group'] = array_unique( array_merge( $params[
'group'], $groups ) );
151 if ( $params[
'group'] !==
null && count( $params[
'group'] ) ) {
154 $this->
addTables(
'user_groups',
'ug1' );
159 'ug1.ug_user=user_id',
160 'ug1.ug_group' => $params[
'group'],
161 'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
165 $maxDuplicateRows *= count( $params[
'group'] );
168 if ( $params[
'excludegroup'] !==
null && count( $params[
'excludegroup'] ) ) {
171 $this->
addTables(
'user_groups',
'ug1' );
173 if ( count( $params[
'excludegroup'] ) == 1 ) {
174 $exclude = [
'ug1.ug_group' => $params[
'excludegroup'][0] ];
176 $exclude = [ $db->makeList(
177 [
'ug1.ug_group' => $params[
'excludegroup'] ],
183 'ug1.ug_user=user_id',
184 'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
187 $this->
addWhere(
'ug1.ug_user IS NULL' );
190 if ( $params[
'witheditsonly'] ) {
191 $this->
addWhere(
'user_editcount > 0' );
196 if ( $fld_groups || $fld_rights ) {
198 $db->buildGroupConcatField(
'|',
'user_groups',
'ug_group', [
200 'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
205 if ( $params[
'activeusers'] ) {
206 $activeUserSeconds = $activeUserDays * 86400;
213 'qcc_type' =>
'activeusers',
215 'qcc_title=user_name',
220 $tables = [
'recentchanges',
'actor' ];
222 'actor' => [
'JOIN',
'rc_actor = actor_id' ],
224 $timestamp = $db->timestamp( (
int)
wfTimestamp( TS_UNIX ) - $activeUserSeconds );
226 'recentactions' =>
'(' . $db->selectSQLText(
230 'actor_user = user_id',
232 'rc_log_type IS NULL OR rc_log_type != ' . $db->addQuotes(
'newusers' ),
233 'rc_timestamp >= ' . $db->addQuotes( $timestamp ),
242 $sqlLimit = $limit + $maxDuplicateRows;
249 $this->
addFieldsIf(
'user_editcount', $fld_editcount );
250 $this->
addFieldsIf(
'user_registration', $fld_registration );
254 $countDuplicates = 0;
257 foreach (
$res as $row ) {
260 if ( $lastUser === $row->user_name ) {
265 if ( $countDuplicates == $maxDuplicateRows ) {
271 $countDuplicates = 0;
272 $lastUser = $row->user_name;
274 if ( $count > $limit ) {
281 if ( $count == $sqlLimit ) {
288 if ( $params[
'activeusers'] && (
int)$row->recentactions === 0 ) {
294 'userid' => (int)$row->user_id,
295 'name' => $row->user_name,
298 if ( $fld_centralids ) {
300 $this->
getConfig(), $this->userFactory->newFromId( (
int)$row->user_id ), $params[
'attachedwiki']
304 if ( $fld_blockinfo && $row->ipb_id !==
null ) {
305 $data += $this->getBlockDetails( DatabaseBlock::newFromRow( $row ) );
307 if ( $row->ipb_deleted ) {
308 $data[
'hidden'] =
true;
310 if ( $fld_editcount ) {
311 $data[
'editcount'] = (int)$row->user_editcount;
313 if ( $params[
'activeusers'] ) {
314 $data[
'recentactions'] = (int)$row->recentactions;
316 if ( $fld_registration ) {
317 $data[
'registration'] = $row->user_registration ?
318 wfTimestamp( TS_ISO_8601, $row->user_registration ) :
'';
321 if ( $fld_implicitgroups || $fld_groups || $fld_rights ) {
322 $implicitGroups = $this->userGroupManager
323 ->getUserImplicitGroups( $this->userFactory->newFromId( (
int)$row->user_id ) );
324 if ( isset( $row->groups ) && $row->groups !==
'' ) {
325 $groups = array_merge( $implicitGroups, explode(
'|', $row->groups ) );
327 $groups = $implicitGroups;
331 $data[
'groups'] = $groups;
336 if ( $fld_implicitgroups ) {
337 $data[
'implicitgroups'] = $implicitGroups;
343 $data[
'rights'] = $this->groupPermissionsLookup->getGroupPermissions( $groups );
349 $fit = $result->addValue( [
'query', $this->
getModuleName() ],
null, $data );
356 $result->addIndexedTagName( [
'query', $this->
getModuleName() ],
'u' );
360 return 'anon-public-user-private';
364 $userGroups = $this->userGroupManager->listAllGroups();
391 ApiBase::PARAM_ISMULTI =>
true,
413 'witheditsonly' =>
false,
417 'apihelp-query+allusers-param-activeusers',
418 $this->
getConfig()->get( MainConfigNames::ActiveUserDays )
421 'attachedwiki' =>
null,
427 'action=query&list=allusers&aufrom=Y'
428 =>
'apihelp-query+allusers-example-y',
433 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Allusers';
addBlockInfoToQuery( $showBlockInfo)
Filters hidden users (where the user doesn't have the right to view them) Also adds relevant block in...
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
const LIMIT_BIG1
Fast query, standard limit.
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
const LIMIT_BIG2
Fast query, apihighlimits limit.
getModuleName()
Get the name of the module being executed by this instance.
Query module to enumerate all registered users.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
__construct(ApiQuery $query, $moduleName, UserFactory $userFactory, UserGroupManager $userGroupManager, GroupPermissionsLookup $groupPermissionsLookup, Language $contentLanguage)
getExamplesMessages()
Returns usage examples for this module.
Language $contentLanguage
getAllowedParams( $flags=0)
UserGroupManager $userGroupManager
GroupPermissionsLookup $groupPermissionsLookup
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getCanonicalUserName( $name)
This function converts the user name to a canonical form which is stored in the database.
getHelpUrls()
Return links to more detailed help pages about the module.
This is a base class for all Query modules.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
addWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, and an ORDER BY clause to sort in the right direction.
addFields( $value)
Add a set of fields to select to the internal array.
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
getDB()
Get the Query database connection (read-only)
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
addFieldsIf( $value, $condition)
Same as addFields(), but add the fields only if a condition is met.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
addWhere( $value)
Add a set of WHERE clauses to the internal array.
static getCentralUserInfo(Config $config, UserIdentity $user, $attachedWiki=UserIdentity::LOCAL)
Get central user info.
This is the main query class.
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
A class containing constants representing the names of configuration variables.
trait ApiQueryBlockInfoTrait