<?php
class blogStatistics {
  protected $hitCount = 0;
  protected $dayHitCount = 0;
  protected $dayPageViews = 0;
  protected $saveTime = 0;
  protected $pageViews = 0;

  /**
   * @var blogStatistics
   */
  public static $instance = null;
  public static $incHit = false;
  public static $incPageView = false;

  /**
   * array of views entry
   *
   * @var array
   */
  public static $entryViewCache = null;

  /**
   * Enter description here...
   *
   * @param Tblblogentry $tblblogentry
   */
  public static function recordViewEntry($tblblogentry) {
    $cache = sfMemcacheCache::getInstance();
    $entry_id = $tblblogentry->getEntryId();
    $cache_name = 'viewscache'.($entry_id % 50);

    self::$entryViewCache = $cache->getWithQueue($cache_name, '');
    if (null == self::$entryViewCache) self::$entryViewCache = array(0=>time());

    $current_hit = @self::$entryViewCache[$entry_id];
    if (null===$current_hit) $current_hit = $tblblogentry->getEntryHit();
    $current_hit ++;
    self::$entryViewCache[$entry_id] = $current_hit;
    if (count(self::$entryViewCache)>50 || self::$entryViewCache[0]+600<time()) {
      //myUtility::log("Cache $cache_name is expired", "views.log", "\n");
      $test = $cache->get($cache_name);
      if ($test[0] != self::$entryViewCache[0]) {/*myUtility::log("new cache", "views.log");*/return $current_hit;}
      $cache->set($cache_name, '', array(0=>time()), 90000);

      //myUtility::log("Start save $cache_name (".count(self::$entryViewCache)." records)", "views.log");
      foreach (self::$entryViewCache as $id=>$hit) {
        if ($id>0) {
          $s = new Criteria();
          $s->add(TblblogentryPeer::ENTRY_ID, $id);

          $v = new Criteria();
          $v->add(TblblogentryPeer::ENTRY_HIT, $hit);
          BasePeer::doUpdate($s, $v, Propel::getConnection(TblblogentryPeer::DATABASE_NAME));
        }
      }
      //myUtility::log("Finish save $cache_name", "views.log");
    } else {
      $cache->set($cache_name, '', self::$entryViewCache, 90000);
    }

    return $current_hit;
  }

  /**
   * set $incHit = true if this user first visit this blog
   *
   */
  public static function checkHitBlog() {
    if (self::$incHit) return;
    $cookieName = 'visit'.blogStore::$blogId;
    $user = sfContext::getInstance()->getUser();
    $isVisited = $user->getAttribute($cookieName, null, 'user');
    if ($isVisited===null) {
      $cache = sfMemcacheCache::getInstance();
      $ip = myUtility::getRealIpAddr();
      $cache_name = blogStore::$blogId.'.'.$ip;
      if (null == $cache->get($cache_name, 'ip')) {
        self::$incHit = true;
        $cache->set($cache_name, 'ip', 1, 300);
      }
      $user->setAttribute($cookieName, 1, 'user');
    }
  }

  public function getHitCount() {
    return $this->hitCount;
  }

  public function getPageViews() {
    return $this->pageViews;
  }

  public function getDayPageViews() {
    return $this->dayPageViews;
  }

  public function getDayHitCount() {
    return $this->dayHitCount;
  }

  public static function getBlogId() {
    if (class_exists('blogStore')) return blogStore::$blogId; else return 0;
  }

  public function saveToCache() {
    sfMemcacheCache::getInstance()->set(self::getBlogId(), 'blogstat', $this, 90000);
  }

  public function incHitCount() {
    $this->hitCount++;
    $this->dayHitCount++;
  }

  public function doStatistics() {
		// quang's disable statistics
		// return;
    $this->pageViews++;
    $this->dayPageViews++;
    $minuteOfDay = (time() - strtotime(date('Y-m-d')))/60;
    if ($minuteOfDay<0) $minuteOfDay = 1;
    if (time() > $this->saveTime + 300 /*|| $this->dayHitCount < $minuteOfDay*/) {
      $this->passToDatabase();
      $this->saveTime = time();
    }
    $this->saveToCache();
  }

  public static function getInstance() {
    $blogId = self::getBlogId();
    if (self::$instance===null) {
      $cache = sfMemcacheCache::getInstance();
      self::$instance = $cache->getWithQueue($blogId, 'blogstat');

      if (self::$instance===null) {
        self::$instance = new blogStatistics();
        if ($blogId!=0) {
          $tblblog = TblblogPeer::retrieveByPK($blogId);
          self::$instance->hitCount = $tblblog->getBlHit();
          self::$instance->pageViews = $tblblog->getBlPageviews();

          $today = date('Y-m-d');
          $tblblogstatday = TblblogstatdayPeer::retrieveByPK($blogId, $today);
          if ($tblblogstatday) {
            self::$instance->dayHitCount = $tblblogstatday->getStdVisitors();
            self::$instance->dayPageViews = $tblblogstatday->getStdPageviews();
          }
        } else {
          self::$instance->hitCount = 0;
          self::$instance->pageViews = 0;
        }
        self::$instance->saveTime = time();
        self::$instance->saveToCache();
      }

      self::checkHitBlog();
      if (self::$incHit) {
        self::$instance->incHitCount();
      }
      self::$instance->doStatistics();
    }
    return self::$instance;
  }

  /**
   * Pass all cache data to database
   *
   */
  function passToDatabase() {
    $blogId = self::getBlogId();
    //if ($blogId==10) myUtility::log("Start save statistics", "statistics.log", "\n");
    if ($blogId!=0) {
      $c = new Criteria();
      $c->add(TblblogPeer::BL_ID, $blogId, Criteria::EQUAL);
      $c->add(TblblogPeer::BL_HIT, $this->hitCount);
      $c->add(TblblogPeer::BL_PAGEVIEWS, $this->pageViews);
      TblblogPeer::doUpdate($c);
    }

    $today = date('Y-m-d');
    $tblblogstatday = TblblogstatdayPeer::retrieveByPK($blogId, $today);
    if (!$tblblogstatday) {
      $yesterday = date('Y-m-d', strtotime('-1 day'));
      $tblblogstatdaybefore = TblblogstatdayPeer::retrieveByPK($blogId, $yesterday);
      if ($tblblogstatdaybefore) {
        if ($this->dayHitCount >= $tblblogstatdaybefore->getStdVisitors())
          $this->dayHitCount -= $tblblogstatdaybefore->getStdVisitors();
        if ($this->dayPageViews >= $tblblogstatdaybefore->getStdPageviews())
          $this->dayPageViews -= $tblblogstatdaybefore->getStdPageviews();
        $this->saveToCache();
      }

      $tblblogstatday = new Tblblogstatday();
      $tblblogstatday->setStdBlog($blogId);
      $tblblogstatday->setStdDate($today);
      $tblblogstatday->setStdVisitors($this->dayHitCount);
      $tblblogstatday->setStdPageviews($this->dayPageViews);
      $tblblogstatday->setStdBlogtype(blogStore::getBlogStyle());
      $tblblogstatday->setStdBlogadmin(blogStore::$blog->getBlUser());

    } else {
      $tblblogstatday->setStdVisitors($this->dayHitCount);
      $tblblogstatday->setStdPageviews($this->dayPageViews);
    }
    $tblblogstatday->save();
    //if ($blogId==10) myUtility::log("Finish save statistics", "statistics.log");
  }
}
?>
