MediaWiki
1.41.2
ActiveUsersPager.php
Go to the documentation of this file.
1
<?php
22
namespace
MediaWiki\Pager
;
23
24
use
IContextSource
;
25
use
MediaWiki\Cache\LinkBatchFactory
;
26
use
MediaWiki\HookContainer\HookContainer
;
27
use
MediaWiki\Html\FormOptions
;
28
use
MediaWiki\Html\Html
;
29
use
MediaWiki\Linker\Linker
;
30
use
MediaWiki\MainConfigNames
;
31
use
MediaWiki\Title\Title
;
32
use
MediaWiki\User\UserGroupManager
;
33
use
MediaWiki\User\UserIdentityLookup
;
34
use
MediaWiki\User\UserIdentityValue
;
35
use
Wikimedia\Rdbms\IConnectionProvider
;
36
44
class
ActiveUsersPager
extends
UsersPager
{
45
49
protected
$opts
;
50
54
protected
$groups
;
55
59
private
$blockStatusByUid;
60
62
private
$RCMaxAge;
63
65
private
$excludegroups;
66
76
public
function
__construct
(
77
IContextSource
$context,
78
HookContainer
$hookContainer,
79
LinkBatchFactory
$linkBatchFactory,
80
IConnectionProvider
$dbProvider,
81
UserGroupManager
$userGroupManager,
82
UserIdentityLookup
$userIdentityLookup,
83
FormOptions
$opts
84
) {
85
parent::__construct(
86
$context,
87
$hookContainer,
88
$linkBatchFactory,
89
$dbProvider,
90
$userGroupManager,
91
$userIdentityLookup,
92
null
,
93
null
94
);
95
96
$this->RCMaxAge = $this->
getConfig
()->get(
MainConfigNames::ActiveUserDays
);
97
$this->requestedUser =
''
;
98
99
$un =
$opts
->
getValue
(
'username'
);
100
if
( $un !=
''
) {
101
$username = Title::makeTitleSafe(
NS_USER
, $un );
102
if
( $username !==
null
) {
103
$this->requestedUser = $username->getText();
104
}
105
}
106
107
$this->groups =
$opts
->
getValue
(
'groups'
);
108
$this->excludegroups =
$opts
->
getValue
(
'excludegroups'
);
109
// Backwards-compatibility with old URLs
110
if
(
$opts
->
getValue
(
'hidebots'
) ) {
111
$this->excludegroups[] =
'bot'
;
112
}
113
if
(
$opts
->
getValue
(
'hidesysops'
) ) {
114
$this->excludegroups[] =
'sysop'
;
115
}
116
}
117
118
public
function
getIndexField
() {
119
return
'qcc_title'
;
120
}
121
122
public
function
getQueryInfo
( $data =
null
) {
123
$dbr = $this->
getDatabase
();
124
125
$activeUserSeconds = $this->
getConfig
()->get(
MainConfigNames::ActiveUserDays
) * 86400;
126
$timestamp = $dbr->timestamp( (
int
)
wfTimestamp
( TS_UNIX ) - $activeUserSeconds );
127
$fname = __METHOD__ .
' ('
. $this->
getSqlComment
() .
')'
;
128
129
// Inner subselect to pull the active users out of querycachetwo
130
$tables = [
'querycachetwo'
,
'user'
,
'actor'
];
131
$fields = [
'qcc_title'
,
'user_id'
,
'actor_id'
];
132
$jconds = [
133
'user'
=> [
'JOIN'
,
'user_name = qcc_title'
],
134
'actor'
=> [
'JOIN'
,
'actor_user = user_id'
],
135
];
136
$conds = [
137
'qcc_type'
=>
'activeusers'
,
138
'qcc_namespace'
=>
NS_USER
,
139
];
140
$options = [];
141
if
( $data !==
null
) {
142
$options[
'ORDER BY'
] =
'qcc_title '
. $data[
'order'
];
143
$options[
'LIMIT'
] = $data[
'limit'
];
144
$conds = array_merge( $conds, $data[
'conds'
] );
145
}
146
if
( $this->requestedUser !=
''
) {
147
$conds[] =
'qcc_title >= '
. $dbr->addQuotes( $this->requestedUser );
148
}
149
if
( $this->groups !== [] ) {
150
$tables[
'ug1'
] =
'user_groups'
;
151
$jconds[
'ug1'
] = [
'JOIN'
,
'ug1.ug_user = user_id'
];
152
$conds[
'ug1.ug_group'
] =
$this->groups
;
153
$conds[] =
'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= '
. $dbr->addQuotes( $dbr->timestamp() );
154
}
155
if
( $this->excludegroups !== [] ) {
156
$tables[
'ug2'
] =
'user_groups'
;
157
$jconds[
'ug2'
] = [
'LEFT JOIN'
, [
158
'ug2.ug_user = user_id'
,
159
'ug2.ug_group'
=> $this->excludegroups,
160
'ug2.ug_expiry IS NULL OR ug2.ug_expiry >= '
. $dbr->addQuotes( $dbr->timestamp() ),
161
] ];
162
$conds[
'ug2.ug_user'
] =
null
;
163
}
164
if
( !$this->
canSeeHideuser
() ) {
165
$conds[] =
'NOT EXISTS ('
. $dbr->selectSQLText(
166
'ipblocks'
,
'1'
, [
'ipb_user=user_id'
,
'ipb_deleted'
=> 1 ], __METHOD__
167
) .
')'
;
168
}
169
$subquery = $dbr->buildSelectSubquery( $tables, $fields, $conds, $fname, $options, $jconds );
170
171
// Outer query to select the recent edit counts for the selected active users
172
$tables = [
'qcc_users'
=> $subquery,
'recentchanges'
];
173
$jconds = [
'recentchanges'
=> [
'LEFT JOIN'
, [
174
'rc_actor = actor_id'
,
175
'rc_type != '
. $dbr->addQuotes(
RC_EXTERNAL
),
// Don't count wikidata.
176
'rc_type != '
. $dbr->addQuotes(
RC_CATEGORIZE
),
// Don't count categorization changes.
177
'rc_log_type IS NULL OR rc_log_type != '
. $dbr->addQuotes(
'newusers'
),
178
'rc_timestamp >= '
. $dbr->addQuotes( $timestamp ),
179
] ] ];
180
$conds = [];
181
182
return
[
183
'tables'
=> $tables,
184
'fields'
=> [
185
'qcc_title'
,
186
'user_name'
=>
'qcc_title'
,
187
'user_id'
=>
'user_id'
,
188
'recentedits'
=>
'COUNT(DISTINCT rc_id)'
189
],
190
'options'
=> [
'GROUP BY'
=> [
'qcc_title'
,
'user_id'
] ],
191
'conds'
=> $conds,
192
'join_conds'
=> $jconds,
193
];
194
}
195
196
protected
function
buildQueryInfo
( $offset, $limit, $order ) {
197
$fname = __METHOD__ .
' ('
. $this->
getSqlComment
() .
')'
;
198
199
$sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
200
if
( $order === self::QUERY_ASCENDING ) {
201
$dir =
'ASC'
;
202
$orderBy = $sortColumns;
203
$operator = $this->mIncludeOffset ?
'>='
:
'>'
;
204
}
else
{
205
$dir =
'DESC'
;
206
$orderBy = [];
207
foreach
( $sortColumns as $col ) {
208
$orderBy[] = $col .
' DESC'
;
209
}
210
$operator = $this->mIncludeOffset ?
'<='
:
'<'
;
211
}
212
$info = $this->
getQueryInfo
( [
213
'limit'
=> intval( $limit ),
214
'order'
=> $dir,
215
'conds'
=>
216
$offset !=
''
? [ $this->mIndexField . $operator . $this->
getDatabase
()->addQuotes( $offset ) ] : [],
217
] );
218
219
$tables = $info[
'tables'
];
220
$fields = $info[
'fields'
];
221
$conds = $info[
'conds'
];
222
$options = $info[
'options'
];
223
$join_conds = $info[
'join_conds'
];
224
$options[
'ORDER BY'
] = $orderBy;
225
return
[ $tables, $fields, $conds, $fname, $options, $join_conds ];
226
}
227
228
protected
function
doBatchLookups
() {
229
parent::doBatchLookups();
230
231
$uids = [];
232
foreach
( $this->mResult as $row ) {
233
$uids[] = (int)$row->user_id;
234
}
235
// Fetch the block status of the user for showing "(blocked)" text and for
236
// striking out names of suppressed users when privileged user views the list.
237
// Although the first query already hits the block table for un-privileged, this
238
// is done in two queries to avoid huge quicksorts and to make COUNT(*) correct.
239
$dbr = $this->
getDatabase
();
240
$res = $dbr->newSelectQueryBuilder()
241
->select( [
'ipb_user'
,
'deleted'
=>
'MAX(ipb_deleted)'
,
'sitewide'
=>
'MAX(ipb_sitewide)'
] )
242
->from(
'ipblocks'
)
243
->where( [
'ipb_user'
=> $uids ] )
244
->groupBy( [
'ipb_user'
] )
245
->caller( __METHOD__ )->fetchResultSet();
246
$this->blockStatusByUid = [];
247
foreach
( $res as $row ) {
248
$this->blockStatusByUid[$row->ipb_user] = [
249
'deleted'
=> $row->deleted,
250
'sitewide'
=> $row->sitewide,
251
];
252
}
253
$this->mResult->seek( 0 );
254
}
255
256
public
function
formatRow
( $row ) {
257
$userName = $row->user_name;
258
259
$ulinks = Linker::userLink( $row->user_id, $userName );
260
$ulinks .= Linker::userToolLinks(
261
$row->user_id,
262
$userName,
263
// Should the contributions link be red if the user has no edits (using default)
264
false
,
265
// Customisation flags (using default 0)
266
0,
267
// User edit count (using default)
268
null
,
269
// do not wrap the message in parentheses (CSS will provide these)
270
false
271
);
272
273
$lang = $this->
getLanguage
();
274
275
$list = [];
276
277
$userIdentity =
new
UserIdentityValue
( intval( $row->user_id ), $userName );
278
$ugms = $this->
getGroupMemberships
( $userIdentity );
279
foreach
( $ugms as $ugm ) {
280
$list[] = $this->
buildGroupLink
( $ugm, $userName );
281
}
282
283
$groups
= $lang->commaList( $list );
284
285
$item = $lang->specialList( $ulinks,
$groups
);
286
287
// If there is a block, 'deleted' and 'sitewide' are both set on
288
// $this->blockStatusByUid[$row->user_id].
289
$blocked =
''
;
290
$isBlocked = isset( $this->blockStatusByUid[$row->user_id] );
291
if
( $isBlocked ) {
292
if
( $this->blockStatusByUid[$row->user_id][
'deleted'
] == 1 ) {
293
$item =
"<span class=\"deleted\">$item</span>"
;
294
}
295
if
( $this->blockStatusByUid[$row->user_id][
'sitewide'
] == 1 ) {
296
$blocked =
' '
. $this->
msg
(
'listusers-blocked'
, $userName )->escaped();
297
}
298
}
299
$count = $this->
msg
(
'activeusers-count'
)->numParams( $row->recentedits )
300
->params( $userName )->numParams( $this->RCMaxAge )->escaped();
301
302
return
Html::rawElement(
'li'
, [],
"{$item} [{$count}]{$blocked}"
);
303
}
304
305
}
306
311
class_alias( ActiveUsersPager::class,
'ActiveUsersPager'
);
NS_USER
const NS_USER
Definition
Defines.php:66
RC_EXTERNAL
const RC_EXTERNAL
Definition
Defines.php:119
RC_CATEGORIZE
const RC_CATEGORIZE
Definition
Defines.php:120
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition
GlobalFunctions.php:1364
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition
ContextSource.php:202
ContextSource\getConfig
getConfig()
Definition
ContextSource.php:77
ContextSource\getLanguage
getLanguage()
Definition
ContextSource.php:169
MediaWiki\Cache\LinkBatchFactory
Definition
LinkBatchFactory.php:41
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition
HookContainer.php:58
MediaWiki\Html\FormOptions
Helper class to keep track of options when mixing links and form elements.
Definition
FormOptions.php:41
MediaWiki\Html\FormOptions\getValue
getValue( $name)
Get the value for the given option name.
Definition
FormOptions.php:190
MediaWiki\Html\Html
This class is a collection of static functions that serve two purposes:
Definition
Html.php:57
MediaWiki\Linker\Linker
Some internal bits split of from Skin.php.
Definition
Linker.php:65
MediaWiki\MainConfigNames
A class containing constants representing the names of configuration variables.
Definition
MainConfigNames.php:22
MediaWiki\MainConfigNames\ActiveUserDays
const ActiveUserDays
Name constant for the ActiveUserDays setting, for use with Config::get()
Definition
MainConfigNames.php:2487
MediaWiki\Pager\ActiveUsersPager
This class is used to get a list of active users.
Definition
ActiveUsersPager.php:44
MediaWiki\Pager\ActiveUsersPager\getQueryInfo
getQueryInfo( $data=null)
Definition
ActiveUsersPager.php:122
MediaWiki\Pager\ActiveUsersPager\formatRow
formatRow( $row)
Definition
ActiveUsersPager.php:256
MediaWiki\Pager\ActiveUsersPager\doBatchLookups
doBatchLookups()
Called from getBody(), before getStartBody() is called and after doQuery() was called.
Definition
ActiveUsersPager.php:228
MediaWiki\Pager\ActiveUsersPager\getIndexField
getIndexField()
Definition
ActiveUsersPager.php:118
MediaWiki\Pager\ActiveUsersPager\buildQueryInfo
buildQueryInfo( $offset, $limit, $order)
Build variables to use by the database wrapper.
Definition
ActiveUsersPager.php:196
MediaWiki\Pager\ActiveUsersPager\$opts
FormOptions $opts
Definition
ActiveUsersPager.php:49
MediaWiki\Pager\ActiveUsersPager\__construct
__construct(IContextSource $context, HookContainer $hookContainer, LinkBatchFactory $linkBatchFactory, IConnectionProvider $dbProvider, UserGroupManager $userGroupManager, UserIdentityLookup $userIdentityLookup, FormOptions $opts)
Definition
ActiveUsersPager.php:76
MediaWiki\Pager\ActiveUsersPager\$groups
string[] $groups
Definition
ActiveUsersPager.php:54
MediaWiki\Pager\IndexPager\getDatabase
getDatabase()
Get the Database object in use.
Definition
IndexPager.php:256
MediaWiki\Pager\IndexPager\getSqlComment
getSqlComment()
Get some text to go in brackets in the "function name" part of the SQL comment.
Definition
IndexPager.php:447
MediaWiki\Pager\UsersPager
This class is used to get a list of user.
Definition
UsersPager.php:57
MediaWiki\Pager\UsersPager\canSeeHideuser
canSeeHideuser()
Definition
UsersPager.php:440
MediaWiki\Pager\UsersPager\getQueryInfo
getQueryInfo()
Definition
UsersPager.php:168
MediaWiki\Pager\UsersPager\getGroupMemberships
getGroupMemberships( $user)
Get an associative array containing groups the specified user belongs to, and the relevant UserGroupM...
Definition
UsersPager.php:483
MediaWiki\Pager\UsersPager\buildGroupLink
buildGroupLink( $group, $username)
Format a link to a group description page.
Definition
UsersPager.php:498
MediaWiki\Title\Title
Represents a title within MediaWiki.
Definition
Title.php:76
MediaWiki\User\UserGroupManager
Manages user groups.
Definition
UserGroupManager.php:52
MediaWiki\User\UserIdentityValue
Value object representing a user's identity.
Definition
UserIdentityValue.php:35
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition
IContextSource.php:64
MediaWiki\User\UserIdentityLookup
Definition
UserIdentityLookup.php:33
Wikimedia\Rdbms\IConnectionProvider
Provide primary and replica IDatabase connections.
Definition
IConnectionProvider.php:35
MediaWiki\Pager
Definition
HistoryPager.php:24
includes
specials
pagers
ActiveUsersPager.php
Generated on Thu Jun 27 2024 15:43:27 for MediaWiki by
1.10.0