SiteStatsInit.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. */
  20. use Wikimedia\Rdbms\IDatabase;
  21. use MediaWiki\MediaWikiServices;
  22. /**
  23. * Class designed for counting of stats.
  24. */
  25. class SiteStatsInit {
  26. /* @var IDatabase */
  27. private $dbr;
  28. /** @var int */
  29. private $edits;
  30. /** @var int */
  31. private $articles;
  32. /** @var int */
  33. private $pages;
  34. /** @var int */
  35. private $users;
  36. /** @var int */
  37. private $files;
  38. /**
  39. * @param bool|IDatabase $database
  40. * - bool: Whether to use the master DB
  41. * - IDatabase: Database connection to use
  42. */
  43. public function __construct( $database = false ) {
  44. if ( $database instanceof IDatabase ) {
  45. $this->dbr = $database;
  46. } elseif ( $database ) {
  47. $this->dbr = self::getDB( DB_MASTER );
  48. } else {
  49. $this->dbr = self::getDB( DB_REPLICA, 'vslow' );
  50. }
  51. }
  52. /**
  53. * Count the total number of edits
  54. * @return int
  55. */
  56. public function edits() {
  57. $this->edits = $this->dbr->selectField( 'revision', 'COUNT(*)', '', __METHOD__ );
  58. $this->edits += $this->dbr->selectField( 'archive', 'COUNT(*)', '', __METHOD__ );
  59. return $this->edits;
  60. }
  61. /**
  62. * Count pages in article space(s)
  63. * @return int
  64. */
  65. public function articles() {
  66. $config = MediaWikiServices::getInstance()->getMainConfig();
  67. $tables = [ 'page' ];
  68. $conds = [
  69. 'page_namespace' => MWNamespace::getContentNamespaces(),
  70. 'page_is_redirect' => 0,
  71. ];
  72. if ( $config->get( 'ArticleCountMethod' ) == 'link' ) {
  73. $tables[] = 'pagelinks';
  74. $conds[] = 'pl_from=page_id';
  75. }
  76. $this->articles = $this->dbr->selectField(
  77. $tables,
  78. 'COUNT(DISTINCT page_id)',
  79. $conds,
  80. __METHOD__
  81. );
  82. return $this->articles;
  83. }
  84. /**
  85. * Count total pages
  86. * @return int
  87. */
  88. public function pages() {
  89. $this->pages = $this->dbr->selectField( 'page', 'COUNT(*)', '', __METHOD__ );
  90. return $this->pages;
  91. }
  92. /**
  93. * Count total users
  94. * @return int
  95. */
  96. public function users() {
  97. $this->users = $this->dbr->selectField( 'user', 'COUNT(*)', '', __METHOD__ );
  98. return $this->users;
  99. }
  100. /**
  101. * Count total files
  102. * @return int
  103. */
  104. public function files() {
  105. $this->files = $this->dbr->selectField( 'image', 'COUNT(*)', '', __METHOD__ );
  106. return $this->files;
  107. }
  108. /**
  109. * Do all updates and commit them. More or less a replacement
  110. * for the original initStats, but without output.
  111. *
  112. * @param IDatabase|bool $database
  113. * - bool: Whether to use the master DB
  114. * - IDatabase: Database connection to use
  115. * @param array $options Array of options, may contain the following values
  116. * - activeUsers bool: Whether to update the number of active users (default: false)
  117. */
  118. public static function doAllAndCommit( $database, array $options = [] ) {
  119. $options += [ 'update' => false, 'activeUsers' => false ];
  120. // Grab the object and count everything
  121. $counter = new self( $database );
  122. $counter->edits();
  123. $counter->articles();
  124. $counter->pages();
  125. $counter->users();
  126. $counter->files();
  127. $counter->refresh();
  128. // Count active users if need be
  129. if ( $options['activeUsers'] ) {
  130. SiteStatsUpdate::cacheUpdate( self::getDB( DB_MASTER ) );
  131. }
  132. }
  133. /**
  134. * Insert a dummy row with all zeroes if no row is present
  135. */
  136. public static function doPlaceholderInit() {
  137. $dbw = self::getDB( DB_MASTER );
  138. $exists = $dbw->selectField( 'site_stats', '1', [ 'ss_row_id' => 1 ], __METHOD__ );
  139. if ( $exists === false ) {
  140. $dbw->insert(
  141. 'site_stats',
  142. [ 'ss_row_id' => 1 ] + array_fill_keys( SiteStats::selectFields(), 0 ),
  143. __METHOD__,
  144. [ 'IGNORE' ]
  145. );
  146. }
  147. }
  148. /**
  149. * Refresh site_stats
  150. */
  151. public function refresh() {
  152. $values = [
  153. 'ss_row_id' => 1,
  154. 'ss_total_edits' => $this->edits === null ? $this->edits() : $this->edits,
  155. 'ss_good_articles' => $this->articles === null ? $this->articles() : $this->articles,
  156. 'ss_total_pages' => $this->pages === null ? $this->pages() : $this->pages,
  157. 'ss_users' => $this->users === null ? $this->users() : $this->users,
  158. 'ss_images' => $this->files === null ? $this->files() : $this->files,
  159. ];
  160. self::getDB( DB_MASTER )->upsert(
  161. 'site_stats',
  162. $values,
  163. [ 'ss_row_id' ],
  164. $values,
  165. __METHOD__
  166. );
  167. }
  168. /**
  169. * @param int $index
  170. * @param string[] $groups
  171. * @return IDatabase
  172. */
  173. private static function getDB( $index, $groups = [] ) {
  174. $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
  175. return $lb->getConnection( $index, $groups );
  176. }
  177. }