MediaWiki master
SpecialActiveUsers.php
Go to the documentation of this file.
1<?php
24namespace MediaWiki\Specials;
25
37
44
45 private LinkBatchFactory $linkBatchFactory;
46 private IConnectionProvider $dbProvider;
47 private UserGroupManager $userGroupManager;
48 private UserIdentityLookup $userIdentityLookup;
49 private HideUserUtils $hideUserUtils;
50
58 public function __construct(
59 LinkBatchFactory $linkBatchFactory,
60 IConnectionProvider $dbProvider,
61 UserGroupManager $userGroupManager,
62 UserIdentityLookup $userIdentityLookup,
63 HideUserUtils $hideUserUtils
64 ) {
65 parent::__construct( 'Activeusers' );
66 $this->linkBatchFactory = $linkBatchFactory;
67 $this->dbProvider = $dbProvider;
68 $this->userGroupManager = $userGroupManager;
69 $this->userIdentityLookup = $userIdentityLookup;
70 $this->hideUserUtils = $hideUserUtils;
71 }
72
76 public function execute( $par ) {
77 $out = $this->getOutput();
78
79 $this->setHeaders();
80 $this->outputHeader();
81
82 $opts = new FormOptions();
83
84 $opts->add( 'username', '' );
85 $opts->add( 'groups', [] );
86 $opts->add( 'excludegroups', [] );
87 // Backwards-compatibility with old URLs
88 $opts->add( 'hidebots', false, FormOptions::BOOL );
89 $opts->add( 'hidesysops', false, FormOptions::BOOL );
90
91 $opts->fetchValuesFromRequest( $this->getRequest() );
92
93 if ( $par !== null ) {
94 $opts->setValue( 'username', $par );
95 }
96
97 $pager = new ActiveUsersPager(
98 $this->getContext(),
99 $this->getHookContainer(),
100 $this->linkBatchFactory,
101 $this->dbProvider,
102 $this->userGroupManager,
103 $this->userIdentityLookup,
104 $this->hideUserUtils,
105 $opts
106 );
107 $usersBody = $pager->getBody();
108
109 $this->buildForm();
110
111 if ( $usersBody ) {
112 $out->addHTML(
113 $pager->getNavigationBar() .
114 Html::rawElement( 'ul', [], $usersBody ) .
115 $pager->getNavigationBar()
116 );
117 $out->addModuleStyles( 'mediawiki.interface.helpers.styles' );
118 } else {
119 $out->addWikiMsg( 'activeusers-noresult' );
120 }
121 }
122
126 protected function buildForm() {
127 $groups = $this->userGroupManager->listAllGroups();
128
129 $options = [];
130 $lang = $this->getLanguage();
131 foreach ( $groups as $group ) {
132 $msg = htmlspecialchars( $lang->getGroupName( $group ) );
133 $options[$msg] = $group;
134 }
135 ksort( $options );
136
137 // Backwards-compatibility with old URLs
138 $req = $this->getRequest();
139 $excludeDefault = [];
140 if ( $req->getCheck( 'hidebots' ) ) {
141 $excludeDefault[] = 'bot';
142 }
143 if ( $req->getCheck( 'hidesysops' ) ) {
144 $excludeDefault[] = 'sysop';
145 }
146
147 $formDescriptor = [
148 'username' => [
149 'type' => 'user',
150 'name' => 'username',
151 'label-message' => 'activeusers-from',
152 ],
153 'groups' => [
154 'type' => 'multiselect',
155 'dropdown' => true,
156 'flatlist' => true,
157 'name' => 'groups',
158 'label-message' => 'activeusers-groups',
159 'options' => $options,
160 ],
161 'excludegroups' => [
162 'type' => 'multiselect',
163 'dropdown' => true,
164 'flatlist' => true,
165 'name' => 'excludegroups',
166 'label-message' => 'activeusers-excludegroups',
167 'options' => $options,
168 'default' => $excludeDefault,
169 ],
170 ];
171
172 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
173 // For the 'multiselect' field values to be preserved on submit
174 ->setFormIdentifier( 'specialactiveusers' )
175 ->setPreHtml( $this->getIntroText() )
176 ->setWrapperLegendMsg( 'activeusers' )
177 ->setSubmitTextMsg( 'activeusers-submit' )
178 // prevent setting subpage and 'username' parameter at the same time
179 ->setTitle( $this->getPageTitle() )
180 ->setMethod( 'get' )
181 ->prepareForm()
182 ->displayForm( false );
183 }
184
189 protected function getIntroText() {
190 $days = $this->getConfig()->get( MainConfigNames::ActiveUserDays );
191
192 $intro = $this->msg( 'activeusers-intro' )->numParams( $days )->parse();
193
194 // Mention the level of cache staleness...
195 $dbr = $this->dbProvider->getReplicaDatabase();
196
197 $rcMax = $dbr->newSelectQueryBuilder()
198 ->select( 'MAX(rc_timestamp)' )
199 ->from( 'recentchanges' )
200 ->caller( __METHOD__ )->fetchField();
201 if ( $rcMax ) {
202 $cTime = $dbr->newSelectQueryBuilder()
203 ->select( 'qci_timestamp' )
204 ->from( 'querycache_info' )
205 ->where( [ 'qci_type' => 'activeusers' ] )
206 ->caller( __METHOD__ )->fetchField();
207 if ( $cTime ) {
208 $secondsOld = (int)wfTimestamp( TS_UNIX, $rcMax ) - (int)wfTimestamp( TS_UNIX, $cTime );
209 } else {
210 $rcMin = $dbr->newSelectQueryBuilder()
211 ->select( 'MIN(rc_timestamp)' )
212 ->from( 'recentchanges' )
213 ->caller( __METHOD__ )->fetchField();
214 $secondsOld = time() - (int)wfTimestamp( TS_UNIX, $rcMin );
215 }
216 if ( $secondsOld > 0 ) {
217 $intro .= $this->msg( 'cachedspecial-viewing-cached-ttl' )
218 ->durationParams( $secondsOld )->parseAsBlock();
219 }
220 }
221
222 return $intro;
223 }
224
225 protected function getGroupName() {
226 return 'users';
227 }
228}
229
233class_alias( SpecialActiveUsers::class, 'SpecialActiveUsers' );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Helpers for building queries that determine whether a user is hidden.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:206
Helper class to keep track of options when mixing links and form elements.
This class is a collection of static functions that serve two purposes:
Definition Html.php:56
A class containing constants representing the names of configuration variables.
const ActiveUserDays
Name constant for the ActiveUserDays setting, for use with Config::get()
This class is used to get a list of active users.
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getPageTitle( $subpage=false)
Get a self-referential title object.
getConfig()
Shortcut to get main config object.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getLanguage()
Shortcut to get user's language.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
Implements Special:Activeusers.
__construct(LinkBatchFactory $linkBatchFactory, IConnectionProvider $dbProvider, UserGroupManager $userGroupManager, UserIdentityLookup $userIdentityLookup, HideUserUtils $hideUserUtils)
buildForm()
Generate and output the form.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getIntroText()
Return introductory message.
Provide primary and replica IDatabase connections.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...