MediaWiki REL1_35
SpecialStatistics.php
Go to the documentation of this file.
1<?php
25
35
36 public function __construct() {
37 parent::__construct( 'Statistics' );
38 }
39
40 public function execute( $par ) {
41 $this->setHeaders();
42 $this->getOutput()->addModuleStyles( 'mediawiki.special' );
43
44 $this->edits = SiteStats::edits();
45 $this->good = SiteStats::articles();
46 $this->images = SiteStats::images();
47 $this->total = SiteStats::pages();
48 $this->users = SiteStats::users();
49 $this->activeUsers = SiteStats::activeUsers();
50
51 $text = Xml::openElement( 'table', [ 'class' => 'wikitable mw-statistics-table' ] );
52
53 # Statistic - pages
54 $text .= $this->getPageStats();
55
56 # Statistic - edits
57 $text .= $this->getEditStats();
58
59 # Statistic - users
60 $text .= $this->getUserStats();
61
62 # Statistic - usergroups
63 $text .= $this->getGroupStats();
64
65 # Statistic - other
66 $extraStats = [];
67 if ( $this->getHookRunner()->onSpecialStatsAddExtra(
68 $extraStats, $this->getContext() )
69 ) {
70 $text .= $this->getOtherStats( $extraStats );
71 }
72
73 $text .= Xml::closeElement( 'table' );
74
75 # Customizable footer
76 $footer = $this->msg( 'statistics-footer' );
77 if ( !$footer->isBlank() ) {
78 $text .= "\n" . $footer->parse();
79 }
80
81 $this->getOutput()->addHTML( $text );
82 }
83
93 private function formatRow( $text, $number, $trExtraParams = [],
94 $descMsg = '', $descMsgParam = ''
95 ) {
96 if ( $descMsg ) {
97 $msg = $this->msg( $descMsg, $descMsgParam );
98 if ( !$msg->isDisabled() ) {
99 $descriptionHtml = $this->msg( 'parentheses' )->rawParams( $msg->parse() )
100 ->escaped();
101 $text .= "<br />" . Html::rawElement(
102 'small',
103 [ 'class' => 'mw-statistic-desc' ],
104 " $descriptionHtml"
105 );
106 }
107 }
108
109 return Html::rawElement( 'tr', $trExtraParams,
110 Html::rawElement( 'td', [], $text ) .
111 Html::rawElement( 'td', [ 'class' => 'mw-statistics-numbers' ], $number )
112 );
113 }
114
120 private function getPageStats() {
122
123 $specialAllPagesTitle = SpecialPage::getTitleFor( 'Allpages' );
124 $pageStatsHtml = Xml::openElement( 'tr' ) .
125 Xml::tags( 'th', [ 'colspan' => '2' ], $this->msg( 'statistics-header-pages' )
126 ->parse() ) .
127 Xml::closeElement( 'tr' ) .
128 $this->formatRow( $linkRenderer->makeKnownLink(
129 $specialAllPagesTitle,
130 $this->msg( 'statistics-articles' )->text(),
131 [], [ 'hideredirects' => 1 ] ),
132 $this->getLanguage()->formatNum( $this->good ),
133 [ 'class' => 'mw-statistics-articles' ],
134 'statistics-articles-desc' ) .
135 $this->formatRow( $linkRenderer->makeKnownLink( $specialAllPagesTitle,
136 $this->msg( 'statistics-pages' )->text() ),
137 $this->getLanguage()->formatNum( $this->total ),
138 [ 'class' => 'mw-statistics-pages' ],
139 'statistics-pages-desc' );
140
141 // Show the image row only, when there are files or upload is possible
142 if ( $this->images !== 0 || $this->getConfig()->get( 'EnableUploads' ) ) {
143 $pageStatsHtml .= $this->formatRow(
144 $linkRenderer->makeKnownLink( SpecialPage::getTitleFor( 'MediaStatistics' ),
145 $this->msg( 'statistics-files' )->text() ),
146 $this->getLanguage()->formatNum( $this->images ),
147 [ 'class' => 'mw-statistics-files' ] );
148 }
149
150 return $pageStatsHtml;
151 }
152
153 private function getEditStats() {
154 return Xml::openElement( 'tr' ) .
155 Xml::tags( 'th', [ 'colspan' => '2' ],
156 $this->msg( 'statistics-header-edits' )->parse() ) .
157 Xml::closeElement( 'tr' ) .
158 $this->formatRow( $this->msg( 'statistics-edits' )->parse(),
159 $this->getLanguage()->formatNum( $this->edits ),
160 [ 'class' => 'mw-statistics-edits' ]
161 ) .
162 $this->formatRow( $this->msg( 'statistics-edits-average' )->parse(),
163 $this->getLanguage()->formatNum(
164 sprintf( '%.2f', $this->total ? $this->edits / $this->total : 0 )
165 ), [ 'class' => 'mw-statistics-edits-average' ]
166 );
167 }
168
169 private function getUserStats() {
170 return Xml::openElement( 'tr' ) .
171 Xml::tags( 'th', [ 'colspan' => '2' ],
172 $this->msg( 'statistics-header-users' )->parse() ) .
173 Xml::closeElement( 'tr' ) .
174 $this->formatRow( $this->msg( 'statistics-users' )->parse() . ' ' .
175 $this->getLinkRenderer()->makeKnownLink(
176 SpecialPage::getTitleFor( 'Listusers' ),
177 $this->msg( 'listgrouprights-members' )->text()
178 ),
179 $this->getLanguage()->formatNum( $this->users ),
180 [ 'class' => 'mw-statistics-users' ]
181 ) .
182 $this->formatRow( $this->msg( 'statistics-users-active' )->parse() . ' ' .
183 $this->getLinkRenderer()->makeKnownLink(
184 SpecialPage::getTitleFor( 'Activeusers' ),
185 $this->msg( 'listgrouprights-members' )->text()
186 ),
187 $this->getLanguage()->formatNum( $this->activeUsers ),
188 [ 'class' => 'mw-statistics-users-active' ],
189 'statistics-users-active-desc',
190 $this->getLanguage()->formatNum(
191 $this->getConfig()->get( 'ActiveUserDays' ) )
192 );
193 }
194
195 private function getGroupStats() {
197 $text = '';
198 foreach ( $this->getConfig()->get( 'GroupPermissions' ) as $group => $permissions ) {
199 # Skip generic * and implicit groups
200 if ( in_array( $group, $this->getConfig()->get( 'ImplicitGroups' ) )
201 || $group == '*' ) {
202 continue;
203 }
204 $groupname = htmlspecialchars( $group );
205 $msg = $this->msg( 'group-' . $groupname );
206 if ( $msg->isBlank() ) {
207 $groupnameLocalized = $groupname;
208 } else {
209 $groupnameLocalized = $msg->text();
210 }
211 $msg = $this->msg( 'grouppage-' . $groupname )->inContentLanguage();
212 if ( $msg->isBlank() ) {
213 $grouppageLocalized = MediaWikiServices::getInstance()->getNamespaceInfo()->
214 getCanonicalName( NS_PROJECT ) . ':' . $groupname;
215 } else {
216 $grouppageLocalized = $msg->text();
217 }
218 $linkTarget = Title::newFromText( $grouppageLocalized );
219
220 if ( $linkTarget ) {
221 $grouppage = $linkRenderer->makeLink(
222 $linkTarget,
223 $groupnameLocalized
224 );
225 } else {
226 $grouppage = htmlspecialchars( $groupnameLocalized );
227 }
228
229 $grouplink = $linkRenderer->makeKnownLink(
230 SpecialPage::getTitleFor( 'Listusers' ),
231 $this->msg( 'listgrouprights-members' )->text(),
232 [],
233 [ 'group' => $group ]
234 );
235 # Add a class when a usergroup contains no members to allow hiding these rows
236 $classZero = '';
237 $countUsers = SiteStats::numberingroup( $groupname );
238 if ( $countUsers == 0 ) {
239 $classZero = ' statistics-group-zero';
240 }
241 $text .= $this->formatRow( $grouppage . ' ' . $grouplink,
242 $this->getLanguage()->formatNum( $countUsers ),
243 [ 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) .
244 $classZero ] );
245 }
246
247 return $text;
248 }
249
257 private function getOtherStats( array $stats ) {
258 $return = '';
259
260 foreach ( $stats as $header => $items ) {
261 // Identify the structure used
262 if ( is_array( $items ) ) {
263 // Ignore headers that are recursively set as legacy header
264 if ( $header !== 'statistics-header-hooks' ) {
265 $return .= $this->formatRowHeader( $header );
266 }
267
268 // Collect all items that belong to the same header
269 foreach ( $items as $key => $value ) {
270 if ( is_array( $value ) ) {
271 $name = $value['name'];
272 $number = $value['number'];
273 } else {
274 $name = $this->msg( $key )->parse();
275 $number = $value;
276 }
277
278 $return .= $this->formatRow(
279 $name,
280 $this->getLanguage()->formatNum( htmlspecialchars( $number ) ),
281 [ 'class' => 'mw-statistics-hook', 'id' => 'mw-' . $key ]
282 );
283 }
284 } else {
285 // Create the legacy header only once
286 if ( $return === '' ) {
287 $return .= $this->formatRowHeader( 'statistics-header-hooks' );
288 }
289
290 // Recursively remap the legacy structure
291 $return .= $this->getOtherStats( [ 'statistics-header-hooks' =>
292 [ $header => $items ] ] );
293 }
294 }
295
296 return $return;
297 }
298
305 private function formatRowHeader( $header ) {
306 return Xml::openElement( 'tr' ) .
307 Xml::tags( 'th', [ 'colspan' => '2' ], $this->msg( $header )->parse() ) .
308 Xml::closeElement( 'tr' );
309 }
310
311 protected function getGroupName() {
312 return 'wiki';
313 }
314}
MediaWikiServices is the service locator for the application scope of MediaWiki.
static articles()
static images()
static edits()
Definition SiteStats.php:94
static users()
static pages()
static numberingroup( $group)
Find the number of users in a given user group.
static activeUsers()
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!...
getOutput()
Get the OutputPage being used for this instance.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getLanguage()
Shortcut to get user's language.
MediaWiki Linker LinkRenderer null $linkRenderer
Special page lists various statistics, including the contents of site_stats, plus page view details i...
getOtherStats(array $stats)
Conversion of external statistics into an internal representation Following a ([<header-message>][<it...
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getPageStats()
Each of these methods is pretty self-explanatory, get a particular row for the table of statistics.
formatRowHeader( $header)
Format row header.
formatRow( $text, $number, $trExtraParams=[], $descMsg='', $descMsgParam='')
Format a row.
execute( $par)
Default execute method Checks user permissions.
const NS_PROJECT
Definition Defines.php:74
$header
$footer