MediaWiki  REL1_20
SpecialStatistics.php
Go to the documentation of this file.
00001 <?php
00030 class SpecialStatistics extends SpecialPage {
00031 
00032         private $views, $edits, $good, $images, $total, $users,
00033                         $activeUsers = 0;
00034 
00035         public function __construct() {
00036                 parent::__construct( 'Statistics' );
00037         }
00038 
00039         public function execute( $par ) {
00040                 global $wgMemc, $wgDisableCounters, $wgMiserMode;
00041 
00042                 $this->setHeaders();
00043                 $this->getOutput()->addModuleStyles( 'mediawiki.special' );
00044 
00045                 $this->views = SiteStats::views();
00046                 $this->edits = SiteStats::edits();
00047                 $this->good = SiteStats::articles();
00048                 $this->images = SiteStats::images();
00049                 $this->total = SiteStats::pages();
00050                 $this->users = SiteStats::users();
00051                 $this->activeUsers = SiteStats::activeUsers();
00052                 $this->hook = '';
00053 
00054                 # Staticic - views
00055                 $viewsStats = '';
00056                 if( !$wgDisableCounters ) {
00057                         $viewsStats = $this->getViewsStats();
00058                 }
00059 
00060                 # Set active user count
00061                 if( !$wgMiserMode ) {
00062                         $key = wfMemcKey( 'sitestats', 'activeusers-updated' );
00063                         // Re-calculate the count if the last tally is old...
00064                         if( !$wgMemc->get($key) ) {
00065                                 $dbw = wfGetDB( DB_MASTER );
00066                                 SiteStatsUpdate::cacheUpdate( $dbw );
00067                                 $wgMemc->set( $key, '1', 24*3600 ); // don't update for 1 day
00068                         }
00069                 }
00070 
00071                 $text = Xml::openElement( 'table', array( 'class' => 'wikitable mw-statistics-table' ) );
00072 
00073                 # Statistic - pages
00074                 $text .= $this->getPageStats();
00075 
00076                 # Statistic - edits
00077                 $text .= $this->getEditStats();
00078 
00079                 # Statistic - users
00080                 $text .= $this->getUserStats();
00081 
00082                 # Statistic - usergroups
00083                 $text .= $this->getGroupStats();
00084                 $text .= $viewsStats;
00085 
00086                 # Statistic - popular pages
00087                 if( !$wgDisableCounters && !$wgMiserMode ) {
00088                         $text .= $this->getMostViewedPages();
00089                 }
00090 
00091                 # Statistic - other
00092                 $extraStats = array();
00093                 if( wfRunHooks( 'SpecialStatsAddExtra', array( &$extraStats ) ) ) {
00094                         $text .= $this->getOtherStats( $extraStats );
00095                 }
00096 
00097                 $text .= Xml::closeElement( 'table' );
00098 
00099                 # Customizable footer
00100                 $footer = $this->msg( 'statistics-footer' );
00101                 if ( !$footer->isBlank() ) {
00102                         $text .= "\n" . $footer->parse();
00103                 }
00104 
00105                 $this->getOutput()->addHTML( $text );
00106         }
00107 
00117         private function formatRow( $text, $number, $trExtraParams = array(), $descMsg = '', $descMsgParam = '' ) {
00118                 if( $descMsg ) {
00119                         $msg = $this->msg( $descMsg, $descMsgParam );
00120                         if ( $msg->exists() ) {
00121                                 $descriptionText = $this->msg( 'parentheses' )->rawParams( $msg->parse() )->escaped();
00122                                 $text .= "<br />" . Xml::element( 'small', array( 'class' => 'mw-statistic-desc'),
00123                                         " $descriptionText" );
00124                         }
00125                 }
00126                 return Html::rawElement( 'tr', $trExtraParams,
00127                         Html::rawElement( 'td', array(), $text ) .
00128                         Html::rawElement( 'td', array( 'class' => 'mw-statistics-numbers' ), $number )
00129                 );
00130         }
00131 
00137         private function getPageStats() {
00138                 return Xml::openElement( 'tr' ) .
00139                         Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-pages' )->parse() ) .
00140                         Xml::closeElement( 'tr' ) .
00141                                 $this->formatRow( Linker::linkKnown( SpecialPage::getTitleFor( 'Allpages' ),
00142                                                 $this->msg( 'statistics-articles' )->parse() ),
00143                                                 $this->getLanguage()->formatNum( $this->good ),
00144                                                 array( 'class' => 'mw-statistics-articles' ) ) .
00145                                 $this->formatRow( $this->msg( 'statistics-pages' )->parse(),
00146                                                 $this->getLanguage()->formatNum( $this->total ),
00147                                                 array( 'class' => 'mw-statistics-pages' ),
00148                                                 'statistics-pages-desc' ) .
00149                                 $this->formatRow( Linker::linkKnown( SpecialPage::getTitleFor( 'Listfiles' ),
00150                                                 $this->msg( 'statistics-files' )->parse() ),
00151                                                 $this->getLanguage()->formatNum( $this->images ),
00152                                                 array( 'class' => 'mw-statistics-files' ) );
00153         }
00154         private function getEditStats() {
00155                 return Xml::openElement( 'tr' ) .
00156                         Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-edits' )->parse() ) .
00157                         Xml::closeElement( 'tr' ) .
00158                                 $this->formatRow( $this->msg( 'statistics-edits' )->parse(),
00159                                                 $this->getLanguage()->formatNum( $this->edits ),
00160                                                 array( 'class' => 'mw-statistics-edits' ) ) .
00161                                 $this->formatRow( $this->msg( 'statistics-edits-average' )->parse(),
00162                                                 $this->getLanguage()->formatNum( sprintf( '%.2f', $this->total ? $this->edits / $this->total : 0 ) ),
00163                                                 array( 'class' => 'mw-statistics-edits-average' ) );
00164         }
00165 
00166         private function getUserStats() {
00167                 global $wgActiveUserDays;
00168                 return Xml::openElement( 'tr' ) .
00169                         Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-users' )->parse() ) .
00170                         Xml::closeElement( 'tr' ) .
00171                                 $this->formatRow( $this->msg( 'statistics-users' )->parse(),
00172                                                 $this->getLanguage()->formatNum( $this->users ),
00173                                                 array( 'class' => 'mw-statistics-users' ) ) .
00174                                 $this->formatRow( $this->msg( 'statistics-users-active' )->parse() . ' ' .
00175                                                         Linker::linkKnown(
00176                                                                 SpecialPage::getTitleFor( 'Activeusers' ),
00177                                                                 $this->msg( 'listgrouprights-members' )->escaped()
00178                                                         ),
00179                                                 $this->getLanguage()->formatNum( $this->activeUsers ),
00180                                                 array( 'class' => 'mw-statistics-users-active' ),
00181                                                 'statistics-users-active-desc',
00182                                                 $this->getLanguage()->formatNum( $wgActiveUserDays ) );
00183         }
00184 
00185         private function getGroupStats() {
00186                 global $wgGroupPermissions, $wgImplicitGroups;
00187                 $text = '';
00188                 foreach( $wgGroupPermissions as $group => $permissions ) {
00189                         # Skip generic * and implicit groups
00190                         if ( in_array( $group, $wgImplicitGroups ) || $group == '*' ) {
00191                                 continue;
00192                         }
00193                         $groupname = htmlspecialchars( $group );
00194                         $msg = $this->msg( 'group-' . $groupname );
00195                         if ( $msg->isBlank() ) {
00196                                 $groupnameLocalized = $groupname;
00197                         } else {
00198                                 $groupnameLocalized = $msg->text();
00199                         }
00200                         $msg = $this->msg( 'grouppage-' . $groupname )->inContentLanguage();
00201                         if ( $msg->isBlank() ) {
00202                                 $grouppageLocalized = MWNamespace::getCanonicalName( NS_PROJECT ) . ':' . $groupname;
00203                         } else {
00204                                 $grouppageLocalized = $msg->text();
00205                         }
00206                         $linkTarget = Title::newFromText( $grouppageLocalized );
00207                         $grouppage = Linker::link(
00208                                 $linkTarget,
00209                                 htmlspecialchars( $groupnameLocalized )
00210                         );
00211                         $grouplink = Linker::linkKnown(
00212                                 SpecialPage::getTitleFor( 'Listusers' ),
00213                                 $this->msg( 'listgrouprights-members' )->escaped(),
00214                                 array(),
00215                                 array( 'group' => $group )
00216                         );
00217                         # Add a class when a usergroup contains no members to allow hiding these rows
00218                         $classZero = '';
00219                         $countUsers = SiteStats::numberingroup( $groupname );
00220                         if( $countUsers == 0 ) {
00221                                 $classZero = ' statistics-group-zero';
00222                         }
00223                         $text .= $this->formatRow( $grouppage . ' ' . $grouplink,
00224                                 $this->getLanguage()->formatNum( $countUsers ),
00225                                 array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero )  );
00226                 }
00227                 return $text;
00228         }
00229 
00230         private function getViewsStats() {
00231                 return Xml::openElement( 'tr' ) .
00232                         Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-views' )->parse() ) .
00233                         Xml::closeElement( 'tr' ) .
00234                                 $this->formatRow( $this->msg( 'statistics-views-total' )->parse(),
00235                                         $this->getLanguage()->formatNum( $this->views ),
00236                                                 array ( 'class' => 'mw-statistics-views-total' ), 'statistics-views-total-desc' ) .
00237                                 $this->formatRow( $this->msg( 'statistics-views-peredit' )->parse(),
00238                                         $this->getLanguage()->formatNum( sprintf( '%.2f', $this->edits ?
00239                                                 $this->views / $this->edits : 0 ) ),
00240                                                 array ( 'class' => 'mw-statistics-views-peredit' ) );
00241         }
00242 
00243         private function getMostViewedPages() {
00244                 $text = '';
00245                 $dbr = wfGetDB( DB_SLAVE );
00246                 $res = $dbr->select(
00247                                 'page',
00248                                 array(
00249                                         'page_namespace',
00250                                         'page_title',
00251                                         'page_counter',
00252                                 ),
00253                                 array(
00254                                         'page_is_redirect' => 0,
00255                                         'page_counter > 0',
00256                                 ),
00257                                 __METHOD__,
00258                                 array(
00259                                         'ORDER BY' => 'page_counter DESC',
00260                                         'LIMIT' => 10,
00261                                 )
00262                         );
00263                         if( $res->numRows() > 0 ) {
00264                                 $text .= Xml::openElement( 'tr' );
00265                                 $text .= Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-mostpopular' )->parse() );
00266                                 $text .= Xml::closeElement( 'tr' );
00267                                 foreach ( $res as $row ) {
00268                                         $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
00269                                         if( $title instanceof Title ) {
00270                                                 $text .= $this->formatRow( Linker::link( $title ),
00271                                                                 $this->getLanguage()->formatNum( $row->page_counter ) );
00272 
00273                                         }
00274                                 }
00275                                 $res->free();
00276                         }
00277                 return $text;
00278         }
00279 
00280         private function getOtherStats( $stats ) {
00281                 if ( !count( $stats ) )
00282                         return '';
00283 
00284                 $return = Xml::openElement( 'tr' ) .
00285                         Xml::tags( 'th', array( 'colspan' => '2' ), $this->msg( 'statistics-header-hooks' )->parse() ) .
00286                         Xml::closeElement( 'tr' );
00287 
00288                 foreach( $stats as $name => $number ) {
00289                         $name = htmlspecialchars( $name );
00290                         $number = htmlspecialchars( $number );
00291 
00292                         $return .= $this->formatRow( $name, $this->getLanguage()->formatNum( $number ), array( 'class' => 'mw-statistics-hook' ) );
00293                 }
00294 
00295                 return $return;
00296         }
00297 }