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