MediaWiki master
SpecialActiveUsers.php
Go to the documentation of this file.
1<?php
7namespace MediaWiki\Specials;
8
10use MediaWiki\Cache\LinkBatchFactory;
15use MediaWiki\Pager\ActiveUsersPager;
22use Wikimedia\Timestamp\TimestampFormat as TS;
23
30
31 private LinkBatchFactory $linkBatchFactory;
32 private IConnectionProvider $dbProvider;
33 private UserGroupManager $userGroupManager;
34 private UserIdentityLookup $userIdentityLookup;
35 private HideUserUtils $hideUserUtils;
36 private TempUserConfig $tempUserConfig;
37 private RecentChangeLookup $recentChangeLookup;
38
39 public function __construct(
40 LinkBatchFactory $linkBatchFactory,
41 IConnectionProvider $dbProvider,
42 UserGroupManager $userGroupManager,
43 UserIdentityLookup $userIdentityLookup,
44 HideUserUtils $hideUserUtils,
45 TempUserConfig $tempUserConfig,
46 RecentChangeLookup $recentChangeLookup
47 ) {
48 parent::__construct( 'Activeusers' );
49 $this->linkBatchFactory = $linkBatchFactory;
50 $this->dbProvider = $dbProvider;
51 $this->userGroupManager = $userGroupManager;
52 $this->userIdentityLookup = $userIdentityLookup;
53 $this->hideUserUtils = $hideUserUtils;
54 $this->tempUserConfig = $tempUserConfig;
55 $this->recentChangeLookup = $recentChangeLookup;
56 }
57
61 public function execute( $par ) {
62 $out = $this->getOutput();
63
64 $this->setHeaders();
65 $this->outputHeader();
66
67 $opts = new FormOptions();
68
69 $opts->add( 'username', '' );
70 $opts->add( 'groups', [] );
71 $opts->add( 'excludegroups', [] );
72 // Backwards-compatibility with old URLs
73 $opts->add( 'hidebots', false, FormOptions::BOOL );
74 $opts->add( 'hidesysops', false, FormOptions::BOOL );
75
76 $opts->fetchValuesFromRequest( $this->getRequest() );
77
78 if ( $par !== null ) {
79 $opts->setValue( 'username', $par );
80 }
81
82 $pager = new ActiveUsersPager(
83 $this->getContext(),
84 $this->getHookContainer(),
85 $this->linkBatchFactory,
86 $this->dbProvider,
87 $this->userGroupManager,
88 $this->userIdentityLookup,
89 $this->hideUserUtils,
90 $this->tempUserConfig,
91 $this->recentChangeLookup,
92 $opts
93 );
94 $usersBody = $pager->getBody();
95
96 $this->buildForm();
97
98 if ( $usersBody ) {
99 $out->addHTML(
100 $pager->getNavigationBar() .
101 Html::rawElement( 'ul', [], $usersBody ) .
102 $pager->getNavigationBar()
103 );
104 $out->addModuleStyles( 'mediawiki.interface.helpers.styles' );
105 } else {
106 $out->addWikiMsg( 'activeusers-noresult' );
107 }
108 }
109
113 protected function buildForm() {
114 $groups = $this->userGroupManager->listAllGroups();
115
116 $options = [];
117 $lang = $this->getLanguage();
118 foreach ( $groups as $group ) {
119 $msg = htmlspecialchars( $lang->getGroupName( $group ) );
120 $options[$msg] = $group;
121 }
122 ksort( $options );
123
124 // Backwards-compatibility with old URLs
125 $req = $this->getRequest();
126 $excludeDefault = [];
127 if ( $req->getCheck( 'hidebots' ) ) {
128 $excludeDefault[] = 'bot';
129 }
130 if ( $req->getCheck( 'hidesysops' ) ) {
131 $excludeDefault[] = 'sysop';
132 }
133
134 $formDescriptor = [
135 'username' => [
136 'type' => 'user',
137 'name' => 'username',
138 'label-message' => 'activeusers-from',
139 ],
140 'groups' => [
141 'type' => 'multiselect',
142 'dropdown' => true,
143 'flatlist' => true,
144 'name' => 'groups',
145 'label-message' => 'activeusers-groups',
146 'options' => $options,
147 ],
148 'excludegroups' => [
149 'type' => 'multiselect',
150 'dropdown' => true,
151 'flatlist' => true,
152 'name' => 'excludegroups',
153 'label-message' => 'activeusers-excludegroups',
154 'options' => $options,
155 'default' => $excludeDefault,
156 ],
157 ];
158
159 HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
160 // For the 'multiselect' field values to be preserved on submit
161 ->setFormIdentifier( 'specialactiveusers' )
162 ->setPreHtml( $this->getIntroText() )
163 ->setWrapperLegendMsg( 'activeusers' )
164 ->setSubmitTextMsg( 'activeusers-submit' )
165 // prevent setting subpage and 'username' parameter at the same time
166 ->setTitle( $this->getPageTitle() )
167 ->setMethod( 'get' )
168 ->prepareForm()
169 ->displayForm( false );
170 }
171
176 protected function getIntroText() {
177 $days = $this->getConfig()->get( MainConfigNames::ActiveUserDays );
178
179 $intro = $this->msg( 'activeusers-intro' )->numParams( $days )->parse();
180
181 // Mention the level of cache staleness...
182 $dbr = $this->dbProvider->getReplicaDatabase();
183
184 $rcMax = $dbr->newSelectQueryBuilder()
185 ->select( 'MAX(rc_timestamp)' )
186 ->from( 'recentchanges' )
187 ->caller( __METHOD__ )->fetchField();
188 if ( $rcMax ) {
189 $cTime = $dbr->newSelectQueryBuilder()
190 ->select( 'qci_timestamp' )
191 ->from( 'querycache_info' )
192 ->where( [ 'qci_type' => 'activeusers' ] )
193 ->caller( __METHOD__ )->fetchField();
194 if ( $cTime ) {
195 $secondsOld = (int)wfTimestamp( TS::UNIX, $rcMax ) - (int)wfTimestamp( TS::UNIX, $cTime );
196 } else {
197 $rcMin = $dbr->newSelectQueryBuilder()
198 ->select( 'MIN(rc_timestamp)' )
199 ->from( 'recentchanges' )
200 ->caller( __METHOD__ )->fetchField();
201 $secondsOld = time() - (int)wfTimestamp( TS::UNIX, $rcMin );
202 }
203 if ( $secondsOld > 0 ) {
204 $intro .= $this->msg( 'cachedspecial-viewing-cached-ttl' )
205 ->durationParams( $secondsOld )->parseAsBlock();
206 }
207 }
208
209 return $intro;
210 }
211
213 protected function getGroupName() {
214 return 'users';
215 }
216}
217
219class_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:195
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:43
A class containing constants representing the names of configuration variables.
const ActiveUserDays
Name constant for the ActiveUserDays setting, for use with Config::get()
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 By default the message key is the canonical name of...
Implements Special:Activeusers.
__construct(LinkBatchFactory $linkBatchFactory, IConnectionProvider $dbProvider, UserGroupManager $userGroupManager, UserIdentityLookup $userIdentityLookup, HideUserUtils $hideUserUtils, TempUserConfig $tempUserConfig, RecentChangeLookup $recentChangeLookup)
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.
Manage user group memberships.
Interface for temporary user creation config and name matching.
Service for looking up UserIdentity.
Provide primary and replica IDatabase connections.