MediaWiki REL1_37
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->getConnectionRef( DB_REPLICA );
56 wfDebug( __METHOD__ . ": reading site_stats from replica DB" );
58
59 if ( !self::isRowSane( $row ) && $lb->hasOrMadeRecentPrimaryChanges() ) {
60 // Might have just been initialized during this request? Underflow?
61 wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB" );
62 $row = self::doLoadFromDB( $lb->getConnectionRef( DB_PRIMARY ) );
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" );
77 }
78
79 $row = self::doLoadFromDB( $lb->getConnectionRef( DB_PRIMARY ) );
80 }
81
82 if ( !self::isRowSane( $row ) ) {
83 wfDebug( __METHOD__ . ": site_stats persistently nonsensical o_O" );
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 $fname = __METHOD__;
153
154 return $cache->getWithSetCallback(
155 $cache->makeKey( 'SiteStats', 'groupcounts', $group ),
156 $cache::TTL_HOUR,
157 function ( $oldValue, &$ttl, array &$setOpts ) use ( $group, $fname ) {
158 $dbr = self::getLB()->getConnectionRef( DB_REPLICA );
159 $setOpts += Database::getCacheSetOptions( $dbr );
160
161 return (int)$dbr->selectField(
162 'user_groups',
163 'COUNT(*)',
164 [
165 'ug_group' => $group,
166 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
167 ],
168 $fname
169 );
170 },
171 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
172 );
173 }
174
179 public static function jobs() {
180 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
181
182 return $cache->getWithSetCallback(
183 $cache->makeKey( 'SiteStats', 'jobscount' ),
184 $cache::TTL_MINUTE,
185 static function ( $oldValue, &$ttl, array &$setOpts ) {
186 try{
187 $jobs = array_sum( JobQueueGroup::singleton()->getQueueSizes() );
188 } catch ( JobQueueError $e ) {
189 $jobs = 0;
190 }
191 return $jobs;
192 },
193 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
194 );
195 }
196
201 public static function pagesInNs( $ns ) {
202 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
203 $fname = __METHOD__;
204
205 return $cache->getWithSetCallback(
206 $cache->makeKey( 'SiteStats', 'page-in-namespace', $ns ),
207 $cache::TTL_HOUR,
208 function ( $oldValue, &$ttl, array &$setOpts ) use ( $ns, $fname ) {
209 $dbr = self::getLB()->getConnectionRef( DB_REPLICA );
210 $setOpts += Database::getCacheSetOptions( $dbr );
211
212 return (int)$dbr->selectField(
213 'page',
214 'COUNT(*)',
215 [ 'page_namespace' => $ns ],
216 $fname
217 );
218 },
219 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
220 );
221 }
222
226 public static function selectFields() {
227 return [
228 'ss_total_edits',
229 'ss_good_articles',
230 'ss_total_pages',
231 'ss_users',
232 'ss_active_users',
233 'ss_images',
234 ];
235 }
236
241 private static function doLoadFromDB( IDatabase $db ) {
242 return $db->selectRow(
243 'site_stats',
244 self::selectFields(),
245 [ 'ss_row_id' => 1 ],
246 __METHOD__
247 );
248 }
249
258 private static function isRowSane( $row ) {
259 if ( $row === false
260 || $row->ss_total_pages < $row->ss_good_articles
261 || $row->ss_total_edits < $row->ss_total_pages
262 ) {
263 return false;
264 }
265 // Now check for underflow/overflow
266 foreach ( [
267 'ss_total_edits',
268 'ss_good_articles',
269 'ss_total_pages',
270 'ss_users',
271 'ss_images',
272 ] as $member ) {
273 if ( $row->$member < 0 ) {
274 return false;
275 }
276 }
277
278 return true;
279 }
280
285 private static function salvageInsaneRow( $row ) {
286 $map = $row ? (array)$row : [];
287 // Fill in any missing values with zero
288 $map += array_fill_keys( self::selectFields(), 0 );
289 // Convert negative values to zero
290 foreach ( $map as $field => $value ) {
291 $map[$field] = max( 0, $value );
292 }
293
294 return (object)$row;
295 }
296
300 private static function getLB() {
301 return MediaWikiServices::getInstance()->getDBLoadBalancer();
302 }
303}
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
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:52
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
selectRow( $table, $vars, $conds, $fname=__METHOD__, $options=[], $join_conds=[])
Wrapper to IDatabase::select() that only fetches one row (via LIMIT)
Database cluster connection, tracking, load balancing, and transaction manager interface.
$cache
Definition mcc.php:33
const DB_REPLICA
Definition defines.php:25
const DB_PRIMARY
Definition defines.php:27