]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/specials/SpecialStatistics.php
MediaWiki 1.17.3-scripts
[autoinstallsdev/mediawiki.git] / includes / specials / SpecialStatistics.php
1 <?php
2 /**
3  * Implements Special:Statistics
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  * http://www.gnu.org/copyleft/gpl.html
19  *
20  * @file
21  * @ingroup SpecialPage
22  */
23
24 /**
25  * Special page lists various statistics, including the contents of
26  * `site_stats`, plus page view details if enabled
27  *
28  * @ingroup SpecialPage
29  */
30 class SpecialStatistics extends SpecialPage {
31         
32         private $views, $edits, $good, $images, $total, $users,
33                         $activeUsers, $admins = 0;
34         
35         public function __construct() {
36                 parent::__construct( 'Statistics' );
37         }
38         
39         public function execute( $par ) {
40                 global $wgOut, $wgMemc;
41                 global $wgDisableCounters, $wgMiserMode;
42                 
43                 $this->setHeaders();
44         
45                 $this->views = SiteStats::views();
46                 $this->edits = SiteStats::edits();
47                 $this->good = SiteStats::articles();
48                 $this->images = SiteStats::images();
49                 $this->total = SiteStats::pages();
50                 $this->users = SiteStats::users();
51                 $this->activeUsers = SiteStats::activeUsers();
52                 $this->admins = SiteStats::numberingroup('sysop');
53                 $this->hook = '';
54         
55                 # Staticic - views
56                 $viewsStats = '';
57                 if( !$wgDisableCounters ) {
58                         $viewsStats = $this->getViewsStats();
59                 }
60                 
61                 # Set active user count
62                 if( !$wgMiserMode ) {
63                         $key = wfMemcKey( 'sitestats', 'activeusers-updated' );
64                         // Re-calculate the count if the last tally is old...
65                         if( !$wgMemc->get($key) ) {
66                                 $dbw = wfGetDB( DB_MASTER );
67                                 SiteStatsUpdate::cacheUpdate( $dbw );
68                                 $wgMemc->set( $key, '1', 24*3600 ); // don't update for 1 day
69                         }
70                 }
71
72                 $text = Xml::openElement( 'table', array( 'class' => 'wikitable mw-statistics-table' ) );
73
74                 # Statistic - pages
75                 $text .= $this->getPageStats();
76
77                 # Statistic - edits
78                 $text .= $this->getEditStats();
79
80                 # Statistic - users
81                 $text .= $this->getUserStats();
82
83                 # Statistic - usergroups
84                 $text .= $this->getGroupStats();
85                 $text .= $viewsStats;
86
87                 # Statistic - popular pages
88                 if( !$wgDisableCounters && !$wgMiserMode ) {
89                         $text .= $this->getMostViewedPages();
90                 }
91                 
92                 # Statistic - other
93                 $extraStats = array();
94                 if( wfRunHooks( 'SpecialStatsAddExtra', array( &$extraStats ) ) ) {
95                         $text .= $this->getOtherStats( $extraStats );
96                 }
97
98                 $text .= Xml::closeElement( 'table' );
99
100                 # Customizable footer
101                 $footer = wfMsgExt( 'statistics-footer', array('parseinline') );
102                 if( !wfEmptyMsg( 'statistics-footer', $footer ) && $footer != '' ) {
103                         $text .= "\n" . $footer;
104                 }
105
106                 $wgOut->addHTML( $text );
107         }
108
109         /**
110          * Format a row
111          * @param $text  String: description of the row
112          * @param $number  Float: a statistical number
113          * @param $trExtraParams  Array: params to table row, see Html::elememt
114          * @param $descMsg  String: message key
115          * @param $descMsgParam  Array: message params
116          * @return string table row in HTML format
117          */
118         private function formatRow( $text, $number, $trExtraParams = array(), $descMsg = '', $descMsgParam = '' ) {
119                 if( $descMsg ) {
120                         $descriptionText = wfMsgExt( $descMsg, array( 'parseinline' ), $descMsgParam );
121                         if ( !wfEmptyMsg( $descMsg, $descriptionText ) ) {
122                                 $descriptionText = " ($descriptionText)";
123                                 $text .= "<br />" . Xml::element( 'small', array( 'class' => 'mw-statistic-desc'), 
124                                         $descriptionText );
125                         }
126                 }
127                 return
128                 Html::rawElement( 'tr', $trExtraParams,
129                         Html::rawElement( 'td', array(), $text ) .
130                         Html::rawElement( 'td', array( 'class' => 'mw-statistics-numbers' ), $number )
131                 );
132         }
133         
134         /**
135          * Each of these methods is pretty self-explanatory, get a particular
136          * row for the table of statistics
137          * @return string
138          */
139         private function getPageStats() {
140                 global $wgLang;
141                 return Xml::openElement( 'tr' ) .
142                         Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-pages', array( 'parseinline' ) ) ) .
143                         Xml::closeElement( 'tr' ) .
144                                 $this->formatRow( wfMsgExt( 'statistics-articles', array( 'parseinline' ) ),
145                                                 $wgLang->formatNum( $this->good ),
146                                                 array( 'class' => 'mw-statistics-articles' ) ) .
147                                 $this->formatRow( wfMsgExt( 'statistics-pages', array( 'parseinline' ) ),
148                                                 $wgLang->formatNum( $this->total ),
149                                                 array( 'class' => 'mw-statistics-pages' ),
150                                                 'statistics-pages-desc' ) .
151                                 $this->formatRow( wfMsgExt( 'statistics-files', array( 'parseinline' ) ),
152                                                 $wgLang->formatNum( $this->images ),
153                                                 array( 'class' => 'mw-statistics-files' ) );
154         }
155         private function getEditStats() {
156                 global $wgLang;
157                 return Xml::openElement( 'tr' ) .
158                         Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-edits', array( 'parseinline' ) ) ) .
159                         Xml::closeElement( 'tr' ) .
160                                 $this->formatRow( wfMsgExt( 'statistics-edits', array( 'parseinline' ) ),
161                                                 $wgLang->formatNum( $this->edits ),
162                                                 array( 'class' => 'mw-statistics-edits' ) ) .
163                                 $this->formatRow( wfMsgExt( 'statistics-edits-average', array( 'parseinline' ) ),
164                                                 $wgLang->formatNum( sprintf( '%.2f', $this->total ? $this->edits / $this->total : 0 ) ),
165                                                 array( 'class' => 'mw-statistics-edits-average' ) );
166         }
167
168         private function getUserStats() {
169                 global $wgLang, $wgUser, $wgActiveUserDays;
170                 $sk = $wgUser->getSkin();
171                 return Xml::openElement( 'tr' ) .
172                         Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-users', array( 'parseinline' ) ) ) .
173                         Xml::closeElement( 'tr' ) .
174                                 $this->formatRow( wfMsgExt( 'statistics-users', array( 'parseinline' ) ),
175                                                 $wgLang->formatNum( $this->users ),
176                                                 array( 'class' => 'mw-statistics-users' ) ) .
177                                 $this->formatRow( wfMsgExt( 'statistics-users-active', array( 'parseinline' ) ) . ' ' .
178                                                         $sk->link(
179                                                                 SpecialPage::getTitleFor( 'Activeusers' ),
180                                                                 wfMsgHtml( 'listgrouprights-members' ),
181                                                                 array(),
182                                                                 array(),
183                                                                 'known'
184                                                         ),
185                                                 $wgLang->formatNum( $this->activeUsers ),
186                                                 array( 'class' => 'mw-statistics-users-active' ),
187                                                 'statistics-users-active-desc',
188                                                 $wgLang->formatNum( $wgActiveUserDays ) );
189         }
190
191         private function getGroupStats() {
192                 global $wgGroupPermissions, $wgImplicitGroups, $wgLang, $wgUser;
193                 $sk = $wgUser->getSkin();
194                 $text = '';
195                 foreach( $wgGroupPermissions as $group => $permissions ) {
196                         # Skip generic * and implicit groups
197                         if ( in_array( $group, $wgImplicitGroups ) || $group == '*' ) {
198                                 continue;
199                         }
200                         $groupname = htmlspecialchars( $group );
201                         $msg = wfMsg( 'group-' . $groupname );
202                         if ( wfEmptyMsg( 'group-' . $groupname, $msg ) || $msg == '' ) {
203                                 $groupnameLocalized = $groupname;
204                         } else {
205                                 $groupnameLocalized = $msg;
206                         }
207                         $msg = wfMsgForContent( 'grouppage-' . $groupname );
208                         if ( wfEmptyMsg( 'grouppage-' . $groupname, $msg ) || $msg == '' ) {
209                                 $grouppageLocalized = MWNamespace::getCanonicalName( NS_PROJECT ) . ':' . $groupname;
210                         } else {
211                                 $grouppageLocalized = $msg;
212                         }
213                         $linkTarget = Title::newFromText( $grouppageLocalized );
214                         $grouppage = $sk->link(
215                                 $linkTarget,
216                                 htmlspecialchars( $groupnameLocalized )
217                         );
218                         $grouplink = $sk->link(
219                                 SpecialPage::getTitleFor( 'Listusers' ),
220                                 wfMsgHtml( 'listgrouprights-members' ),
221                                 array(),
222                                 array( 'group' => $group ),
223                                 'known'
224                         );
225                         # Add a class when a usergroup contains no members to allow hiding these rows
226                         $classZero = '';
227                         $countUsers = SiteStats::numberingroup( $groupname );
228                         if( $countUsers == 0 ) {
229                                 $classZero = ' statistics-group-zero';
230                         }
231                         $text .= $this->formatRow( $grouppage . ' ' . $grouplink,
232                                 $wgLang->formatNum( $countUsers ),
233                                 array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero )  );
234                 }
235                 return $text;
236         }
237
238         private function getViewsStats() {
239                 global $wgLang;
240                 return Xml::openElement( 'tr' ) .
241                         Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-views', array( 'parseinline' ) ) ) .
242                         Xml::closeElement( 'tr' ) .
243                                 $this->formatRow( wfMsgExt( 'statistics-views-total', array( 'parseinline' ) ),
244                                         $wgLang->formatNum( $this->views ),
245                                                 array ( 'class' => 'mw-statistics-views-total' ), 'statistics-views-total-desc' ) .
246                                 $this->formatRow( wfMsgExt( 'statistics-views-peredit', array( 'parseinline' ) ),
247                                         $wgLang->formatNum( sprintf( '%.2f', $this->edits ? 
248                                                 $this->views / $this->edits : 0 ) ),
249                                                 array ( 'class' => 'mw-statistics-views-peredit' ) );
250         }
251
252         private function getMostViewedPages() {
253                 global $wgLang, $wgUser;
254                 $text = '';
255                 $dbr = wfGetDB( DB_SLAVE );
256                 $sk = $wgUser->getSkin();
257                 $res = $dbr->select(
258                                 'page',
259                                 array(
260                                         'page_namespace',
261                                         'page_title',
262                                         'page_counter',
263                                 ),
264                                 array(
265                                         'page_is_redirect' => 0,
266                                         'page_counter > 0',
267                                 ),
268                                 __METHOD__,
269                                 array(
270                                         'ORDER BY' => 'page_counter DESC',
271                                         'LIMIT' => 10,
272                                 )
273                         );
274                         if( $res->numRows() > 0 ) {
275                                 $text .= Xml::openElement( 'tr' );
276                                 $text .= Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-mostpopular', array( 'parseinline' ) ) );
277                                 $text .= Xml::closeElement( 'tr' );
278                                 foreach ( $res as $row ) {
279                                         $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
280                                         if( $title instanceof Title ) {
281                                                 $text .= $this->formatRow( $sk->link( $title ),
282                                                                 $wgLang->formatNum( $row->page_counter ) );
283         
284                                         }
285                                 }
286                                 $res->free();
287                         }
288                 return $text;
289         }
290
291         private function getOtherStats( $stats ) {
292                 global $wgLang;
293
294                 if ( !count( $stats ) )
295                         return '';
296
297                 $return = Xml::openElement( 'tr' ) .
298                         Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-hooks', array( 'parseinline' ) ) ) .
299                         Xml::closeElement( 'tr' );
300                         
301                 foreach( $stats as $name => $number ) {
302                         $name = htmlspecialchars( $name );
303                         $number = htmlspecialchars( $number );
304                         
305                         $return .= $this->formatRow( $name, $wgLang->formatNum( $number ), array( 'class' => 'mw-statistics-hook' ) );
306                 }
307                 
308                 return $return;
309         }
310 }