MediaWiki REL1_31
SiteStats.php
Go to the documentation of this file.
1<?php
27
31class SiteStats {
33 private static $row;
34
38 public static function unload() {
39 self::$row = null;
40 }
41
42 protected static function load() {
43 if ( self::$row === null ) {
44 self::$row = self::loadAndLazyInit();
45 }
46 }
47
51 protected static function loadAndLazyInit() {
52 $config = MediaWikiServices::getInstance()->getMainConfig();
53
54 $lb = self::getLB();
55 $dbr = $lb->getConnection( DB_REPLICA );
56 wfDebug( __METHOD__ . ": reading site_stats from replica DB\n" );
58
59 if ( !self::isRowSane( $row ) && $lb->hasOrMadeRecentMasterChanges() ) {
60 // Might have just been initialized during this request? Underflow?
61 wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB\n" );
62 $row = self::doLoadFromDB( $lb->getConnection( DB_MASTER ) );
63 }
64
65 if ( !self::isRowSane( $row ) ) {
66 if ( $config->get( 'MiserMode' ) ) {
67 // Start off with all zeroes, assuming that this is a new wiki or any
68 // repopulations where done manually via script.
70 } else {
71 // Normally the site_stats table is initialized at install time.
72 // Some manual construction scenarios may leave the table empty or
73 // broken, however, for instance when importing from a dump into a
74 // clean schema with mwdumper.
75 wfDebug( __METHOD__ . ": initializing damaged or missing site_stats\n" );
77 }
78
79 $row = self::doLoadFromDB( $lb->getConnection( DB_MASTER ) );
80 }
81
82 if ( !self::isRowSane( $row ) ) {
83 wfDebug( __METHOD__ . ": site_stats persistently nonsensical o_O\n" );
84 // Always return a row-like object
86 }
87
88 return $row;
89 }
90
94 public static function edits() {
95 self::load();
96
97 return (int)self::$row->ss_total_edits;
98 }
99
103 public static function articles() {
104 self::load();
105
106 return (int)self::$row->ss_good_articles;
107 }
108
112 public static function pages() {
113 self::load();
114
115 return (int)self::$row->ss_total_pages;
116 }
117
121 public static function users() {
122 self::load();
123
124 return (int)self::$row->ss_users;
125 }
126
130 public static function activeUsers() {
131 self::load();
132
133 return (int)self::$row->ss_active_users;
134 }
135
139 public static function images() {
140 self::load();
141
142 return (int)self::$row->ss_images;
143 }
144
150 public static function numberingroup( $group ) {
151 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
152
153 return $cache->getWithSetCallback(
154 $cache->makeKey( 'SiteStats', 'groupcounts', $group ),
155 $cache::TTL_HOUR,
156 function ( $oldValue, &$ttl, array &$setOpts ) use ( $group ) {
157 $dbr = self::getLB()->getConnection( DB_REPLICA );
158 $setOpts += Database::getCacheSetOptions( $dbr );
159
160 return (int)$dbr->selectField(
161 'user_groups',
162 'COUNT(*)',
163 [
164 'ug_group' => $group,
165 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
166 ],
167 __METHOD__
168 );
169 },
170 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
171 );
172 }
173
178 public static function jobs() {
179 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
180
181 return $cache->getWithSetCallback(
182 $cache->makeKey( 'SiteStats', 'jobscount' ),
183 $cache::TTL_MINUTE,
184 function ( $oldValue, &$ttl, array &$setOpts ) {
185 try{
186 $jobs = array_sum( JobQueueGroup::singleton()->getQueueSizes() );
187 } catch ( JobQueueError $e ) {
188 $jobs = 0;
189 }
190 return $jobs;
191 },
192 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
193 );
194 }
195
200 public static function pagesInNs( $ns ) {
201 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
202
203 return $cache->getWithSetCallback(
204 $cache->makeKey( 'SiteStats', 'page-in-namespace', $ns ),
205 $cache::TTL_HOUR,
206 function ( $oldValue, &$ttl, array &$setOpts ) use ( $ns ) {
207 $dbr = self::getLB()->getConnection( DB_REPLICA );
208 $setOpts += Database::getCacheSetOptions( $dbr );
209
210 return (int)$dbr->selectField(
211 'page',
212 'COUNT(*)',
213 [ 'page_namespace' => $ns ],
214 __METHOD__
215 );
216 },
217 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
218 );
219 }
220
224 public static function selectFields() {
225 return [
226 'ss_total_edits',
227 'ss_good_articles',
228 'ss_total_pages',
229 'ss_users',
230 'ss_active_users',
231 'ss_images',
232 ];
233 }
234
239 private static function doLoadFromDB( IDatabase $db ) {
240 return $db->selectRow(
241 'site_stats',
242 self::selectFields(),
243 [ 'ss_row_id' => 1 ],
244 __METHOD__
245 );
246 }
247
256 private static function isRowSane( $row ) {
257 if ( $row === false
258 || $row->ss_total_pages < $row->ss_good_articles
259 || $row->ss_total_edits < $row->ss_total_pages
260 ) {
261 return false;
262 }
263 // Now check for underflow/overflow
264 foreach ( [
265 'ss_total_edits',
266 'ss_good_articles',
267 'ss_total_pages',
268 'ss_users',
269 'ss_images',
270 ] as $member ) {
271 if ( $row->$member < 0 ) {
272 return false;
273 }
274 }
275
276 return true;
277 }
278
283 private static function salvageInsaneRow( $row ) {
284 $map = $row ? (array)$row : [];
285 // Fill in any missing values with zero
286 $map += array_fill_keys( self::selectFields(), 0 );
287 // Convert negative values to zero
288 foreach ( $map as $field => $value ) {
289 $map[$field] = max( 0, $value );
290 }
291
292 return (object)$row;
293 }
294
298 private static function getLB() {
299 return MediaWikiServices::getInstance()->getDBLoadBalancer();
300 }
301}
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
static singleton( $domain=false)
MediaWikiServices is the service locator for the application scope of MediaWiki.
static doAllAndCommit( $database, array $options=[])
Do all updates and commit them.
static doPlaceholderInit()
Insert a dummy row with all zeroes if no row is present.
Static accessor class for site_stats and related things.
Definition SiteStats.php:31
static articles()
static jobs()
Total number of jobs in the job queue.
static pagesInNs( $ns)
static getLB()
static salvageInsaneRow( $row)
static images()
static load()
Definition SiteStats.php:42
static selectFields()
static edits()
Definition SiteStats.php:94
static loadAndLazyInit()
Definition SiteStats.php:51
static isRowSane( $row)
Is the provided row of site stats sane, or should it be regenerated?
static users()
static doLoadFromDB(IDatabase $db)
static pages()
static unload()
Trigger a reload next time a field is accessed.
Definition SiteStats.php:38
static numberingroup( $group)
Find the number of users in a given user group.
static stdClass $row
Definition SiteStats.php:33
static activeUsers()
Relational database abstraction object.
Definition Database.php:48
Database connection, tracking, load balancing, and transaction manager for a cluster.
when a variable name is used in a function
Definition design.txt:94
the array() calling protocol came about after MediaWiki 1.4rc1.
returning false will NOT prevent logging $e
Definition hooks.txt:2176
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
selectRow( $table, $vars, $conds, $fname=__METHOD__, $options=[], $join_conds=[])
Single row SELECT wrapper.
$cache
Definition mcc.php:33
const DB_REPLICA
Definition defines.php:25
const DB_MASTER
Definition defines.php:29