61 private $blockStatusByUid;
67 private $excludegroups;
94 $this->requestedUser =
'';
98 $username = Title::makeTitleSafe(
NS_USER, $un );
99 if ( $username !==
null ) {
100 $this->requestedUser = $username->getText();
108 $this->excludegroups[] =
'bot';
111 $this->excludegroups[] =
'sysop';
123 $timestamp = $dbr->timestamp( (
int)
wfTimestamp( TS_UNIX ) - $activeUserSeconds );
127 $subquery = $dbr->newSelectQueryBuilder()
128 ->select( [
'qcc_title',
'user_id',
'actor_id' ] )
129 ->from(
'querycachetwo' )
130 ->join(
'user',
null,
'user_name = qcc_title' )
131 ->join(
'actor',
null,
'actor_user = user_id' )
133 'qcc_type' =>
'activeusers',
137 if ( $data !==
null ) {
139 ->orderBy(
'qcc_title', $data[
'order'] )
140 ->limit( $data[
'limit'] )
141 ->andWhere( $data[
'conds'] );
143 if ( $this->requestedUser !=
'' ) {
144 $subquery->andWhere( $dbr->expr(
'qcc_title',
'>=', $this->requestedUser ) );
146 if ( $this->groups !== [] ) {
148 ->join(
'user_groups',
'ug1',
'ug1.ug_user = user_id' )
150 'ug1.ug_group' => $this->groups,
151 $dbr->expr(
'ug1.ug_expiry',
'=',
null )->or(
'ug1.ug_expiry',
'>=', $dbr->timestamp() ),
154 if ( $this->excludegroups !== [] ) {
156 ->leftJoin(
'user_groups',
'ug2', [
157 'ug2.ug_user = user_id',
158 'ug2.ug_group' => $this->excludegroups,
159 $dbr->expr(
'ug2.ug_expiry',
'=',
null )->or(
'ug2.ug_expiry',
'>=', $dbr->timestamp() ),
161 ->andWhere( [
'ug2.ug_user' =>
null ] );
164 $subquery->andWhere( $this->hideUserUtils->getExpression( $dbr ) );
169 'tables' => [
'qcc_users' =>
new Subquery( $subquery->getSQL() ),
'recentchanges' ],
172 'user_name' =>
'qcc_title',
173 'user_id' =>
'user_id',
174 'recentedits' =>
'COUNT(DISTINCT rc_id)'
176 'options' => [
'GROUP BY' => [
'qcc_title',
'user_id' ] ],
178 'join_conds' => [
'recentchanges' => [
'LEFT JOIN', [
179 'rc_actor = actor_id',
182 $dbr->expr(
'rc_log_type',
'=',
null )->or(
'rc_log_type',
'!=',
'newusers' ),
183 $dbr->expr(
'rc_timestamp',
'>=', $timestamp ),
191 $sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
192 if ( $order === self::QUERY_ASCENDING ) {
194 $orderBy = $sortColumns;
195 $operator = $this->mIncludeOffset ?
'>=' :
'>';
199 foreach ( $sortColumns as $col ) {
200 $orderBy[] = $col .
' DESC';
202 $operator = $this->mIncludeOffset ?
'<=' :
'<';
205 'limit' => intval( $limit ),
208 $offset !=
'' ? [ $this->
getDatabase()->expr( $this->mIndexField, $operator, $offset ) ] : [],
211 $tables = $info[
'tables'];
212 $fields = $info[
'fields'];
213 $conds = $info[
'conds'];
214 $options = $info[
'options'];
215 $join_conds = $info[
'join_conds'];
216 $options[
'ORDER BY'] = $orderBy;
217 return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
221 parent::doBatchLookups();
224 foreach ( $this->mResult as $row ) {
225 $uids[] = (int)$row->user_id;
232 $res = $dbr->newSelectQueryBuilder()
235 'deleted' =>
'MAX(bl_deleted)',
236 'sitewide' =>
'MAX(bl_sitewide)'
238 ->from(
'block_target' )
239 ->join(
'block',
null,
'bl_target=bt_id' )
240 ->where( [
'bt_user' => $uids ] )
241 ->groupBy( [
'bt_user' ] )
242 ->caller( __METHOD__ )->fetchResultSet();
243 $this->blockStatusByUid = [];
244 foreach ( $res as $row ) {
245 $this->blockStatusByUid[$row->bt_user] = [
246 'deleted' => $row->deleted,
247 'sitewide' => $row->sitewide,
250 $this->mResult->seek( 0 );
254 $userName = $row->user_name;
256 $ulinks = Linker::userLink( $row->user_id, $userName );
257 $ulinks .= Linker::userToolLinks(
276 foreach ( $ugms as $ugm ) {
280 $groups = $lang->commaList( $list );
282 $item = $lang->specialList( $ulinks,
$groups );
287 $isBlocked = isset( $this->blockStatusByUid[$row->user_id] );
289 if ( $this->blockStatusByUid[$row->user_id][
'deleted'] == 1 ) {
290 $item =
"<span class=\"deleted\">$item</span>";
292 if ( $this->blockStatusByUid[$row->user_id][
'sitewide'] == 1 ) {
293 $blocked =
' ' . $this->
msg(
'listusers-blocked', $userName )->escaped();
296 $count = $this->
msg(
'activeusers-count' )->numParams( $row->recentedits )
297 ->params( $userName )->numParams( $this->RCMaxAge )->escaped();
299 return Html::rawElement(
'li', [],
"{$item} [{$count}]{$blocked}" );
308class_alias( ActiveUsersPager::class,
'ActiveUsersPager' );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
A class containing constants representing the names of configuration variables.
const ActiveUserDays
Name constant for the ActiveUserDays setting, for use with Config::get()
Interface for objects which can provide a MediaWiki context on request.