45 private int $activeUsers;
50 parent::__construct(
'Statistics' );
51 $this->userGroupManager = $userGroupManager;
57 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
59 $this->edits = SiteStats::edits();
60 $this->good = SiteStats::articles();
61 $this->images = SiteStats::images();
62 $this->total = SiteStats::pages();
63 $this->users = SiteStats::users();
64 $this->activeUsers = SiteStats::activeUsers();
66 $text =
Xml::openElement(
'table', [
'class' =>
'wikitable mw-statistics-table' ] );
69 $text .= $this->getPageStats();
72 $text .= $this->getEditStats();
75 $text .= $this->getUserStats();
77 # Statistic - usergroups
78 $text .= $this->getGroupStats();
85 $text .= $this->getOtherStats( $extraStats );
93 $text .=
"\n" .
$footer->parse();
108 private function formatRow( $text, $number, $trExtraParams = [],
109 $descMsg =
'', $descMsgParam =
''
112 $msg = $this->
msg( $descMsg, $descMsgParam );
113 if ( !$msg->isDisabled() ) {
114 $descriptionHtml = $this->
msg(
'parentheses' )->rawParams( $msg->parse() )
116 $text .=
"<br />" . Html::rawElement(
118 [
'class' =>
'mw-statistic-desc' ],
124 return Html::rawElement(
'tr', $trExtraParams,
125 Html::rawElement(
'td', [], $text ) .
126 Html::rawElement(
'td', [
'class' =>
'mw-statistics-numbers' ], $number )
135 private function getPageStats() {
139 $pageStatsHtml = Html::rawElement(
'tr', [],
140 Xml::tags(
'th', [
'colspan' =>
'2' ],
141 $this->
msg(
'statistics-header-pages' )->parse()
145 ? $this->
msg(
'statistics-articles' )->escaped()
146 : $linkRenderer->makeKnownLink(
147 $specialAllPagesTitle,
148 $this->
msg(
'statistics-articles' )->text(),
149 [], [
'hideredirects' => 1 ] ),
151 [
'class' =>
'mw-statistics-articles' ],
152 'statistics-articles-desc' ) .
153 $this->formatRow( $linkRenderer->makeKnownLink( $specialAllPagesTitle,
154 $this->
msg(
'statistics-pages' )->text() ),
156 [
'class' =>
'mw-statistics-pages' ],
157 'statistics-pages-desc' );
161 $pageStatsHtml .= $this->formatRow(
163 $this->msg(
'statistics-files' )->text() ),
164 $this->getLanguage()->formatNum( $this->images ),
165 [
'class' =>
'mw-statistics-files' ],
'statistics-files-desc' );
168 return $pageStatsHtml;
171 private function getEditStats() {
172 return Html::rawElement(
'tr', [],
173 Xml::tags(
'th', [
'colspan' =>
'2' ],
174 $this->
msg(
'statistics-header-edits' )->parse()
176 $this->formatRow( $this->
msg(
'statistics-edits' )->parse(),
178 [
'class' =>
'mw-statistics-edits' ]
180 $this->formatRow( $this->
msg(
'statistics-edits-average' )->parse(),
182 sprintf(
'%.2f', $this->total ? $this->edits / $this->total : 0 )
183 ), [
'class' =>
'mw-statistics-edits-average' ]
187 private function getUserStats() {
188 return Html::rawElement(
'tr', [],
189 Xml::tags(
'th', [
'colspan' =>
'2' ],
190 $this->
msg(
'statistics-header-users' )->parse()
192 $this->formatRow( $this->
msg(
'statistics-users' )->parse() .
' ' .
195 $this->
msg(
'listgrouprights-members' )->text()
198 [
'class' =>
'mw-statistics-users' ]
200 $this->formatRow( $this->
msg(
'statistics-users-active' )->parse() .
' ' .
203 $this->
msg(
'listgrouprights-members' )->text()
205 $this->
getLanguage()->formatNum( $this->activeUsers ),
206 [
'class' =>
'mw-statistics-users-active' ],
207 'statistics-users-active-desc',
213 private function getGroupStats() {
217 foreach ( $this->userGroupManager->listAllGroups() as $group ) {
218 $groupnameLocalized = $lang->getGroupName( $group );
219 $linkTarget = UserGroupMembership::getGroupPage( $group )
220 ?: Title::makeTitleSafe(
NS_PROJECT, $group );
223 $grouppage = $linkRenderer->makeLink(
228 $grouppage = htmlspecialchars( $groupnameLocalized );
231 $grouplink = $linkRenderer->makeKnownLink(
233 $this->
msg(
'listgrouprights-members' )->text(),
235 [
'group' => $group ]
237 # Add a class when a usergroup contains no members to allow hiding these rows
239 $countUsers = SiteStats::numberingroup( $group );
240 if ( $countUsers == 0 ) {
241 $classZero =
' statistics-group-zero';
243 $text .= $this->formatRow( $grouppage .
' ' . $grouplink,
245 [
'class' =>
'statistics-group-' . Sanitizer::escapeClass( $group ) .
259 private function getOtherStats( array $stats ) {
262 foreach ( $stats as
$header => $items ) {
264 if ( is_array( $items ) ) {
266 if (
$header !==
'statistics-header-hooks' ) {
267 $return .= $this->formatRowHeader(
$header );
271 foreach ( $items as $key => $value ) {
272 if ( is_array( $value ) ) {
273 $name = $value[
'name'];
274 $number = $value[
'number'];
276 $name = $this->
msg( $key )->parse();
280 $return .= $this->formatRow(
282 $this->
getLanguage()->formatNum( htmlspecialchars( $number ) ),
283 [
'class' =>
'mw-statistics-hook',
'id' =>
'mw-' . $key ]
288 if ( $return ===
'' ) {
289 $return .= $this->formatRowHeader(
'statistics-header-hooks' );
293 $return .= $this->getOtherStats( [
'statistics-header-hooks' =>
307 private function formatRowHeader(
$header ) {
308 return Html::rawElement(
'tr', [],
309 Xml::tags(
'th', [
'colspan' =>
'2' ], $this->
msg(
$header )->parse() )