MediaWiki REL1_40
SiteStats.php
Go to the documentation of this file.
1<?php
28
32class SiteStats {
34 private static $row;
35
39 public static function unload() {
40 self::$row = null;
41 }
42
43 protected static function load() {
44 if ( self::$row === null ) {
45 self::$row = self::loadAndLazyInit();
46 }
47 }
48
52 protected static function loadAndLazyInit() {
53 $config = MediaWikiServices::getInstance()->getMainConfig();
54
55 $lb = self::getLB();
56 $dbr = $lb->getConnectionRef( DB_REPLICA );
57 wfDebug( __METHOD__ . ": reading site_stats from replica DB" );
58 $row = self::doLoadFromDB( $dbr );
59
60 if ( !self::isRowSensible( $row ) && $lb->hasOrMadeRecentPrimaryChanges() ) {
61 // Might have just been initialized during this request? Underflow?
62 wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB" );
63 $row = self::doLoadFromDB( $lb->getConnectionRef( DB_PRIMARY ) );
64 }
65
66 if ( !self::isRowSensible( $row ) ) {
67 if ( $config->get( MainConfigNames::MiserMode ) ) {
68 // Start off with all zeroes, assuming that this is a new wiki or any
69 // repopulations where done manually via script.
71 } else {
72 // Normally the site_stats table is initialized at install time.
73 // Some manual construction scenarios may leave the table empty or
74 // broken, however, for instance when importing from a dump into a
75 // clean schema with mwdumper.
76 wfDebug( __METHOD__ . ": initializing damaged or missing site_stats" );
78 }
79
80 $row = self::doLoadFromDB( $lb->getConnectionRef( DB_PRIMARY ) );
81 }
82
83 return $row;
84 }
85
89 public static function edits() {
90 self::load();
91
92 return (int)self::$row->ss_total_edits;
93 }
94
98 public static function articles() {
99 self::load();
100
101 return (int)self::$row->ss_good_articles;
102 }
103
107 public static function pages() {
108 self::load();
109
110 return (int)self::$row->ss_total_pages;
111 }
112
116 public static function users() {
117 self::load();
118
119 return (int)self::$row->ss_users;
120 }
121
125 public static function activeUsers() {
126 self::load();
127
128 return (int)self::$row->ss_active_users;
129 }
130
134 public static function images() {
135 self::load();
136
137 return (int)self::$row->ss_images;
138 }
139
145 public static function numberingroup( $group ) {
146 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
147 $fname = __METHOD__;
148
149 return $cache->getWithSetCallback(
150 $cache->makeKey( 'SiteStats', 'groupcounts', $group ),
151 $cache::TTL_HOUR,
152 function ( $oldValue, &$ttl, array &$setOpts ) use ( $group, $fname ) {
153 $dbr = self::getLB()->getConnectionRef( DB_REPLICA );
154 $setOpts += Database::getCacheSetOptions( $dbr );
155 return (int)$dbr->newSelectQueryBuilder()
156 ->select( 'COUNT(*)' )
157 ->from( 'user_groups' )
158 ->where(
159 [
160 'ug_group' => $group,
161 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
162 ]
163 )
164 ->caller( $fname )
165 ->fetchField();
166 },
167 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
168 );
169 }
170
175 public static function jobs() {
176 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
177
178 return $cache->getWithSetCallback(
179 $cache->makeKey( 'SiteStats', 'jobscount' ),
180 $cache::TTL_MINUTE,
181 static function ( $oldValue, &$ttl, array &$setOpts ) {
182 try {
183 $jobs = array_sum( MediaWikiServices::getInstance()->getJobQueueGroup()->getQueueSizes() );
184 } catch ( JobQueueError $e ) {
185 $jobs = 0;
186 }
187 return $jobs;
188 },
189 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
190 );
191 }
192
197 public static function pagesInNs( $ns ) {
198 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
199 $fname = __METHOD__;
200
201 return $cache->getWithSetCallback(
202 $cache->makeKey( 'SiteStats', 'page-in-namespace', $ns ),
203 $cache::TTL_HOUR,
204 function ( $oldValue, &$ttl, array &$setOpts ) use ( $ns, $fname ) {
205 $dbr = self::getLB()->getConnectionRef( DB_REPLICA );
206 $setOpts += Database::getCacheSetOptions( $dbr );
207
208 return (int)$dbr->selectField(
209 'page',
210 'COUNT(*)',
211 [ 'page_namespace' => $ns ],
212 $fname
213 );
214 },
215 [ 'pcTTL' => $cache::TTL_PROC_LONG ]
216 );
217 }
218
222 public static function selectFields() {
223 return [
224 'ss_total_edits',
225 'ss_good_articles',
226 'ss_total_pages',
227 'ss_users',
228 'ss_active_users',
229 'ss_images',
230 ];
231 }
232
237 private static function doLoadFromDB( IDatabase $db ) {
238 $fields = self::selectFields();
239 $rows = $db->newSelectQueryBuilder()
240 ->select( $fields )
241 ->from( 'site_stats' )
242 ->caller( __METHOD__ )
243 ->fetchResultSet();
244 if ( !$rows->numRows() ) {
245 return false;
246 }
247 $finalRow = new stdClass();
248 foreach ( $rows as $row ) {
249 foreach ( $fields as $field ) {
250 $finalRow->$field ??= 0;
251 if ( $row->$field ) {
252 $finalRow->$field += $row->$field;
253 }
254 }
255
256 }
257 return $finalRow;
258 }
259
268 private static function isRowSensible( $row ) {
269 if ( $row === false
270 || $row->ss_total_pages < $row->ss_good_articles
271 || $row->ss_total_edits < $row->ss_total_pages
272 ) {
273 return false;
274 }
275 // Now check for underflow/overflow
276 foreach ( [
277 'ss_total_edits',
278 'ss_good_articles',
279 'ss_total_pages',
280 'ss_users',
281 'ss_images',
282 ] as $member ) {
283 if ( $row->$member < 0 ) {
284 return false;
285 }
286 }
287
288 return true;
289 }
290
294 private static function getLB() {
295 return MediaWikiServices::getInstance()->getDBLoadBalancer();
296 }
297}
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
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:32
static articles()
Definition SiteStats.php:98
static jobs()
Total number of jobs in the job queue.
static pagesInNs( $ns)
static images()
static load()
Definition SiteStats.php:43
static selectFields()
static edits()
Definition SiteStats.php:89
static loadAndLazyInit()
Definition SiteStats.php:52
static users()
static pages()
static unload()
Trigger a reload next time a field is accessed.
Definition SiteStats.php:39
static numberingroup( $group)
Find the number of users in a given user group.
static activeUsers()
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:36
This class is a delegate to ILBFactory for a given database cluster.
newSelectQueryBuilder()
Create an empty SelectQueryBuilder which can be used to run queries against this connection.
const DB_REPLICA
Definition defines.php:26
const DB_PRIMARY
Definition defines.php:28