[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/deferred/ -> ViewCountUpdate.php (source)

   1  <?php
   2  /**
   3   * Update for the 'page_counter' field
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   */
  22  
  23  /**
  24   * Update for the 'page_counter' field, when $wgDisableCounters is false.
  25   *
  26   * Depending on $wgHitcounterUpdateFreq, this will directly increment the
  27   * 'page_counter' field or use the 'hitcounter' table and then collect the data
  28   * from that table to update the 'page_counter' field in a batch operation.
  29   */
  30  class ViewCountUpdate implements DeferrableUpdate {
  31      /** @var int Page ID to increment the view count */
  32      protected $id;
  33  
  34      /**
  35       * Constructor
  36       *
  37       * @param int $id Page ID to increment the view count
  38       */
  39  	public function __construct( $id ) {
  40          $this->id = intval( $id );
  41      }
  42  
  43      /**
  44       * Run the update
  45       */
  46  	public function doUpdate() {
  47          global $wgHitcounterUpdateFreq;
  48  
  49          $dbw = wfGetDB( DB_MASTER );
  50  
  51          if ( $wgHitcounterUpdateFreq <= 1 || $dbw->getType() == 'sqlite' ) {
  52              $id = $this->id;
  53              $method = __METHOD__;
  54              $dbw->onTransactionIdle( function () use ( $dbw, $id, $method ) {
  55                  try {
  56                      $dbw->update( 'page',
  57                          array( 'page_counter = page_counter + 1' ),
  58                          array( 'page_id' => $id ),
  59                          $method
  60                      );
  61                  } catch ( DBError $e ) {
  62                      MWExceptionHandler::logException( $e );
  63                  }
  64              } );
  65              return;
  66          }
  67  
  68          # Not important enough to warrant an error page in case of failure
  69          try {
  70              // Since `hitcounter` is non-transactional, the contention is minimal
  71              $dbw->insert( 'hitcounter', array( 'hc_id' => $this->id ), __METHOD__ );
  72              $checkfreq = intval( $wgHitcounterUpdateFreq / 25 + 1 );
  73              if ( rand() % $checkfreq == 0 && $dbw->lastErrno() == 0 ) {
  74                  $this->collect();
  75              }
  76          } catch ( DBError $e ) {
  77              MWExceptionHandler::logException( $e );
  78          }
  79      }
  80  
  81  	protected function collect() {
  82          global $wgHitcounterUpdateFreq;
  83  
  84          $dbw = wfGetDB( DB_MASTER );
  85  
  86          $rown = $dbw->selectField( 'hitcounter', 'COUNT(*)', array(), __METHOD__ );
  87          if ( $rown < $wgHitcounterUpdateFreq ) {
  88              return;
  89          }
  90  
  91          wfProfileIn( __METHOD__ . '-collect' );
  92          $old_user_abort = ignore_user_abort( true );
  93  
  94          $dbType = $dbw->getType();
  95          $tabletype = $dbType == 'mysql' ? "ENGINE=HEAP " : '';
  96          $hitcounterTable = $dbw->tableName( 'hitcounter' );
  97          $acchitsTable = $dbw->tableName( 'acchits' );
  98          $pageTable = $dbw->tableName( 'page' );
  99  
 100          $dbw->lockTables( array(), array( 'hitcounter' ), __METHOD__, false );
 101          $dbw->query( "CREATE TEMPORARY TABLE $acchitsTable $tabletype AS " .
 102              "SELECT hc_id,COUNT(*) AS hc_n FROM $hitcounterTable " .
 103              'GROUP BY hc_id', __METHOD__ );
 104          $dbw->delete( 'hitcounter', '*', __METHOD__ );
 105          $dbw->unlockTables( __METHOD__ );
 106  
 107          if ( $dbType == 'mysql' ) {
 108              $dbw->query( "UPDATE $pageTable,$acchitsTable SET page_counter=page_counter + hc_n " .
 109                  'WHERE page_id = hc_id', __METHOD__ );
 110          } else {
 111              $dbw->query( "UPDATE $pageTable SET page_counter=page_counter + hc_n " .
 112                  "FROM $acchitsTable WHERE page_id = hc_id", __METHOD__ );
 113          }
 114          $dbw->query( "DROP TABLE $acchitsTable", __METHOD__ );
 115  
 116          ignore_user_abort( $old_user_abort );
 117          wfProfileOut( __METHOD__ . '-collect' );
 118      }
 119  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1