|
|
<?php
|
|
|
|
|
|
/**
|
|
|
* 外部访问统计
|
|
|
*
|
|
|
*/
|
|
|
class Website_analytics extends CI_Controller
|
|
|
{
|
|
|
|
|
|
private $sites;
|
|
|
|
|
|
/** 用于加密v_id的key, 解密也需要用 */
|
|
|
private $encrypt_key = "web_analytics_uoerwrhxxckjjlfdjfkdj";
|
|
|
|
|
|
function __construct()
|
|
|
{
|
|
|
parent::__construct();
|
|
|
// $this->output->enable_profiler(TRUE);
|
|
|
|
|
|
$this->load->model('Analytics_visits_model');
|
|
|
$this->load->model('Analytics_historys_model');
|
|
|
$this->load->model('Analytics_pages_model');
|
|
|
|
|
|
$this->load->model('Orders_model');
|
|
|
$this->load->model('Operator_model');
|
|
|
|
|
|
// 站点列表
|
|
|
$sites_config = $this->config->item('site');
|
|
|
foreach ($sites_config as $value)
|
|
|
{
|
|
|
$sites[] = $value['site_code'];
|
|
|
}
|
|
|
$this->sites = $sites;
|
|
|
}
|
|
|
|
|
|
// 记录客户端浏览信息
|
|
|
public function index($action = 'view')
|
|
|
{
|
|
|
return false;
|
|
|
$site_code = strtolower($this->input->get('site_code'));
|
|
|
$user_ip = $this->input->ip_address();
|
|
|
$page_title = $this->input->get('page_title');
|
|
|
$page_url = $this->input->server('HTTP_REFERER'); //因为是调用关系,所以它的来源页面才是访问页面
|
|
|
$page_referer = $this->input->get('page_referer');
|
|
|
|
|
|
// var_dump($page_url);
|
|
|
// 第一次访问出现的问题
|
|
|
// if(empty($page_url))
|
|
|
// {
|
|
|
// $page_url = $page_referer;
|
|
|
// }
|
|
|
|
|
|
$first_visit = FALSE;
|
|
|
|
|
|
// 测试 -- 关闭测试后删除下面两行
|
|
|
// $site_code = 'cht';
|
|
|
// $page_url = 'http://www.chinahighlights.ru/chongqing/att33343435n/';
|
|
|
// 判断站点
|
|
|
if (!in_array($site_code, $this->sites))
|
|
|
{
|
|
|
log_message('error', 'Invalid site_code: ' . $site_code);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 获取信息作者和页面ID
|
|
|
// $this->benchmark->mark('hash_page_start');
|
|
|
$page = $this->Analytics_pages_model->get_one_page($page_url, $site_code);
|
|
|
if (empty($page))
|
|
|
{
|
|
|
// 插入新的
|
|
|
$page_id = $this->Analytics_pages_model->add_add_return($site_code, $page_url, $page_title);
|
|
|
if (empty($page_id))
|
|
|
{
|
|
|
log_message('error', 'Cant insert new page url: ' . $page_url);
|
|
|
return;
|
|
|
}
|
|
|
// var_dump($page_id);
|
|
|
$page = $this->Analytics_pages_model->get_one($page_id);
|
|
|
// var_dump($page);
|
|
|
}
|
|
|
// var_dump($page);
|
|
|
// die();
|
|
|
// hash_page方法还没有直接查询快.. :(
|
|
|
// $page = $this->Page_model->get_hash_page($site_code, $page_url, $page_title);
|
|
|
// $this->benchmark->mark('hash_page_end');
|
|
|
// echo $this->benchmark->elapsed_time('hash_page_start', 'hash_page_end');
|
|
|
|
|
|
$page_id = $page->p_id;
|
|
|
$author = $page->p_author;
|
|
|
|
|
|
// 访客
|
|
|
// $this->_clear_user_key(); // 测试用
|
|
|
$user_key = $this->_get_user_key();
|
|
|
// 首访页面判断
|
|
|
if ($user_key === FALSE)
|
|
|
{
|
|
|
$first_visit = TRUE;
|
|
|
|
|
|
// 新增一个访客记录
|
|
|
$log_visit_id = $this->Analytics_visits_model->add($site_code, $page_id, $author, $user_ip, $page_referer);
|
|
|
if ($log_visit_id)
|
|
|
{
|
|
|
// 保存key
|
|
|
$user_key = $site_code . '_visit_' . passport_encrypt((string) $log_visit_id, $this->encrypt_key);
|
|
|
$this->_save_user_key($user_key);
|
|
|
} else
|
|
|
{
|
|
|
log_message('error', 'Cant get visitor id from cookie');
|
|
|
return;
|
|
|
}
|
|
|
} else
|
|
|
{
|
|
|
$log_visit_id = $this->_get_visit_id($user_key);
|
|
|
}
|
|
|
|
|
|
// 页面更新点击
|
|
|
$this->Analytics_pages_model->inc_view($page_id);
|
|
|
|
|
|
// 记录访问历史
|
|
|
$this->Analytics_historys_model->add($log_visit_id, $page_id, $page_referer);
|
|
|
|
|
|
// 更新最后点击页面
|
|
|
// 注: 每次都把当前访问页面当成离开页面是因为JS的unload和onbeforeunloa事件同样是每次刷新都请求.
|
|
|
// 独立出来还不如直接在访问的时候就写进去, 防止两次请求
|
|
|
$this->Analytics_visits_model->update_leave_page($log_visit_id, $site_code, $page_id);
|
|
|
|
|
|
// 匹配关联订单
|
|
|
$this->_do_order($site_code, $page_url);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 匹配关联订单
|
|
|
* @param type $site_code
|
|
|
* @param type $page_url
|
|
|
* @return type
|
|
|
*/
|
|
|
private function _do_order($site_code, $page_url)
|
|
|
{
|
|
|
//这一步做一个定时器,不需要每次访问都去检查关联
|
|
|
$this->load->driver('cache', array('adapter' => 'wincache', 'backup' => 'file')); // 线上
|
|
|
// $web_time = $this->cache->get($site_code . '_website_analytics_timer');
|
|
|
$web_time = FALSE;
|
|
|
// 有人下单才更新应该就可以了吧
|
|
|
// 缓存时间到, 或者访问页面包含thank或order 则更新关联
|
|
|
// strpos($page_url, 'thank') || strpos($page_url, 'order')
|
|
|
if ($web_time === false)
|
|
|
{
|
|
|
$this->cache->save($site_code . '_website_analytics_timer', time(), 900);
|
|
|
|
|
|
$confirm_line_list = $this->Orders_model->get_confirm_line_info($site_code);
|
|
|
// 测试数据
|
|
|
// $confirm_line_item['COLI_ID'] = '20121113';
|
|
|
// $confirm_line_item['COLI_WebCode'] = 'cht';
|
|
|
// $confirm_line_item['COLI_SenderIP'] = '202.103.68.62';
|
|
|
// $confirm_line_list[] = (object) $confirm_line_item;
|
|
|
//
|
|
|
if (!empty($confirm_line_list))
|
|
|
{
|
|
|
// 查询当天传统订单,把订单号和客人首访页面关联起来
|
|
|
foreach ($confirm_line_list as $confirm_line_item)
|
|
|
{
|
|
|
// 根据 site_code和ip获取当天的访客信息
|
|
|
$visit = $this->Analytics_visits_model->get_order_visit($confirm_line_item->COLI_WebCode, $confirm_line_item->COLI_SenderIP);
|
|
|
if ($visit && empty($visit->v_order_num))
|
|
|
{
|
|
|
// 绑定订单ID
|
|
|
$rs = $this->Analytics_visits_model->bing_order_num($visit->v_id, $confirm_line_item->COLI_ID);
|
|
|
if ($rs == TRUE)
|
|
|
{
|
|
|
$author = $this->Operator_model->get_user($visit->v_page_author);
|
|
|
// 发送通知Email
|
|
|
if ($author)
|
|
|
{
|
|
|
$data['author'] = $author;
|
|
|
$visit->v_order_num = $confirm_line_item->COLI_ID;
|
|
|
$data['view_log'] = $visit;
|
|
|
$mail_body = $this->load->view('analytics/email', $data, true);
|
|
|
$this->Orders_model->send_mail('YCC', 'ycc@chinahighlights.com', $author['OPI_Name'], $author['OPI_Email'], $this->lang->line('order_mail_title'), $mail_body);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}// end foreach 当天传统订单
|
|
|
}
|
|
|
|
|
|
// 查询当天商务订单,把订单号和客人首访页面关联起来
|
|
|
$biz_list = $this->Orders_model->get_biz_info($site_code);
|
|
|
if (!empty($biz_list))
|
|
|
{
|
|
|
foreach ($biz_list as $biz_item)
|
|
|
{
|
|
|
// 根据 site_code和ip获取当天的访客信息
|
|
|
$visit = $this->Analytics_visits_model->get_order_visit($biz_item->COLI_WebCode, $biz_item->COLI_SenderIP);
|
|
|
if ($visit && empty($visit->v_order_num))
|
|
|
{
|
|
|
// 绑定订单ID
|
|
|
$rs = $this->Analytics_visits_model->bing_order_num($visit->v_id, $biz_item->COLI_ID, 'b');
|
|
|
if ($rs == TRUE)
|
|
|
{
|
|
|
$author = $this->Operator_model->get_user($visit->v_page_author);
|
|
|
// 发送通知Email
|
|
|
if ($author)
|
|
|
{
|
|
|
$data['author'] = $author;
|
|
|
$visit->v_order_num = $biz_item->COLI_ID;
|
|
|
$data['view_log'] = $visit;
|
|
|
$mail_body = $this->load->view('analytics/email', $data, true);
|
|
|
$this->Orders_model->send_mail('YCC', 'ycc@chinahighlights.com', $author['OPI_Name'], $author['OPI_Email'], $this->lang->line('order_mail_title'), $mail_body);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
} // endforeach 当天商务订单
|
|
|
}
|
|
|
|
|
|
} // endif
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取用户key
|
|
|
*/
|
|
|
private function _get_user_key()
|
|
|
{
|
|
|
$analytics_cookie = $this->input->cookie('website_analytics');
|
|
|
if ($analytics_cookie)
|
|
|
{
|
|
|
return $analytics_cookie;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据用户KEY获取对应的log_visit_id
|
|
|
* @param type $user_key
|
|
|
* @return boolean
|
|
|
*/
|
|
|
private function _get_visit_id($user_key)
|
|
|
{
|
|
|
if (!$user_key)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
list($site, $log_visit_id) = explode('_visit_', $user_key);
|
|
|
$log_visit_id = passport_decrypt($log_visit_id, $this->encrypt_key);
|
|
|
// Cookie值出错 -- 客户端问题或者恶意修改cookie
|
|
|
if (!in_array($site, $this->sites) OR !$log_visit_id)
|
|
|
{
|
|
|
// 清空当前cookie指
|
|
|
$this->_clear_user_key();
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
$log_visit_id = intval($log_visit_id);
|
|
|
if (!$log_visit_id)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
return $log_visit_id;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* 生成或者获取用户key
|
|
|
*/
|
|
|
|
|
|
private function _save_user_key($key)
|
|
|
{
|
|
|
$analytics_cookie = array(
|
|
|
'name' => 'website_analytics',
|
|
|
'value' => $key,
|
|
|
'expire' => '865000', //秒,目前是10天
|
|
|
'domain' => '',
|
|
|
'path' => '/',
|
|
|
'prefix' => '',
|
|
|
);
|
|
|
$this->input->set_cookie($analytics_cookie);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 清空, 用于cookie可能出错的情况
|
|
|
*/
|
|
|
private function _clear_user_key()
|
|
|
{
|
|
|
$this->input->set_cookie('website_analytics', '');
|
|
|
}
|
|
|
|
|
|
function test()
|
|
|
{
|
|
|
return;
|
|
|
// $this->output->enable_profiler(TRUE);
|
|
|
// $confirm_line_list = $this->Orders_model->get_confirm_line_info('jp');
|
|
|
// var_dump($confirm_line_list);
|
|
|
// foreach ($confirm_line_list as $biz_item)
|
|
|
// {
|
|
|
// // 根据 site_code和ip获取当天的访客信息
|
|
|
// $visit = $this->Log_visit_model->get_order_visit($biz_item->COLI_WebCode, $biz_item->COLI_SenderIP);
|
|
|
// var_dump($visit);
|
|
|
// }
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 以下为加密解密函数 ==================================================
|
|
|
*/
|
|
|
function passport_encrypt($txt, $key)
|
|
|
{
|
|
|
srand((double) microtime() * 1000000);
|
|
|
$encrypt_key = md5(rand(0, 32000));
|
|
|
$ctr = 0;
|
|
|
$tmp = '';
|
|
|
for ($i = 0; $i < strlen($txt); $i++)
|
|
|
{
|
|
|
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
|
|
|
$tmp .= $encrypt_key[$ctr] . ($txt[$i] ^ $encrypt_key[$ctr++]);
|
|
|
}
|
|
|
return base64_encode(passport_key($tmp, $key));
|
|
|
}
|
|
|
|
|
|
function passport_decrypt($txt, $key)
|
|
|
{
|
|
|
$txt = passport_key(base64_decode($txt), $key);
|
|
|
$tmp = '';
|
|
|
for ($i = 0; $i < strlen($txt); $i++)
|
|
|
{
|
|
|
$md5 = $txt[$i];
|
|
|
$tmp .= $txt[++$i] ^ $md5;
|
|
|
}
|
|
|
return $tmp;
|
|
|
}
|
|
|
|
|
|
function passport_key($txt, $encrypt_key)
|
|
|
{
|
|
|
$encrypt_key = md5($encrypt_key);
|
|
|
$ctr = 0;
|
|
|
$tmp = '';
|
|
|
for ($i = 0; $i < strlen($txt); $i++)
|
|
|
{
|
|
|
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
|
|
|
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
|
|
|
}
|
|
|
return $tmp;
|
|
|
} |