Server : Apache/2.4.18 (Ubuntu) System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 User : oppastar ( 1041) PHP Version : 7.0.33-0ubuntu0.16.04.15 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, Directory : /var/www/laciasmara.com/public_html/shop/application/libraries/ |
Upload File : |
<?php defined('BASEPATH') or exit('No direct script access allowed'); class VisitorTracking { private $CI; private $session_key = 'initial_visitor_tracking'; private $utm_session_key = 'utm_data'; private $cookie_name = 'visitor_tracking'; private $cookie_expire = 2592000; // 30 days private $excluded_ips = []; public function __construct() { $this->CI = &get_instance(); $this->CI->load->database(); $this->CI->load->library('session'); $this->CI->load->library('user_agent'); $this->CI->load->helper(['url', 'cookie']); // Ensure session is started if (!$this->CI->session->userdata('session_id')) { $this->CI->session->set_userdata('session_id', session_id()); } // Migrate old session data if exists $this->migrateOldSessionData(); // Initialize session debugging $this->debugSession('Constructor called'); } private function migrateOldSessionData() { $old_tracking = $this->CI->session->userdata('visitor_tracking'); if ($old_tracking && !$this->CI->session->userdata($this->session_key)) { $this->CI->session->set_userdata($this->session_key, $old_tracking); $this->debugSession('Migrated old session data'); } } private function debugSession($message) { if (ENVIRONMENT === 'development') { log_message('debug', 'VisitorTracking: ' . $message . ' | Session ID: ' . session_id()); } } public function trackVisitor() { $this->debugSession('trackVisitor() method called'); try { $current_ip = $this->CI->input->ip_address(); if ($this->isExcludedIP($current_ip)) { $this->debugSession('IP excluded: ' . $current_ip); return false; } // Check UTM parameters first $utm_params = $this->getUTMParams(); $initial_tracking = $this->getInitialTracking(); // If there are UTM parameters, this should override the existing tracking if (!empty($utm_params['utm_source'])) { $initial_tracking = $this->createTrackingFromUTM($utm_params); } else { // No UTM parameters in current URL if (empty($initial_tracking)) { $initial_tracking = $this->createTrackingFromSource(); } } // Always track the pageview with the original source $this->trackPageview($initial_tracking); return $initial_tracking; } catch (Exception $e) { log_message('error', 'Error in trackVisitor: ' . $e->getMessage()); return false; } } private function getUTMParams() { return [ 'utm_source' => $this->CI->input->get('utm_source'), 'utm_medium' => $this->CI->input->get('utm_medium'), 'utm_campaign' => $this->CI->input->get('utm_campaign'), 'utm_content' => $this->CI->input->get('utm_content'), 'utm_term' => $this->CI->input->get('utm_term'), 'q' => $this->CI->input->get('q') ]; } private function getInitialTracking() { // Try session first $tracking = $this->CI->session->userdata($this->session_key); // If no session data, try cookie fallback if (empty($tracking)) { $cookie_data = get_cookie($this->cookie_name); if ($cookie_data) { $tracking = json_decode($cookie_data, true); if ($tracking) { // Restore to session $this->setTrackingData($tracking); $this->debugSession('Restored tracking from cookie'); } } } return $tracking; } private function createTrackingFromUTM($utm_params) { $source = [ 'utm_source' => $utm_params['utm_source'], 'utm_medium' => $utm_params['utm_medium'] ?? 'none', 'utm_campaign' => $utm_params['utm_campaign'] ?? 'none', 'utm_content' => $utm_params['utm_content'] ?? 'none', 'utm_term' => $utm_params['utm_term'] ?? 'none', 'utm_query' => $utm_params['q'] ]; $tracking_data = $this->createTrackingData($source); $this->setTrackingData($tracking_data); return $tracking_data; } private function createTrackingFromSource() { $source = $this->determineTrafficSource(); $tracking_data = $this->createTrackingData($source); $this->setTrackingData($tracking_data); return $tracking_data; } private function createTrackingData($source) { $tracking_id = uniqid('track_' . time() . '_'); return [ 'tracking_id' => $tracking_id, 'source' => $source['utm_source'], 'medium' => $source['utm_medium'], 'campaign' => $source['utm_campaign'], 'content' => $source['utm_content'], 'term' => $source['utm_term'], 'query' => $source['utm_query'], 'ip_address' => $this->CI->input->ip_address(), 'initial_url' => current_url(), 'timestamp' => time(), 'user_agent' => $this->CI->input->user_agent(), 'browser' => $this->CI->agent->browser(), 'browser_version' => $this->CI->agent->version(), 'platform' => $this->CI->agent->platform(), 'is_mobile' => $this->CI->agent->is_mobile(), 'is_robot' => $this->CI->agent->is_robot(), 'country' => $this->getCountryFromIP($this->CI->input->ip_address()), 'session_id' => session_id() ]; } private function setTrackingData($tracking_data) { // Set session data with multiple attempts $session_set = false; $attempts = 0; while (!$session_set && $attempts < 3) { $this->CI->session->set_userdata($this->session_key, $tracking_data); $this->CI->session->set_userdata('visitor_tracking', $tracking_data); // Verify session was set if ($this->CI->session->userdata($this->session_key)) { $session_set = true; $this->debugSession('Session data set successfully on attempt ' . ($attempts + 1)); } else { $attempts++; $this->debugSession('Session set failed, attempt ' . $attempts); usleep(100000); // Wait 100ms before retry } } // Cookie fallback $cookie_data = json_encode($tracking_data); set_cookie($this->cookie_name, $cookie_data, $this->cookie_expire); $this->debugSession('Cookie backup set'); // Set UTM data for consistency $utm_data = [ 'utm_source' => $tracking_data['source'], 'utm_medium' => $tracking_data['medium'], 'utm_campaign' => $tracking_data['campaign'], 'utm_content' => $tracking_data['content'] ]; $this->CI->session->set_userdata('data_utm', $utm_data); $this->CI->session->set_userdata($this->utm_session_key, $utm_data); } private function trackPageview($initial_tracking) { if (empty($initial_tracking)) { $this->debugSession('No initial tracking data for pageview'); return false; } $referral_code = $this->CI->session->userdata('referral'); $track_data = [ 'id' => uniqid('page_' . time() . '_'), 'tracking_id' => $initial_tracking['tracking_id'], 'link_url' => current_url(), 'source' => $initial_tracking['source'], 'ip_address' => $this->CI->input->ip_address(), 'user_agent' => $this->CI->input->user_agent(), 'referer' => $this->CI->input->server('HTTP_REFERER'), 'session_id' => session_id(), 'utm_source' => $initial_tracking['source'], 'utm_medium' => $initial_tracking['medium'], 'utm_campaign' => $initial_tracking['campaign'], 'utm_content' => $initial_tracking['content'], 'utm_term' => $initial_tracking['term'], 'search_query' => $initial_tracking['query'], 'referral_code' => $referral_code, 'browser' => $initial_tracking['browser'] ?? '', 'browser_version' => $initial_tracking['browser_version'] ?? '', 'platform' => $initial_tracking['platform'] ?? '', 'is_mobile' => $initial_tracking['is_mobile'] ?? false, 'is_robot' => $initial_tracking['is_robot'] ?? false, 'country' => $initial_tracking['country'] ?? '', 'created_at' => date('Y-m-d H:i:s') ]; $insert_result = $this->CI->db->insert('link_tracks', $track_data); if ($insert_result) { $this->debugSession('Successfully inserted tracking data'); } else { log_message('error', 'Failed to insert tracking data: ' . $this->CI->db->last_query()); } return $insert_result; } private function getCountryFromIP($ip) { // Simple IP to country detection (you can enhance this with GeoIP) if ($this->isExcludedIP($ip)) { return 'Local'; } // Basic country detection based on IP ranges (very simplified) // In production, use a proper GeoIP service return 'Unknown'; } private function isExcludedIP($ip) { $checkIpInRange = function ($ip, $range) { if (strpos($range, '/') !== false) { list($range, $netmask) = explode('/', $range, 2); $range_decimal = ip2long($range); $ip_decimal = ip2long($ip); $wildcard_decimal = pow(2, (32 - $netmask)) - 1; $netmask_decimal = ~$wildcard_decimal; return (($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal)); } else { return $ip === $range; } }; foreach ($this->excluded_ips as $excluded) { if ($checkIpInRange($ip, $excluded)) { return true; } } return false; } private function determineTrafficSource() { $source = [ 'utm_source' => 'direct', 'utm_medium' => 'none', 'utm_campaign' => 'none', 'utm_content' => 'none', 'utm_term' => 'none', 'utm_query' => null, 'raw_referer' => null ]; // Get UTM parameters $utm_params = $this->getUTMParams(); // If UTM parameters exist, use them if (!empty($utm_params['utm_source'])) { $source['utm_source'] = $utm_params['utm_source']; $source['utm_medium'] = $utm_params['utm_medium'] ?? 'none'; $source['utm_campaign'] = $utm_params['utm_campaign'] ?? 'none'; $source['utm_content'] = $utm_params['utm_content'] ?? 'none'; $source['utm_term'] = $utm_params['utm_term'] ?? 'none'; $source['utm_query'] = $utm_params['q']; return $source; } // Check for existing UTM data in session $session_utm = $this->CI->session->userdata($this->utm_session_key); if (!empty($session_utm)) { return $session_utm; } // If no UTM parameters, check referer $referer = $this->CI->input->server('HTTP_REFERER'); if ($referer) { $parsed_referer = parse_url($referer); $host = strtolower($parsed_referer['host'] ?? ''); $known_referrers = [ 'google' => ['source' => 'google', 'medium' => 'organic'], 'facebook.com' => ['source' => 'facebook', 'medium' => 'social'], 'instagram.com' => ['source' => 'instagram', 'medium' => 'social'], 'm.facebook.com' => ['source' => 'facebook', 'medium' => 'social'], 'm.instagram.com' => ['source' => 'instagram', 'medium' => 'social'], 'l.facebook.com' => ['source' => 'facebook', 'medium' => 'paid'], 'lm.facebook.com' => ['source' => 'facebook', 'medium' => 'paid'], 'l.instagram.com' => ['source' => 'instagram', 'medium' => 'paid'], 't.co' => ['source' => 'twitter', 'medium' => 'social'], 'twitter.com' => ['source' => 'twitter', 'medium' => 'social'], 'linkedin.com' => ['source' => 'linkedin', 'medium' => 'social'], 'youtube.com' => ['source' => 'youtube', 'medium' => 'social'], 'm.youtube.com' => ['source' => 'youtube', 'medium' => 'social'], 'youtu.be' => ['source' => 'youtube', 'medium' => 'social'], 'tiktok.com' => ['source' => 'tiktok', 'medium' => 'social'], 'vm.tiktok.com' => ['source' => 'tiktok', 'medium' => 'social'], 'm.tiktok.com' => ['source' => 'tiktok', 'medium' => 'social'] ]; foreach ($known_referrers as $domain => $props) { if (strpos($host, $domain) !== false) { $source['utm_source'] = $props['source']; $source['utm_medium'] = $props['medium']; break; } } if ($source['utm_source'] === 'direct' && !empty($host)) { $source['utm_source'] = $host; $source['utm_medium'] = 'referral'; } $source['raw_referer'] = $referer; } return $source; } // Public methods for accessing tracking data public function getTrackingData() { $tracking_data = $this->getInitialTracking(); $this->debugSession('Retrieved tracking data: ' . ($tracking_data ? 'found' : 'not found')); return $tracking_data; } public function getUTMData() { return $this->CI->session->userdata($this->utm_session_key); } public function clearTrackingData() { $this->CI->session->unset_userdata($this->session_key); $this->CI->session->unset_userdata('visitor_tracking'); $this->CI->session->unset_userdata($this->utm_session_key); $this->CI->session->unset_userdata('data_utm'); delete_cookie($this->cookie_name); $this->debugSession('Tracking data cleared'); } public function getSessionDebugInfo() { return [ 'session_id' => session_id(), 'session_data' => $this->CI->session->all_userdata(), 'cookie_data' => get_cookie($this->cookie_name), 'tracking_data' => $this->getTrackingData(), 'utm_data' => $this->getUTMData() ]; } // IP management methods public function addExcludedIP($ip) { if (!in_array($ip, $this->excluded_ips)) { $this->excluded_ips[] = $ip; } } public function getExcludedIPs() { return $this->excluded_ips; } public function removeExcludedIP($ip) { $key = array_search($ip, $this->excluded_ips); if ($key !== false) { unset($this->excluded_ips[$key]); } } }