From a6d2365015aaa4b26729492cdc25f1a69920b2f6 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Tue, 23 Apr 2013 09:29:36 -0400 Subject: [PATCH] Revert "Remove Special:ActiveUsers" This reverts commit 27104686abe2aaf464d8d654a71e946326a0926d. Revert "Remove link to Special:ActiveUsers from Special:Statistics" This reverts commit 62949af09ea3ceb96d897ec8aab74afdadb02d4e. I used a sledgehammer where a scalpel would've done--and I should be whacked with the cluebat. This should be done per-wiki, plus improvements. Change-Id: Ib43b42057b8d9f714a8a71ba9cbe375385254b7c --- RELEASE-NOTES-1.22 | 1 - includes/AutoLoader.php | 2 + includes/SpecialPageFactory.php | 1 + includes/specials/SpecialActiveusers.php | 250 +++++++++++++++++++++++ includes/specials/SpecialStatistics.php | 6 +- languages/messages/MessagesEn.php | 11 + maintenance/language/messageTypes.inc | 1 + maintenance/language/messages.inc | 12 ++ 8 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 includes/specials/SpecialActiveusers.php diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22 index ff9622a376..761bacc7d9 100644 --- a/RELEASE-NOTES-1.22 +++ b/RELEASE-NOTES-1.22 @@ -127,7 +127,6 @@ changes to languages because of Bugzilla reports. feature, and improper configuration can actually prevent a user from editing * Calling Linker methods using a skin will now output deprecation warnings. * (bug 46680) "Return to" links are no longer tagged with rel="next". -* The Special:ActiveUsers special page was removed. * BREAKING CHANGE: mw.util.tooltipAccessKeyRegexp: The match group for the accesskey character is now $6 instead of $5. * A new Special:Redirect page was added, providing lookup by revision ID, diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 01de4f8d8d..8c7b542def 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -888,6 +888,7 @@ $wgAutoloadLocalClasses = array( 'SiteStore' => 'includes/site/SiteStore.php', # includes/specials + 'ActiveUsersPager' => 'includes/specials/SpecialActiveusers.php', 'AllmessagesTablePager' => 'includes/specials/SpecialAllmessages.php', 'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php', 'BlockListPager' => 'includes/specials/SpecialBlockList.php', @@ -932,6 +933,7 @@ $wgAutoloadLocalClasses = array( 'ProtectedTitlesPager' => 'includes/specials/SpecialProtectedtitles.php', 'RandomPage' => 'includes/specials/SpecialRandompage.php', 'ShortPagesPage' => 'includes/specials/SpecialShortpages.php', + 'SpecialActiveUsers' => 'includes/specials/SpecialActiveusers.php', 'SpecialAllmessages' => 'includes/specials/SpecialAllmessages.php', 'SpecialAllpages' => 'includes/specials/SpecialAllpages.php', 'SpecialBlankpage' => 'includes/specials/SpecialBlankpage.php', diff --git a/includes/SpecialPageFactory.php b/includes/SpecialPageFactory.php index 4c9abe145a..3c4e61d00b 100644 --- a/includes/SpecialPageFactory.php +++ b/includes/SpecialPageFactory.php @@ -99,6 +99,7 @@ class SpecialPageFactory { 'Listusers' => 'SpecialListUsers', 'Listadmins' => 'SpecialListAdmins', 'Listbots' => 'SpecialListBots', + 'Activeusers' => 'SpecialActiveUsers', 'Userrights' => 'UserrightsPage', 'EditWatchlist' => 'SpecialEditWatchlist', diff --git a/includes/specials/SpecialActiveusers.php b/includes/specials/SpecialActiveusers.php new file mode 100644 index 0000000000..c9c82ada74 --- /dev/null +++ b/includes/specials/SpecialActiveusers.php @@ -0,0 +1,250 @@ +RCMaxAge = $wgActiveUserDays; + $un = $this->getRequest()->getText( 'username', $par ); + $this->requestedUser = ''; + if ( $un != '' ) { + $username = Title::makeTitleSafe( NS_USER, $un ); + if( !is_null( $username ) ) { + $this->requestedUser = $username->getText(); + } + } + + $this->setupOptions(); + } + + public function setupOptions() { + $this->opts = new FormOptions(); + + $this->opts->add( 'hidebots', false, FormOptions::BOOL ); + $this->opts->add( 'hidesysops', false, FormOptions::BOOL ); + + $this->opts->fetchValuesFromRequest( $this->getRequest() ); + + if ( $this->opts->getValue( 'hidebots' ) == 1 ) { + $this->hideRights[] = 'bot'; + } + if ( $this->opts->getValue( 'hidesysops' ) == 1 ) { + $this->hideGroups[] = 'sysop'; + } + } + + function getIndexField() { + return 'rc_user_text'; + } + + function getQueryInfo() { + $dbr = wfGetDB( DB_SLAVE ); + $conds = array( 'rc_user > 0' ); // Users - no anons + if( !$this->getUser()->isAllowed( 'hideuser' ) ) { + $conds[] = 'ipb_deleted IS NULL OR ipb_deleted = 0'; // don't show hidden names + } + $conds[] = 'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' ); + $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes( + $dbr->timestamp( wfTimestamp( TS_UNIX ) - $this->RCMaxAge*24*3600 ) ); + + if( $this->requestedUser != '' ) { + $conds[] = 'rc_user_text >= ' . $dbr->addQuotes( $this->requestedUser ); + } + + return array( + 'tables' => array( 'recentchanges', 'ipblocks' ), + 'fields' => array( + 'user_name' => 'rc_user_text', // for Pager inheritance + 'rc_user_text', // for Pager + 'user_id' => 'rc_user', + 'recentedits' => 'COUNT(*)', + 'ipb_deleted' => 'MAX(ipb_deleted)' + ), + 'options' => array( + 'GROUP BY' => array( 'rc_user_text', 'user_id' ), + 'USE INDEX' => array( 'recentchanges' => 'rc_user_text' ) + ), + 'join_conds' => array( // check for suppression blocks + 'ipblocks' => array( 'LEFT JOIN', array( + 'rc_user=ipb_user', + 'ipb_auto' => 0 # avoid duplicate blocks + )), + ), + 'conds' => $conds + ); + } + + function formatRow( $row ) { + $userName = $row->user_name; + + $ulinks = Linker::userLink( $row->user_id, $userName ); + $ulinks .= Linker::userToolLinks( $row->user_id, $userName ); + + $lang = $this->getLanguage(); + + $list = array(); + $user = User::newFromId( $row->user_id ); + + // User right filter + foreach( $this->hideRights as $right ) { + // Calling User::getRights() within the loop so that + // if the hideRights() filter is empty, we don't have to + // trigger the lazy-init of the big userrights array in the + // User object + if ( in_array( $right, $user->getRights() ) ) { + return ''; + } + } + + // User group filter + // Note: This is a different loop than for user rights, + // because we're reusing it to build the group links + // at the same time + foreach( $user->getGroups() as $group ) { + if ( in_array( $group, $this->hideGroups ) ) { + return ''; + } + $list[] = self::buildGroupLink( $group, $userName ); + } + + $groups = $lang->commaList( $list ); + + $item = $lang->specialList( $ulinks, $groups ); + if( $row->ipb_deleted ) { + $item = "$item"; + } + $count = $this->msg( 'activeusers-count' )->numParams( $row->recentedits ) + ->params( $userName )->numParams( $this->RCMaxAge )->escaped(); + $blocked = !is_null( $row->ipb_deleted ) ? ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() : ''; + + return Html::rawElement( 'li', array(), "{$item} [{$count}]{$blocked}" ); + } + + function getPageHeader() { + global $wgScript; + + $self = $this->getTitle(); + $limit = $this->mLimit ? Html::hidden( 'limit', $this->mLimit ) : ''; + + $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ); # Form tag + $out .= Xml::fieldset( $this->msg( 'activeusers' )->text() ) . "\n"; + $out .= Html::hidden( 'title', $self->getPrefixedDBkey() ) . $limit . "\n"; + + $out .= Xml::inputLabel( $this->msg( 'activeusers-from' )->text(), + 'username', 'offset', 20, $this->requestedUser ) . '
';# Username field + + $out .= Xml::checkLabel( $this->msg( 'activeusers-hidebots' )->text(), + 'hidebots', 'hidebots', $this->opts->getValue( 'hidebots' ) ); + + $out .= Xml::checkLabel( $this->msg( 'activeusers-hidesysops' )->text(), + 'hidesysops', 'hidesysops', $this->opts->getValue( 'hidesysops' ) ) . '
'; + + $out .= Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n";# Submit button and form bottom + $out .= Xml::closeElement( 'fieldset' ); + $out .= Xml::closeElement( 'form' ); + + return $out; + } +} + +/** + * @ingroup SpecialPage + */ +class SpecialActiveUsers extends SpecialPage { + + /** + * Constructor + */ + public function __construct() { + parent::__construct( 'Activeusers' ); + } + + /** + * Show the special page + * + * @param $par Mixed: parameter passed to the page or null + */ + public function execute( $par ) { + global $wgActiveUserDays; + + $this->setHeaders(); + $this->outputHeader(); + + $out = $this->getOutput(); + $out->wrapWikiMsg( "
\n$1\n
", + array( 'activeusers-intro', $this->getLanguage()->formatNum( $wgActiveUserDays ) ) ); + + $up = new ActiveUsersPager( $this->getContext(), null, $par ); + + # getBody() first to check, if empty + $usersbody = $up->getBody(); + + $out->addHTML( $up->getPageHeader() ); + if ( $usersbody ) { + $out->addHTML( + $up->getNavigationBar() . + Html::rawElement( 'ul', array(), $usersbody ) . + $up->getNavigationBar() + ); + } else { + $out->addWikiMsg( 'activeusers-noresult' ); + } + } + + protected function getGroupName() { + return 'users'; + } +} diff --git a/includes/specials/SpecialStatistics.php b/includes/specials/SpecialStatistics.php index 2ec955e31c..dbf2f0d99f 100644 --- a/includes/specials/SpecialStatistics.php +++ b/includes/specials/SpecialStatistics.php @@ -171,7 +171,11 @@ class SpecialStatistics extends SpecialPage { $this->formatRow( $this->msg( 'statistics-users' )->parse(), $this->getLanguage()->formatNum( $this->users ), array( 'class' => 'mw-statistics-users' ) ) . - $this->formatRow( $this->msg( 'statistics-users-active' )->parse(), + $this->formatRow( $this->msg( 'statistics-users-active' )->parse() . ' ' . + Linker::linkKnown( + SpecialPage::getTitleFor( 'Activeusers' ), + $this->msg( 'listgrouprights-members' )->escaped() + ), $this->getLanguage()->formatNum( $this->activeUsers ), array( 'class' => 'mw-statistics-users-active' ), 'statistics-users-active-desc', diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index e30fafdc4b..e6f7338d10 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -378,6 +378,7 @@ $magicWords = array( * hook. */ $specialPageAliases = array( + 'Activeusers' => array( 'ActiveUsers' ), 'Allmessages' => array( 'AllMessages' ), 'Allpages' => array( 'AllPages' ), 'Ancientpages' => array( 'AncientPages' ), @@ -2819,6 +2820,16 @@ Supported {{PLURAL:$2|protocol|protocols}}: $1 (defaults to http:// 'listusers-noresult' => 'No user found.', 'listusers-blocked' => '(blocked)', +# Special:ActiveUsers +'activeusers' => 'Active users list', +'activeusers-summary' => '', # do not translate or duplicate this message to other languages +'activeusers-intro' => 'This is a list of users who had some kind of activity within the last $1 {{PLURAL:$1|day|days}}.', +'activeusers-count' => '$1 {{PLURAL:$1|action|actions}} in the last {{PLURAL:$3|day|$3 days}}', +'activeusers-from' => 'Display users starting at:', +'activeusers-hidebots' => 'Hide bots', +'activeusers-hidesysops' => 'Hide administrators', +'activeusers-noresult' => 'No users found.', + # Special:ListGroupRights 'listgrouprights' => 'User group rights', 'listgrouprights-summary' => 'The following is a list of user groups defined on this wiki, with their associated access rights. diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc index 8c6258511c..9e629b4689 100644 --- a/maintenance/language/messageTypes.inc +++ b/maintenance/language/messageTypes.inc @@ -188,6 +188,7 @@ $wgIgnoredMessages = array( 'fewestrevisions-summary', 'upload-summary', 'wantedtemplates-summary', + 'activeusers-summary', 'search-summary', 'editpage-head-copy-warn', 'editpage-tos-summary', diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 34aed9fb9f..a8b682b875 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -1877,6 +1877,17 @@ $wgMessageStructure = array( 'listusers-noresult', 'listusers-blocked', ), + 'activeusers' => array( + 'activeusers', + 'activeusers-summary', + 'activeusers-intro', + 'activeusers-count', + 'activeusers-from', + 'activeusers-hidebots', + 'activeusers-hidesysops', + 'activeusers-submit', + 'activeusers-noresult', + ), 'listgrouprights' => array( 'listgrouprights', 'listgrouprights-summary', @@ -3984,6 +3995,7 @@ XHTML id names.", 'deletedcontribs' => 'Special:DeletedContributions', 'linksearch' => 'Special:LinkSearch', 'listusers' => 'Special:ListUsers', + 'activeusers' => 'Special:ActiveUsers', 'newuserlog' => 'Special:Log/newusers', 'listgrouprights' => 'Special:ListGroupRights', 'emailuser' => 'Email user', -- 2.20.1