includes/specials/SpecialActiveUsers.php
<?php
/**
* Implements Special:Activeusers
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup SpecialPage
*/
namespace MediaWiki\Specials;
use MediaWiki\Block\HideUserUtils;
use MediaWiki\Cache\LinkBatchFactory;
use MediaWiki\Html\FormOptions;
use MediaWiki\Html\Html;
use MediaWiki\HTMLForm\HTMLForm;
use MediaWiki\MainConfigNames;
use MediaWiki\Pager\ActiveUsersPager;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\User\UserGroupManager;
use MediaWiki\User\UserIdentityLookup;
use Wikimedia\Rdbms\IConnectionProvider;
/**
* Implements Special:Activeusers
*
* @ingroup SpecialPage
*/
class SpecialActiveUsers extends SpecialPage {
private LinkBatchFactory $linkBatchFactory;
private IConnectionProvider $dbProvider;
private UserGroupManager $userGroupManager;
private UserIdentityLookup $userIdentityLookup;
private HideUserUtils $hideUserUtils;
/**
* @param LinkBatchFactory $linkBatchFactory
* @param IConnectionProvider $dbProvider
* @param UserGroupManager $userGroupManager
* @param UserIdentityLookup $userIdentityLookup
* @param HideUserUtils $hideUserUtils
*/
public function __construct(
LinkBatchFactory $linkBatchFactory,
IConnectionProvider $dbProvider,
UserGroupManager $userGroupManager,
UserIdentityLookup $userIdentityLookup,
HideUserUtils $hideUserUtils
) {
parent::__construct( 'Activeusers' );
$this->linkBatchFactory = $linkBatchFactory;
$this->dbProvider = $dbProvider;
$this->userGroupManager = $userGroupManager;
$this->userIdentityLookup = $userIdentityLookup;
$this->hideUserUtils = $hideUserUtils;
}
/**
* @param string|null $par Parameter passed to the page or null
*/
public function execute( $par ) {
$out = $this->getOutput();
$this->setHeaders();
$this->outputHeader();
$opts = new FormOptions();
$opts->add( 'username', '' );
$opts->add( 'groups', [] );
$opts->add( 'excludegroups', [] );
// Backwards-compatibility with old URLs
$opts->add( 'hidebots', false, FormOptions::BOOL );
$opts->add( 'hidesysops', false, FormOptions::BOOL );
$opts->fetchValuesFromRequest( $this->getRequest() );
if ( $par !== null ) {
$opts->setValue( 'username', $par );
}
$pager = new ActiveUsersPager(
$this->getContext(),
$this->getHookContainer(),
$this->linkBatchFactory,
$this->dbProvider,
$this->userGroupManager,
$this->userIdentityLookup,
$this->hideUserUtils,
$opts
);
$usersBody = $pager->getBody();
$this->buildForm();
if ( $usersBody ) {
$out->addHTML(
$pager->getNavigationBar() .
Html::rawElement( 'ul', [], $usersBody ) .
$pager->getNavigationBar()
);
$out->addModuleStyles( 'mediawiki.interface.helpers.styles' );
} else {
$out->addWikiMsg( 'activeusers-noresult' );
}
}
/**
* Generate and output the form
*/
protected function buildForm() {
$groups = $this->userGroupManager->listAllGroups();
$options = [];
$lang = $this->getLanguage();
foreach ( $groups as $group ) {
$msg = htmlspecialchars( $lang->getGroupName( $group ) );
$options[$msg] = $group;
}
ksort( $options );
// Backwards-compatibility with old URLs
$req = $this->getRequest();
$excludeDefault = [];
if ( $req->getCheck( 'hidebots' ) ) {
$excludeDefault[] = 'bot';
}
if ( $req->getCheck( 'hidesysops' ) ) {
$excludeDefault[] = 'sysop';
}
$formDescriptor = [
'username' => [
'type' => 'user',
'name' => 'username',
'label-message' => 'activeusers-from',
],
'groups' => [
'type' => 'multiselect',
'dropdown' => true,
'flatlist' => true,
'name' => 'groups',
'label-message' => 'activeusers-groups',
'options' => $options,
],
'excludegroups' => [
'type' => 'multiselect',
'dropdown' => true,
'flatlist' => true,
'name' => 'excludegroups',
'label-message' => 'activeusers-excludegroups',
'options' => $options,
'default' => $excludeDefault,
],
];
HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
// For the 'multiselect' field values to be preserved on submit
->setFormIdentifier( 'specialactiveusers' )
->setPreHtml( $this->getIntroText() )
->setWrapperLegendMsg( 'activeusers' )
->setSubmitTextMsg( 'activeusers-submit' )
// prevent setting subpage and 'username' parameter at the same time
->setTitle( $this->getPageTitle() )
->setMethod( 'get' )
->prepareForm()
->displayForm( false );
}
/**
* Return introductory message.
* @return string
*/
protected function getIntroText() {
$days = $this->getConfig()->get( MainConfigNames::ActiveUserDays );
$intro = $this->msg( 'activeusers-intro' )->numParams( $days )->parse();
// Mention the level of cache staleness...
$dbr = $this->dbProvider->getReplicaDatabase();
$rcMax = $dbr->newSelectQueryBuilder()
->select( 'MAX(rc_timestamp)' )
->from( 'recentchanges' )
->caller( __METHOD__ )->fetchField();
if ( $rcMax ) {
$cTime = $dbr->newSelectQueryBuilder()
->select( 'qci_timestamp' )
->from( 'querycache_info' )
->where( [ 'qci_type' => 'activeusers' ] )
->caller( __METHOD__ )->fetchField();
if ( $cTime ) {
$secondsOld = (int)wfTimestamp( TS_UNIX, $rcMax ) - (int)wfTimestamp( TS_UNIX, $cTime );
} else {
$rcMin = $dbr->newSelectQueryBuilder()
->select( 'MIN(rc_timestamp)' )
->from( 'recentchanges' )
->caller( __METHOD__ )->fetchField();
$secondsOld = time() - (int)wfTimestamp( TS_UNIX, $rcMin );
}
if ( $secondsOld > 0 ) {
$intro .= $this->msg( 'cachedspecial-viewing-cached-ttl' )
->durationParams( $secondsOld )->parseAsBlock();
}
}
return $intro;
}
protected function getGroupName() {
return 'users';
}
}
/** @deprecated class alias since 1.41 */
class_alias( SpecialActiveUsers::class, 'SpecialActiveUsers' );