00001 <?php 00002 00016 class SpecialStatistics extends SpecialPage { 00017 00018 private $views, $edits, $good, $images, $total, $users, 00019 $activeUsers, $admins, $numJobs = 0; 00020 00021 public function __construct() { 00022 parent::__construct( 'Statistics' ); 00023 } 00024 00025 public function execute( $par ) { 00026 global $wgOut, $wgRequest, $wgMessageCache; 00027 global $wgDisableCounters, $wgMiserMode; 00028 $wgMessageCache->loadAllMessages(); 00029 00030 $this->setHeaders(); 00031 00032 $this->views = SiteStats::views(); 00033 $this->edits = SiteStats::edits(); 00034 $this->good = SiteStats::articles(); 00035 $this->images = SiteStats::images(); 00036 $this->total = SiteStats::pages(); 00037 $this->users = SiteStats::users(); 00038 $this->activeUsers = SiteStats::activeUsers(); 00039 $this->admins = SiteStats::numberingroup('sysop'); 00040 $this->numJobs = SiteStats::jobs(); 00041 00042 # Staticic - views 00043 $viewsStats = ''; 00044 if( !$wgDisableCounters ) { 00045 $viewsStats = $this->getViewsStats(); 00046 } 00047 00048 # Set active user count 00049 if( !$wgMiserMode ) { 00050 $dbw = wfGetDB( DB_MASTER ); 00051 SiteStatsUpdate::cacheUpdate( $dbw ); 00052 } 00053 00054 # Do raw output 00055 if( $wgRequest->getVal( 'action' ) == 'raw' ) { 00056 $this->doRawOutput(); 00057 } 00058 00059 $text = Xml::openElement( 'table', array( 'class' => 'mw-statistics-table' ) ); 00060 00061 # Statistic - pages 00062 $text .= $this->getPageStats(); 00063 00064 # Statistic - edits 00065 $text .= $this->getEditStats(); 00066 00067 # Statistic - users 00068 $text .= $this->getUserStats(); 00069 00070 # Statistic - usergroups 00071 $text .= $this->getGroupStats(); 00072 $text .= $viewsStats; 00073 00074 # Statistic - popular pages 00075 if( !$wgDisableCounters && !$wgMiserMode ) { 00076 $text .= $this->getMostViewedPages(); 00077 } 00078 00079 $text .= Xml::closeElement( 'table' ); 00080 00081 # Customizable footer 00082 $footer = wfMsgExt( 'statistics-footer', array('parseinline') ); 00083 if( !wfEmptyMsg( 'statistics-footer', $footer ) && $footer != '' ) { 00084 $text .= "\n" . $footer; 00085 } 00086 00087 $wgOut->addHTML( $text ); 00088 } 00089 00099 private function formatRow( $text, $number, $trExtraParams = array(), $descMsg = '', $descMsgParam = '' ) { 00100 global $wgStylePath; 00101 if( $descMsg ) { 00102 $descriptionText = wfMsgExt( $descMsg, array( 'parseinline' ), $descMsgParam ); 00103 if ( !wfEmptyMsg( $descMsg, $descriptionText ) ) { 00104 $descriptionText = " ($descriptionText)"; 00105 $text .= "<br />" . Xml::element( 'small', array( 'class' => 'mw-statistic-desc'), 00106 $descriptionText ); 00107 } 00108 } 00109 return Xml::openElement( 'tr', $trExtraParams ) . 00110 Xml::openElement( 'td' ) . $text . Xml::closeElement( 'td' ) . 00111 Xml::openElement( 'td', array( 'class' => 'mw-statistics-numbers' ) ) . $number . Xml::closeElement( 'td' ) . 00112 Xml::closeElement( 'tr' ); 00113 } 00114 00120 private function getPageStats() { 00121 global $wgLang; 00122 return Xml::openElement( 'tr' ) . 00123 Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-pages', array( 'parseinline' ) ) ) . 00124 Xml::closeElement( 'tr' ) . 00125 $this->formatRow( wfMsgExt( 'statistics-articles', array( 'parseinline' ) ), 00126 $wgLang->formatNum( $this->good ), 00127 array( 'class' => 'mw-statistics-articles' ) ) . 00128 $this->formatRow( wfMsgExt( 'statistics-pages', array( 'parseinline' ) ), 00129 $wgLang->formatNum( $this->total ), 00130 array( 'class' => 'mw-statistics-pages' ), 00131 'statistics-pages-desc' ) . 00132 $this->formatRow( wfMsgExt( 'statistics-files', array( 'parseinline' ) ), 00133 $wgLang->formatNum( $this->images ), 00134 array( 'class' => 'mw-statistics-files' ) ); 00135 } 00136 private function getEditStats() { 00137 global $wgLang; 00138 return Xml::openElement( 'tr' ) . 00139 Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-edits', array( 'parseinline' ) ) ) . 00140 Xml::closeElement( 'tr' ) . 00141 $this->formatRow( wfMsgExt( 'statistics-edits', array( 'parseinline' ) ), 00142 $wgLang->formatNum( $this->edits ), 00143 array( 'class' => 'mw-statistics-edits' ) ) . 00144 $this->formatRow( wfMsgExt( 'statistics-edits-average', array( 'parseinline' ) ), 00145 $wgLang->formatNum( sprintf( '%.2f', $this->total ? $this->edits / $this->total : 0 ) ), 00146 array( 'class' => 'mw-statistics-edits-average' ) ) . 00147 $this->formatRow( wfMsgExt( 'statistics-jobqueue', array( 'parseinline' ) ), 00148 $wgLang->formatNum( $this->numJobs ), 00149 array( 'class' => 'mw-statistics-jobqueue' ) ); 00150 } 00151 private function getUserStats() { 00152 global $wgLang, $wgRCMaxAge; 00153 return Xml::openElement( 'tr' ) . 00154 Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-users', array( 'parseinline' ) ) ) . 00155 Xml::closeElement( 'tr' ) . 00156 $this->formatRow( wfMsgExt( 'statistics-users', array( 'parseinline' ) ), 00157 $wgLang->formatNum( $this->users ), 00158 array( 'class' => 'mw-statistics-users' ) ) . 00159 $this->formatRow( wfMsgExt( 'statistics-users-active', array( 'parseinline' ) ), 00160 $wgLang->formatNum( $this->activeUsers ), 00161 array( 'class' => 'mw-statistics-users-active' ), 00162 'statistics-users-active-desc', 00163 $wgLang->formatNum( ceil( $wgRCMaxAge / ( 3600 * 24 ) ) ) ); 00164 } 00165 private function getGroupStats() { 00166 global $wgGroupPermissions, $wgImplicitGroups, $wgLang, $wgUser; 00167 $sk = $wgUser->getSkin(); 00168 $text = ''; 00169 foreach( $wgGroupPermissions as $group => $permissions ) { 00170 # Skip generic * and implicit groups 00171 if ( in_array( $group, $wgImplicitGroups ) || $group == '*' ) { 00172 continue; 00173 } 00174 $groupname = htmlspecialchars( $group ); 00175 $msg = wfMsg( 'group-' . $groupname ); 00176 if ( wfEmptyMsg( 'group-' . $groupname, $msg ) || $msg == '' ) { 00177 $groupnameLocalized = $groupname; 00178 } else { 00179 $groupnameLocalized = $msg; 00180 } 00181 $msg = wfMsgForContent( 'grouppage-' . $groupname ); 00182 if ( wfEmptyMsg( 'grouppage-' . $groupname, $msg ) || $msg == '' ) { 00183 $grouppageLocalized = MWNamespace::getCanonicalName( NS_PROJECT ) . ':' . $groupname; 00184 } else { 00185 $grouppageLocalized = $msg; 00186 } 00187 $grouppage = $sk->makeLink( $grouppageLocalized, htmlspecialchars( $groupnameLocalized ) ); 00188 $grouplink = $sk->link( SpecialPage::getTitleFor( 'Listusers' ), 00189 wfMsgHtml( 'listgrouprights-members' ), 00190 array(), 00191 array( 'group' => $group ), 00192 'known' ); 00193 # Add a class when a usergroup contains no members to allow hiding these rows 00194 $classZero = ''; 00195 $countUsers = SiteStats::numberingroup( $groupname ); 00196 if( $countUsers == 0 ) { 00197 $classZero = ' statistics-group-zero'; 00198 } 00199 $text .= $this->formatRow( $grouppage . ' ' . $grouplink, 00200 $wgLang->formatNum( $countUsers ), 00201 array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero ) ); 00202 } 00203 return $text; 00204 } 00205 private function getViewsStats() { 00206 global $wgLang; 00207 return Xml::openElement( 'tr' ) . 00208 Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-header-views', array( 'parseinline' ) ) ) . 00209 Xml::closeElement( 'tr' ) . 00210 $this->formatRow( wfMsgExt( 'statistics-views-total', array( 'parseinline' ) ), 00211 $wgLang->formatNum( $this->views ), 00212 array ( 'class' => 'mw-statistics-views-total' ) ) . 00213 $this->formatRow( wfMsgExt( 'statistics-views-peredit', array( 'parseinline' ) ), 00214 $wgLang->formatNum( sprintf( '%.2f', $this->edits ? 00215 $this->views / $this->edits : 0 ) ), 00216 array ( 'class' => 'mw-statistics-views-peredit' ) ); 00217 } 00218 private function getMostViewedPages() { 00219 global $wgLang, $wgUser; 00220 $text = ''; 00221 $dbr = wfGetDB( DB_SLAVE ); 00222 $sk = $wgUser->getSkin(); 00223 $res = $dbr->select( 00224 'page', 00225 array( 00226 'page_namespace', 00227 'page_title', 00228 'page_counter', 00229 ), 00230 array( 00231 'page_is_redirect' => 0, 00232 'page_counter > 0', 00233 ), 00234 __METHOD__, 00235 array( 00236 'ORDER BY' => 'page_counter DESC', 00237 'LIMIT' => 10, 00238 ) 00239 ); 00240 if( $res->numRows() > 0 ) { 00241 $text .= Xml::tags( 'th', array( 'colspan' => '2' ), wfMsgExt( 'statistics-mostpopular', array( 'parseinline' ) ) ); 00242 while( $row = $res->fetchObject() ) { 00243 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); 00244 if( $title instanceof Title ) { 00245 $text .= $this->formatRow( $sk->link( $title ), 00246 $wgLang->formatNum( $row->page_counter ) ); 00247 00248 } 00249 } 00250 $res->free(); 00251 } 00252 return $text; 00253 } 00254 00260 private function doRawOutput() { 00261 global $wgOut; 00262 $wgOut->disable(); 00263 header( 'Pragma: nocache' ); 00264 echo "total=" . $this->total . ";good=" . $this->good . ";views=" . 00265 $this->views . ";edits=" . $this->edits . ";users=" . $this->users . ";"; 00266 echo "activeusers=" . $this->activeUsers . ";admins=" . $this->admins . 00267 ";images=" . $this->images . ";jobs=" . $this->numJobs . "\n"; 00268 return; 00269 } 00270 }