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