60 private $blockStatusByUid;
66 private $excludegroups;
101 $this->requestedUser =
'';
105 $username = Title::makeTitleSafe(
NS_USER, $un );
106 if ( $username !==
null ) {
107 $this->requestedUser = $username->getText();
115 $this->excludegroups[] =
'bot';
118 $this->excludegroups[] =
'sysop';
130 $timestamp = $dbr->timestamp( (
int)
wfTimestamp( TS_UNIX ) - $activeUserSeconds );
134 $subquery = $dbr->newSelectQueryBuilder()
135 ->select( [
'qcc_title',
'user_id',
'actor_id' ] )
136 ->from(
'querycachetwo' )
137 ->join(
'user',
null,
'user_name = qcc_title' )
138 ->join(
'actor',
null,
'actor_user = user_id' )
140 'qcc_type' =>
'activeusers',
144 if ( $data !==
null ) {
146 ->orderBy(
'qcc_title', $data[
'order'] )
147 ->limit( $data[
'limit'] )
148 ->andWhere( $data[
'conds'] );
150 if ( $this->requestedUser !=
'' ) {
151 $subquery->andWhere( $dbr->expr(
'qcc_title',
'>=', $this->requestedUser ) );
153 if ( $this->groups !== [] ) {
155 ->join(
'user_groups',
'ug1',
'ug1.ug_user = user_id' )
157 'ug1.ug_group' => $this->groups,
158 $dbr->expr(
'ug1.ug_expiry',
'=',
null )->or(
'ug1.ug_expiry',
'>=', $dbr->timestamp() ),
161 if ( $this->excludegroups !== [] ) {
163 ->leftJoin(
'user_groups',
'ug2', [
164 'ug2.ug_user = user_id',
165 'ug2.ug_group' => $this->excludegroups,
166 $dbr->expr(
'ug2.ug_expiry',
'=',
null )->or(
'ug2.ug_expiry',
'>=', $dbr->timestamp() ),
168 ->andWhere( [
'ug2.ug_user' =>
null ] );
171 $subquery->andWhere( $this->hideUserUtils->getExpression( $dbr ) );
176 'tables' => [
'qcc_users' =>
new Subquery( $subquery->getSQL() ),
'recentchanges' ],
179 'user_name' =>
'qcc_title',
180 'user_id' =>
'user_id',
181 'recentedits' =>
'COUNT(DISTINCT rc_id)'
183 'options' => [
'GROUP BY' => [
'qcc_title',
'user_id' ] ],
185 'join_conds' => [
'recentchanges' => [
'LEFT JOIN', [
186 'rc_actor = actor_id',
189 $dbr->expr(
'rc_log_type',
'=',
null )->or(
'rc_log_type',
'!=',
'newusers' ),
190 $dbr->expr(
'rc_timestamp',
'>=', $timestamp ),
198 $sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
199 if ( $order === self::QUERY_ASCENDING ) {
201 $orderBy = $sortColumns;
202 $operator = $this->mIncludeOffset ?
'>=' :
'>';
206 foreach ( $sortColumns as $col ) {
207 $orderBy[] = $col .
' DESC';
209 $operator = $this->mIncludeOffset ?
'<=' :
'<';
212 'limit' => intval( $limit ),
215 $offset !=
'' ? [ $this->
getDatabase()->expr( $this->mIndexField, $operator, $offset ) ] : [],
218 $tables = $info[
'tables'];
219 $fields = $info[
'fields'];
220 $conds = $info[
'conds'];
221 $options = $info[
'options'];
222 $join_conds = $info[
'join_conds'];
223 $options[
'ORDER BY'] = $orderBy;
224 return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
228 parent::doBatchLookups();
231 foreach ( $this->mResult as $row ) {
232 $uids[] = (int)$row->user_id;
239 $res = $dbr->newSelectQueryBuilder()
242 'deleted' =>
'MAX(bl_deleted)',
243 'sitewide' =>
'MAX(bl_sitewide)'
245 ->from(
'block_target' )
246 ->join(
'block',
null,
'bl_target=bt_id' )
247 ->where( [
'bt_user' => $uids ] )
248 ->groupBy( [
'bt_user' ] )
249 ->caller( __METHOD__ )->fetchResultSet();
250 $this->blockStatusByUid = [];
251 foreach ( $res as $row ) {
252 $this->blockStatusByUid[$row->bt_user] = [
253 'deleted' => $row->deleted,
254 'sitewide' => $row->sitewide,
257 $this->mResult->seek( 0 );
261 $userName = $row->user_name;
263 $ulinks = Linker::userLink( $row->user_id, $userName );
264 $ulinks .= Linker::userToolLinks(
283 foreach ( $ugms as $ugm ) {
287 $groups = $lang->commaList( $list );
289 $item = $lang->specialList( $ulinks,
$groups );
294 $isBlocked = isset( $this->blockStatusByUid[$row->user_id] );
296 if ( $this->blockStatusByUid[$row->user_id][
'deleted'] == 1 ) {
297 $item =
"<span class=\"deleted\">$item</span>";
299 if ( $this->blockStatusByUid[$row->user_id][
'sitewide'] == 1 ) {
300 $blocked =
' ' . $this->
msg(
'listusers-blocked', $userName )->escaped();
303 $count = $this->
msg(
'activeusers-count' )->numParams( $row->recentedits )
304 ->params( $userName )->numParams( $this->RCMaxAge )->escaped();
306 return Html::rawElement(
'li', [],
"{$item} [{$count}]{$blocked}" );
315class_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.