Skip to content

Instantly share code, notes, and snippets.

@ryun
Created May 26, 2012 18:30
Show Gist options
  • Save ryun/2794868 to your computer and use it in GitHub Desktop.
Save ryun/2794868 to your computer and use it in GitHub Desktop.
Hitcounter for pretty much anything
<?php
class Hcount {
private static $CI;
private static $CFG = array();
private static $DEFAULTS = array(
'timeout' => 2419200, // 4 * 7 * 24 * 3600 (1 month)
//Hits counter table
'tbl_hit_count' => array(
'name' => 'hit_counts',
'fields' => array(
'hits' =>'hits',
'item_id' => 'item_id',
'module' => 'module',
'is_unique' => 'is_unique'
)
),
//Hits log table
'tbl_hit_log' => array(
'name' => 'hit_logs',
'fields' => array('hash'=>'hash', 'time' => 'time')
)
);
public function __construct($config=array())
{
self::$CI = & get_instance();
self::init($config);
}
protected function init($config=array())
{
self::$CFG = (!empty($config)) ? array_merge(self::$DEFAULTS, $config) : self::$DEFAULTS;
}
// --------------------------------------------------------------------
/* -------------------------------------
* TABLES
* -------------------------------------
* tbl_hit_logs
* - hash
* - time
*
* tbl_hit_count
* - id
* - item_id
* - module
* - is_unique
* - hits
*
*/
public static function add($item_id, $module=false, $user_id=false)
{
// They must be a guest
if (empty($user_id))
{
$user_id = self::$CI->input->ip_address();
}
// Set module/namespace
$module = self::get_module($module);
// clear old logs from db
self::clean();
// create if not found
if (self::create_new($item_id, $module))
{
self::log_hit($item_id, $module, $user_id);
} else {
// increment unique hit count
if (self::is_unique($item_id, $module, $user_id))
{
self::add_hit($item_id, $module, true);
// Log for unique hit checking
self::log_hit($item_id, $module, $user_id);
}
// increment hit count
self::add_hit($item_id, $module, false);
}
}
/*
* Returns (int) the amount of hits a page has
* $item_id - the page identifier
* $unique - true if you want unique hit count
*/
public static function get($item_id, $module, $unique = false)
{
$unique = $unique ? '1' : '0';
$count = self::$CI->db
->select("hits")
->where(array(self::$CFG['tbl_hit_count']['fields']['item_id'] => $item_id, self::$CFG['tbl_hit_count']['fields']['module'] => $module, self::$CFG['tbl_hit_count']['fields']['is_unique'] => $unique))
->get(self::$CFG['tbl_hit_count']['name'])
->row('hits');
return ($count) ? $count : 0;
}
public static function get_all($item_id, $module)
{
$count = self::$CI->db
->select("hits")
->where(array(self::$CFG['tbl_hit_count']['fields']['item_id'] => $item_id, self::$CFG['tbl_hit_count']['fields']['module'] => $module))
->get(self::$CFG['tbl_hit_count']['name'])
->result_array();
return ($count) ? array('total'=>$count[0]['hits'],'unique' => $count[1]['hits']) : array();
}
public static function get_total($module=false, $unique = false)
{
$where = array('is_unique' => $unique ? '1' : '0');
if ($module) $where['module'] = $module;
$count = self::$CI->db
->select_sum(self::$CFG['tbl_hit_count']['fields']['hits'])
->where($where)
->get(self::$CFG['tbl_hit_count']['name'])
->row(self::$CFG['tbl_hit_count']['fields']['hits']);
return $count;
}
public static function log_hit($item_id, $module, $user_id)
{
$hash = self::hash($item_id, $module, $user_id);
$time = self::$CI->db
->select(self::$CFG['tbl_hit_log']['fields']['time'])
->where('hash', $hash)
->get(self::$CFG['tbl_hit_log']['name'])
->row(self::$CFG['tbl_hit_log']['fields']['time']);
$current_time = time();
if ($time)
{
// Update last visited time
self::$CI->db
->where('hash', $hash)
->update(self::$CFG['tbl_hit_log']['name'], array(self::$CFG['tbl_hit_log']['fields']['time'] => $current_time));
}
else
{
// Insert new visit time
self::$CI->db
->insert(self::$CFG['tbl_hit_log']['name'], array('hash' => $hash, self::$CFG['tbl_hit_log']['fields']['time'] => $current_time));
}
}
public static function add_hit($item_id, $module, $unique=0)
{
$conditions = array(
self::$CFG['tbl_hit_count']['fields']['item_id'] => $item_id,
self::$CFG['tbl_hit_count']['fields']['module'] => $module
);
if (!empty(self::$CFG['tbl_hit_count']['fields']['is_unique']))
{
$conditions[self::$CFG['tbl_hit_count']['fields']['is_unique']] = $unique ? '1' : '0';
}
self::$CI->db
->set(self::$CFG['tbl_hit_count']['fields']['hits'], self::$CFG['tbl_hit_count']['fields']['hits'].' + 1', FALSE)
->where($conditions)
->update(self::$CFG['tbl_hit_count']['name']);
}
/* ====================== PRIVATE METHODS ============================= */
private static function is_unique($item_id, $module, $user_id)
{
$time = self::$CI->db
->select(self::$CFG['tbl_hit_log']['fields']['time'])
->where(self::$CFG['tbl_hit_log']['fields']['hash'], self::hash($item_id, $module, $user_id))
->get(self::$CFG['tbl_hit_log']['name'])
->row(self::$CFG['tbl_hit_log']['fields']['time']);
if ($time)
{
return ($time > (time() - self::$CFG['timeout'])) ? false : true;
}
else
{
return true;
}
}
private static function hash($item_id, $module, $user_id)
{
return $item_id.'-'.$module.'-'.$user_id;
}
private static function create_new($item_id, $module)
{
// Check for existing hits
$count = self::$CI->db->where(array(self::$CFG['tbl_hit_count']['fields']['item_id'] => $item_id, self::$CFG['tbl_hit_count']['fields']['module'] => $module))->count_all_results(self::$CFG['tbl_hit_count']['name']);
if ($count == 0)
{
self::$CI->db->insert(self::$CFG['tbl_hit_count']['name'], array(self::$CFG['tbl_hit_count']['fields']['item_id'] => $item_id, self::$CFG['tbl_hit_count']['fields']['module'] => $module, 'is_unique' => 0, 'hits' => 1));
self::$CI->db->insert(self::$CFG['tbl_hit_count']['name'], array(self::$CFG['tbl_hit_count']['fields']['item_id'] => $item_id, self::$CFG['tbl_hit_count']['fields']['module'] => $module, self::$CFG['tbl_hit_count']['fields']['is_unique'] => 1, self::$CFG['tbl_hit_count']['fields']['hits'] => 1));
return true;
}
}
private static function get_module($module)
{
return (!empty($module)) ? $module : self::$CI->router->fetch_module() ? self::$CI->router->fetch_module() : self::$CI->router->fetch_class();
}
private static function clean()
{
$interval = time() - self::$CFG['timeout'];
self::$CI->db
->where('time <', $interval)
->delete(self::$CFG['tbl_hit_log']['name']);
}
private function merge_config($a1, $a2)
{
foreach($a2 as $k => $v)
{
if(array_key_exists($k, $a1) && is_array($v))
$a1[$k] = self::merge_config($a1[$k], $a2[$k]);
else
$a1[$k] = $v;
}
return $a1;
}
}
$hit_config = array(
//Hits counter table
'tbl_hit_count' => array(
'name' => 'forum_comments',
'fields' => array(
'hits' =>'num_views',
'item_id' => 'id',
'module' => 'forum_id',
)
),
//Hits log table
'tbl_hit_log' => array(
'name' => 'hit_logs',
'fields' => array('hash'=>'hash', 'time' => 'time')
));
$this->load->library('Hcount', $hit_config);
Hcount::add($item_id, $module=false, $user_id=false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment