JezK
Edit File: WPHitsCounter.php
<?php class WPHitsCounter { var $pageId; var $pageTitle; var $postType; var $ipAddress; var $ipIsUnknown; var $userAgent; var $referer; var $refererSite; var $browser; var $searchEngine; var $countryInternetCode; var $countryId; var $keyWords; var $requestUri; var $resolvedCity = ''; var $resolvedRegion = ''; var $geoResolved = false; /** * Constructor * * @param integer $page_id * @param string $page_title Optional * @param string $post_type Optional */ public function __construct($page_id, $page_title = NULL, $post_type = NULL) { global $_SERVER; $this->ipAddress = ahcfree_get_client_ip_address(); if ($this->ipAddress == 'UNKNOWN') { $this->ipIsUnknown = true; $this->ipAddress = 'UNKNOWN' . uniqid(); } else { $this->ipIsUnknown = false; } $this->userAgent = ahc_free_sanitize_text_or_array_field($_SERVER['HTTP_USER_AGENT']); $this->pageId = (isset($page_id)) ? $page_id : ahc_free_sanitize_text_or_array_field($_GET['page_id']); $this->pageTitle = $page_title; $this->postType = $post_type; $this->requestUri = trim($_SERVER['REQUEST_URI'], '/'); //$post_permalink = get_the_permalink($this->pageId); //$protocol_arr = array('http://','https://','www.'); //$link = str_replace($protocol_arr,'',$post_permalink); //$this->requestUri = trim(str_replace($_SERVER['HTTP_HOST'],'',$link),'/'); if (isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER'])) { $hostName = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); if ($hostName != $_SERVER['SERVER_NAME']) { $this->referer = ahc_free_sanitize_text_or_array_field($_SERVER['HTTP_REFERER']); $this->refererSite = $hostName; } } $this->searchEngine = NULL; $this->keyWords = NULL; $this->countryId = NULL; } //-------------------------------------------- //-------------------------------------------- /** * Trace visitor hit * * @return void */ public function traceVisitorHit() { $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? ''; if (preg_match('/bot|crawl|slurp|spider|mediapartners/i', $user_agent)) { return; } //$this->cleanUnwantedRecords(); //$this->cleanHitsTable(); if (!$this->isHitRecorded()) { $visitorRecorded = $this->isVisitorRecorded(); $this->getBrowser(); $this->getCountryId(); if (!empty($this->refererSite)) { $this->getSearchEngine(); } /* if (!$this->isTodayPreparedInDb()) { $this->PrepareForTodayInDb(); }*/ if (!$visitorRecorded) { $this->updateVisitsTime(1, 1); $this->updateVisitors(1, 1); } else { $this->updateVisitsTime(0, 1); $this->updateVisitors(0, 1); } if (!empty($this->pageId) && !empty($this->pageTitle) && ($this->postType == 'post' or $this->postType == 'product' or $this->postType == 'page')) { $this->updateTitleTraffic($this->pageId, $this->pageTitle); } if (!empty($this->keyWords) && !empty($this->searchEngine)) { $this->updateKeywords($this->ipAddress, $this->keyWords, $this->referer, $this->searchEngine, $this->browser, $this->countryId); } if (!empty($this->refererSite)) { $this->updateReferingSites($this->refererSite); } if (!empty($this->searchEngine)) { $this->updateSearchingVisits($this->searchEngine); } if (!empty($this->countryId)) { if ($visitorRecorded) { $this->updateCountries($this->countryId, 0, 1); } else { $this->updateCountries($this->countryId, 1, 1); } } $this->updateBrowsers($this->browser); if (!$visitorRecorded) { $this->updateRecentVisitors($this->ipAddress, $this->referer, $this->searchEngine, $this->browser, $this->countryId); } $this->recordThisHits(); } } //-------------------------------------------- /** * Is visit is already recorded * * @return boolean */ protected function isHitRecorded() { global $wpdb; $custom_timezone_offset = ahcfree_get_current_timezone_offset(); $wpdb->insert( 'ahc_online_users', array( 'date' => ahcfree_localtime('Y-m-d H:i:s'), 'hit_ip_address' => $this->ipAddress, 'hit_page_id' => $this->pageId, 'site_id' => get_current_blog_id() ) ); //$sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(`hit_date`) = '". ahcfree_localtime("Y-m-d") ."' AND `hit_ip_address` = %s AND `hit_page_id` = %s"; $sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(CONVERT_TZ(CONCAT_WS(' ',hit_date,hit_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = '" . ahcfree_localtime("Y-m-d") . "' AND `hit_ip_address` = %s AND `hit_page_id` = %s AND `site_id` = %d "; $result = $wpdb->get_results($wpdb->prepare($sql, $this->ipAddress, $this->pageId, get_current_blog_id()), OBJECT); if ($result !== false) { return ((int) $result[0]->ct > 0); } } //-------------------------------------------- /** * Is visitor is already recorded * * @return boolean */ protected function isVisitorRecorded() { global $wpdb; $custom_timezone_offset = ahcfree_get_current_timezone_offset(); /*$sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(`hit_date`) = '". gmdate("Y-m-d") ."' AND `hit_ip_address` = %s";*/ $sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE site_id = " . get_current_blog_id() . " and DATE(CONVERT_TZ(CONCAT_WS(' ',hit_date,hit_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = '" . ahcfree_localtime("Y-m-d") . "' AND `hit_ip_address` = %s"; $result = $wpdb->get_results($wpdb->prepare($sql, $this->ipAddress), OBJECT); if ($result !== false) { return ((int) $result[0]->ct > 0); } } //-------------------------------------------- /** * Detect client browser * * @return void */ public function get_browser_id($browser) { global $wpdb; $sql = "SELECT `bsr_id` FROM `ahc_browsers` WHERE `bsr_name` = %s and site_id = %d "; $results = $wpdb->get_results($wpdb->prepare($sql, $browser, get_current_blog_id()), OBJECT); if ($results !== false && !empty($results)) { return $results[0]->bsr_id; } return 0; } protected function getBrowser() { if (strpos($this->userAgent, 'MSIE') !== false || strpos($this->userAgent, 'Trident') !== false) { // Internet Explorer $this->browser = $this->get_browser_id('IE'); } elseif (strpos($this->userAgent, 'Firefox') !== false) { // Firefox $this->browser = $this->get_browser_id('Firefox'); } elseif (strpos($this->userAgent, 'Chrome') !== false) { if (strpos($this->userAgent, 'Edg') !== false) { // Edge (based on Chromium) $this->browser = $this->get_browser_id('Edge'); } elseif (strpos($this->userAgent, 'OPR') !== false || strpos($this->userAgent, 'Opera') !== false) { // Opera (based on Chromium) $this->browser = $this->get_browser_id('Opera'); } else { // Chrome $this->browser = $this->get_browser_id('Chrome'); } } elseif (strpos($this->userAgent, 'Safari') !== false && strpos($this->userAgent, 'Chrome') === false) { // Safari (make sure it is not Chrome) $this->browser = $this->get_browser_id('Safari'); } elseif (strpos($this->userAgent, 'Opera Mini') !== false) { // Opera Mini $this->browser = $this->get_browser_id('Opera Mini'); } elseif (strpos($this->userAgent, 'Netscape') !== false) { // Netscape $this->browser = $this->get_browser_id('Netscape'); } elseif (strpos($this->userAgent, 'Gecko') !== false) { // Gecko/Mozilla $this->browser = $this->get_browser_id('Gecko/Mozilla'); } elseif (strpos($this->userAgent, 'iPad') !== false) { // iPad $this->browser = $this->get_browser_id('iPad'); } elseif (strpos($this->userAgent, 'Android') !== false) { // Android $this->browser = $this->get_browser_id('Android'); } elseif (strpos($this->userAgent, 'AIR') !== false) { // AIR $this->browser = $this->get_browser_id('AIR'); } elseif (strpos($this->userAgent, 'Fluid') !== false) { // Fluid $this->browser = $this->get_browser_id('Fluid'); } elseif (strpos($this->userAgent, 'Maxthon') !== false) { // Maxthon $this->browser = $this->get_browser_id('Maxthon'); } else { // Unknown $this->browser = $this->get_browser_id('unknown'); } } //-------------------------------------------- /** * Detect country internet code * * @return void */ protected function getCountryInternetCode() { if (!$this->ipIsUnknown) { // Resolve via the local GeoIP module (Cloudflare header -> permanent // DB cache -> local .mmdb -> optional single external fallback). // This replaces the old chain of up to 5 synchronous external API // calls per visitor, which was the cause of the server overload. if (function_exists('ahcfree_geo_lookup')) { $geo = ahcfree_geo_lookup($this->ipAddress); if (!empty($geo['country_code']) && strlen($geo['country_code']) === 2) { $this->countryInternetCode = $geo['country_code']; } // Stash city/region so updateRecentVisitors() reuses them // without performing a second lookup. $this->resolvedCity = isset($geo['city']) ? $geo['city'] : ''; $this->resolvedRegion = isset($geo['region']) ? $geo['region'] : ''; $this->geoResolved = true; } } if (empty($this->countryInternetCode)) { $this->countryInternetCode = 'XX'; } } //-------------------------------------------- /** * Detect country ID * * @uses wpdb::prepare() * @uses wpdb::get_results() * * @return void */ protected function getCountryId() { global $wpdb; $this->getCountryInternetCode(); if (!empty($this->countryInternetCode)) { $sql = "SELECT `ctr_id` FROM `ahc_countries` WHERE `ctr_internet_code` = %s and site_id = %d "; $results = $wpdb->get_results($wpdb->prepare($sql, $this->countryInternetCode, get_current_blog_id()), OBJECT); if ($results !== false && !empty($results)) { $this->countryId = $results[0]->ctr_id; return; } } } //-------------------------------------------- /** * Detect search engine * * @uses wpdb::prepare() * @uses wpdb::get_results() * * @return void */ protected function getSearchEngine() { global $wpdb; $sql = "SELECT `srh_id`, `srh_query_parameter`, `srh_identifier` FROM `ahc_search_engines`"; $results = $wpdb->get_results($sql, OBJECT); if ($results !== false) { foreach ($results as $s) { if (strpos($this->referer, $s->srh_identifier . '.') !== false) { $this->searchEngine = $s->srh_id; $this->getKeyWords($s->srh_query_parameter); } } } } //-------------------------------------------- /** * Detect search engine * * @uses wpdb::prepare() * @uses wpdb::get_results() * * @return void */ protected function getKeyWords($query_param) { $query = parse_url($this->referer, PHP_URL_QUERY); $query = rawurldecode($query); $arr = array(); parse_str($query, $arr); if (isset($arr[$query_param])) { $this->keyWords = $arr[$query_param]; } } //-------------------------------------------- /** * Is there a record prepared for today's visits * * @uses wpdb::get_results() * * @return boolean */ protected function isTodayPreparedInDb() { global $wpdb; $del_sql = "DELETE v1 FROM ahc_visitors v1, ahc_visitors v2 WHERE v1.`vst_id` > v2.`vst_id` AND v1.`vst_date` = v2.`vst_date`"; //$del_sql = "DELETE v1 FROM ahc_visitors v1, ahc_visitors v2 WHERE v1.`vst_id` > v2.`vst_id` AND CONVERT_TZ(v1.vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') = CONVERT_TZ(v2.vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') "; $del_result = $wpdb->get_results($del_sql, OBJECT); $sql = "SELECT COUNT(`vst_id`) AS ct FROM `ahc_visitors` WHERE site_id = " . get_current_blog_id() . " and DATE(`vst_date`) = '" . gmdate("Y-m-d") . "'"; //$sql = "SELECT COUNT(`vst_id`) AS ct FROM `ahc_visitors` WHERE DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(NOW( ),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'))"; $result = $wpdb->get_results($sql, OBJECT); if ($result !== false) { return ((int) $result[0]->ct > 0); } } //-------------------------------------------- /** * Prepared a record for today's visits * * @uses wpdb::query() * * @return boolean */ protected function PrepareForTodayInDb() { global $wpdb; $sql = "INSERT INTO `ahc_visitors` (`vst_date`, `vst_visitors`, `vst_visits`, `site_id`) VALUES ('" . gmdate("Y-m-d H:i:s") . "', 0, 0,'" . get_current_blog_id() . "')"; if ($wpdb->query($sql) !== false) { return true; } return false; } //-------------------------------------------- /** * Clean daily hits table * * @uses wpdb::query() * * @return boolean */ public function cleanHitsTable() { global $wpdb; // Get current time using saved timezone and calculate 90 days ago $current_time = $this->getCurrentLocalTime(); try { $timezone = new DateTimeZone($current_time['timezone']); $datetime = new DateTime('now', $timezone); $datetime->modify('-90 days'); $threshold_date = $datetime->format('Y-m-d H:i:s'); } catch (Exception $e) { // Fallback calculation using saved timezone $threshold_date = date('Y-m-d H:i:s', strtotime('-90 days')); } // Delete from ahc_online_users where date is older than 90 days $sql1 = $wpdb->prepare("DELETE FROM ahc_online_users WHERE `date` < %s", $threshold_date); $wpdb->query($sql1); // Delete from ahc_hits where hit_date is older than 90 days $sql2 = $wpdb->prepare("DELETE FROM `ahc_hits` WHERE `hit_date` < %s", $threshold_date); return ($wpdb->query($sql2) !== false); } //-------------------------------------------- /** * Update browser visits * * @uses wpdb::prepare() * @uses wpdb::query() * * @param integer $bsr_id * @return boolean */ protected function updateBrowsers($bsr_id) { global $wpdb; $sql = "UPDATE `ahc_browsers` SET bsr_visits = bsr_visits + 1 WHERE bsr_id = %d and site_id=%d"; if ($wpdb->query($wpdb->prepare($sql, $bsr_id, get_current_blog_id())) !== false) { return true; } return false; } //-------------------------------------------- /** * Update country visits * * @uses wpdb::prepare() * @uses wpdb::query() * * @param integer $ctr_id * @param integer $visitors Optional * @param integer $visits Optional * @return boolean */ protected function updateCountries($ctr_id, $visitors = 0, $visits = 0) { global $wpdb; $sql = "UPDATE `ahc_countries` SET ctr_visitors = ctr_visitors + %d, ctr_visits = ctr_visits + %d WHERE ctr_id = %d and site_id = %d"; return ($wpdb->query($wpdb->prepare($sql, $visitors, $visits, $ctr_id, get_current_blog_id())) !== false); } //-------------------------------------------- /** * Update visits sum order by search engine * * @uses wpdb::prepare() * @uses wpdb::get_results() * @uses wpdb::query() * * @param integer $srh_id * @return boolean */ protected function updateSearchingVisits($srh_id) { global $wpdb; // Get current time using saved timezone $current_time = $this->getCurrentLocalTime(); $custom_timezone_offset = ahcfree_get_current_timezone_offset(); $sql = "SELECT vtsh_id FROM `ahc_searching_visits` WHERE site_id = %d AND srh_id = %d AND DATE(vtsh_date) = '" . $current_time['date'] . "'"; $result = $wpdb->get_results($wpdb->prepare($sql, get_current_blog_id(), $srh_id), OBJECT); if ($result !== false) { if ($wpdb->num_rows > 0) { $sql2 = "UPDATE `ahc_searching_visits` SET vtsh_visits = vtsh_visits + 1 WHERE vtsh_id = %d and site_id=%d"; return ($wpdb->query($wpdb->prepare($sql2, $result[0]->vtsh_id, get_current_blog_id())) !== false); } else { $sql2 = "INSERT INTO `ahc_searching_visits` (srh_id, vtsh_date, vtsh_visits,site_id) VALUES (%d, %s, 1,%d)"; return ($wpdb->query($wpdb->prepare($sql2, $srh_id, $current_time['full'], get_current_blog_id())) !== false); // FIXED: Use saved timezone } } else { return false; } } //-------------------------------------------- /** * Update visitors count * * @uses wpdb::prepare() * @uses wpdb::query() * * @param integer $visitors Optional * @param integer $visits Optional * @return boolean */ protected function updateVisitors($visitors = 0, $visits = 0) { global $wpdb; // Get current time using saved timezone $current_time = $this->getCurrentLocalTime(); $sql = "INSERT INTO `ahc_daily_visitors_stats` (vst_date, vst_visitors, vst_visits,site_id) values(%s, %d, %d, %d )"; $wpdb->query($wpdb->prepare($sql, $current_time['full'], $visitors, $visits, get_current_blog_id())); // FIXED: Use saved timezone $sql = "INSERT INTO `ahc_visitors` (vst_date, vst_visitors, vst_visits,site_id) values(%s, %d, %d , %d )"; return ($wpdb->query($wpdb->prepare($sql, $current_time['full'], $visitors, $visits, get_current_blog_id())) !== false); // FIXED: Use saved timezone } //-------------------------------------------- /** * Update referring sites visits table * * @uses wpdb::prepare() * @uses wpdb::query() * @uses wpdb::get_results() * * @param string $rfr_site_name. referring site name * @return boolean */ protected function updateReferingSites($rfr_site_name) { global $wpdb; $sql = "SELECT rfr_id FROM `ahc_refering_sites` where rfr_site_name = %s and site_id=%d"; $result = $wpdb->get_results($wpdb->prepare($sql, $rfr_site_name, get_current_blog_id()), OBJECT); if ($result !== false) { if (!empty($result)) { $sql2 = "UPDATE `ahc_refering_sites` SET rfr_visits = rfr_visits + 1 WHERE rfr_id = %d and site_id=%d"; return ($wpdb->query($wpdb->prepare($sql2, $result[0]->rfr_id, get_current_blog_id())) !== false); } else { $sql2 = "INSERT INTO `ahc_refering_sites` (rfr_site_name, rfr_visits,site_id) VALUES(%s, 1,%d)"; return ($wpdb->query($wpdb->prepare($sql2, $rfr_site_name, get_current_blog_id())) !== false); } } else { return false; } } //-------------------------------------------- /** * Update recent visitors table * * @uses wpdb::prepare() * @uses wpdb::query() * * @param string $vtr_ip_address. IP address * @param string $vtr_referer Optional. Referring site name * @param integer $srh_id Optional. Search engine ID * @param integer $bsr_id Optional. Browser ID * @param integer $ctr_id Optional. Country ID * @return boolean */ protected function updateRecentVisitors($vtr_ip_address, $vtr_referer = '', $srh_id = NULL, $bsr_id = NULL, $ctr_id = NULL) { global $wpdb; // Get current time using saved timezone $current_time = $this->getCurrentLocalTime(); $ahc_city = ''; $ahc_region = ''; // Reuse the city/region already resolved in getCountryInternetCode() // via the local GeoIP module. This avoids a SECOND set of external // API calls per visitor (the old code called ipapi.co + ip-api.com // here on top of the country lookup, compounding the server load). if ($this->geoResolved) { $ahc_city = $this->resolvedCity; $ahc_region = $this->resolvedRegion; } elseif (function_exists('ahcfree_geo_lookup')) { $geo = ahcfree_geo_lookup($vtr_ip_address); $ahc_city = isset($geo['city']) ? $geo['city'] : ''; $ahc_region = isset($geo['region']) ? $geo['region'] : ''; } // Defensive cleanup of placeholder values. if ($ahc_city === 'null' || strlen($ahc_city) < 2) { $ahc_city = ''; } if ($ahc_region === 'null' || strlen($ahc_region) < 2) { $ahc_region = ''; } // Performance: Use prepared statement with proper placeholders $sql = "INSERT INTO `ahc_recent_visitors` (vtr_ip_address, vtr_referer, srh_id, bsr_id, ctr_id, ahc_city, ahc_region, vtr_date, vtr_time, site_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %d)"; return ($wpdb->query($wpdb->prepare( $sql, $vtr_ip_address, $vtr_referer, $srh_id, $bsr_id, $ctr_id, $ahc_city, $ahc_region, $current_time['date'], // FIXED: Use saved timezone instead of gmdate $current_time['time'], // FIXED: Use saved timezone instead of gmdate get_current_blog_id() )) !== false); } private function optimized_get_link($url, $timeout = 5) { // Performance: Check if we have a cached result (optional - implement if needed) $cache_key = 'geo_' . md5($url); $cached = wp_cache_get($cache_key, 'geolocation'); if ($cached !== false) { return $cached; } // Performance: Use WordPress HTTP API with optimized settings $args = array( 'timeout' => $timeout, 'redirection' => 2, // Limit redirects 'httpversion' => '1.1', 'user-agent' => 'Mozilla/5.0 (compatible; WordPressBotGeo/1.0)', 'headers' => array( 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip, deflate' ), 'compress' => true, 'decompress' => true, 'sslverify' => true // Security: verify SSL certificates ); $response = wp_remote_get($url, $args); // Performance: Quick error checking if (is_wp_error($response)) { throw new Exception('HTTP request failed: ' . $response->get_error_message()); } $response_code = wp_remote_retrieve_response_code($response); if ($response_code !== 200) { throw new Exception('HTTP error: ' . $response_code); } $body = wp_remote_retrieve_body($response); if (empty($body)) { throw new Exception('Empty response body'); } // Performance: Parse JSON response $data = json_decode($body); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('Invalid JSON response'); } // Performance: Cache successful results for 1 hour wp_cache_set($cache_key, $data, 'geolocation', 3600); return $data; } //-------------------------------------------- /** * Update key words table * * @uses wpdb::prepare() * @uses wpdb::query() * * @param string $vtr_ip_address. IP address * @param string $kwd_keywords. Key word * @param string $kwd_referer. Referring site name. * @param integer $srh_id. Search engine ID * @param integer $bsr_id. Browser ID * @param integer $ctr_id Optional. Country ID * @return boolean */ protected function updateKeywords($kwd_ip_address, $kwd_keywords, $kwd_referer, $srh_id, $bsr_id, $ctr_id = NULL) { global $wpdb; // Get current time using saved timezone $current_time = $this->getCurrentLocalTime(); $sql = "INSERT INTO `ahc_keywords` (kwd_ip_address, kwd_keywords, kwd_referer, srh_id, ctr_id, bsr_id, kwd_date, kwd_time,site_id) VALUES (%s, %s, %s, %d, %d, %d, %s, %s, %d)"; return ($wpdb->query($wpdb->prepare( $sql, $kwd_ip_address, $kwd_keywords, $kwd_referer, $srh_id, $ctr_id, $bsr_id, $current_time['date'], // FIXED: Use saved timezone instead of gmdate $current_time['time'], // FIXED: Use saved timezone instead of gmdate get_current_blog_id() )) !== false); } //-------------------------------------------- /** * Clean unwanted records. Only keeping a limit of fresh records. Limit is set by AHCFREE_RECENT_VISITORS_LIMIT * * @uses wpdb::prepare() * @uses wpdb::get_results() * @uses wpdb::query() * * @return boolean */ protected function cleanUnwantedRecords() { global $wpdb; $sql11 = "SELECT vtr_id FROM `ahc_recent_visitors` where site_id = %d ORDER BY vtr_id LIMIT %d"; $result = $wpdb->get_results($wpdb->prepare($sql11, get_current_blog_id(), AHCFREE_RECENT_VISITORS_LIMIT), OBJECT); if ($result !== false) { $ids1 = array(); $length = count($result); foreach ($result as $r) { $ids1[] = $r->vtr_id; } $ids1 = implode(',', $ids1); $sql12 = "DELETE FROM `ahc_recent_visitors`" . ((!empty($ids1)) ? " WHERE site_id = " . get_current_blog_id() . " and vtr_id NOT IN (" . $ids1 . ")" : ""); $sql21 = "SELECT kwd_id FROM `ahc_keywords` where site_id=%d ORDER BY kwd_id LIMIT %d"; $result2 = $wpdb->get_results($wpdb->prepare($sql21, get_current_blog_id(), AHCFREE_RECENT_KEYWORDS_LIMIT), OBJECT); if ($result2 !== false) { $ids2 = array(); foreach ($result2 as $r) { $ids2[] = $r->kwd_id; } $ids2 = implode(',', $ids2); $sql22 = "DELETE FROM `ahc_keywords`" . ((!empty($ids2)) ? " WHERE kwd_id NOT IN (" . $ids2 . ")" : ""); if ($wpdb->query($sql12) !== false) { return ($wpdb->query($sql22) !== false); } } } return false; } //-------------------------------------------- /** * Update traffic by title table * * @uses wpdb::prepare() * @uses wpdb::get_results() * @uses wpdb::query() * * @param integer $til_page_id * @param string $til_page_title * @return boolean */ protected function updateTitleTraffic($til_page_id, $til_page_title) { global $wpdb; $sql = "SELECT til_id FROM `ahc_title_traffic` where til_page_id = %s and site_id=%d"; $result = $wpdb->get_results($wpdb->prepare($sql, $til_page_id, get_current_blog_id()), OBJECT); if ($result !== false) { if (!empty($result)) { $sql2 = "UPDATE `ahc_title_traffic` SET til_hits = til_hits + 1, til_page_title = %s WHERE til_id = %d and site_id = %d"; return ($wpdb->query($wpdb->prepare($sql2, $til_page_title, $result[0]->til_id, get_current_blog_id())) !== false); } else { $sql2 = "INSERT INTO `ahc_title_traffic` (til_page_id, til_page_title, til_hits,site_id) VALUES(%s, %s, 1, %d)"; return ($wpdb->query($wpdb->prepare($sql2, $til_page_id, $til_page_title, get_current_blog_id())) !== false); } } else { return false; } } //-------------------------------------------- /** * Update visitor's & visits' times table * * @uses wpdb::prepare() * @uses wpdb::query() * * @param integer $visitors Optional * @param integer $visits Optional * @return boolean */ protected function updateVisitsTime($visitors = 0, $visits = 0) { global $wpdb; // Get current time using saved timezone $current_time = $this->getCurrentLocalTime(); $time = $current_time['time']; // FIXED: Use saved timezone instead of gmdate $sql = "UPDATE `ahc_visits_time` SET vtm_visitors = vtm_visitors + %d, vtm_visits = vtm_visits + %d WHERE TIME(vtm_time_from) <= '$time' AND TIME(vtm_time_to) >= '$time' and site_id=" . get_current_blog_id(); $query = $wpdb->prepare($sql, $visitors, $visits); $result = ($wpdb->query($query) !== false); $sql = "UPDATE `ahc_visits_time` SET vtm_visitors = 1 WHERE vtm_visitors = 0 AND TIME(vtm_time_from) <= '$time' AND TIME(vtm_time_to) >= '$time' and site_id=" . get_current_blog_id(); $query = $wpdb->query($sql); $sql = "UPDATE `ahc_visits_time` SET vtm_visits = 1 WHERE vtm_visits = 0 AND TIME(vtm_time_from) <= '$time' AND TIME(vtm_time_to) >= '$time' and site_id = " . get_current_blog_id(); $query = $wpdb->query($sql); return $result; } //-------------------------------------------- /** * Record (insert) the visit * * @uses wpdb::prepare() * @uses wpdb::query() * * @return boolean */ protected function recordThisHits() { global $wpdb; // Get current time using saved timezone $current_time = $this->getCurrentLocalTime(); $sql = "INSERT INTO `ahc_hits` (`hit_ip_address`, `hit_user_agent`, `hit_request_uri`, `hit_page_id`, `hit_page_title`, `ctr_id`, `hit_referer`, `hit_referer_site`, `srh_id`, `hit_search_words`, `bsr_id`, `hit_date`, `hit_time`, `site_id`) VALUES (%s, %s, %s, %s, %s, %d, %s, %s, %d, %s, %d, %s, %s, %d)"; $result = $wpdb->query($wpdb->prepare( $sql, $this->ipAddress, $this->userAgent, $this->requestUri, $this->pageId, $this->pageTitle, $this->countryId, $this->referer, $this->refererSite, $this->searchEngine, $this->keyWords, $this->browser, $current_time['date'], // FIXED: Use saved timezone instead of gmdate $current_time['time'], // FIXED: Use saved timezone instead of gmdate get_current_blog_id() )); return ($result !== false); } //-------------------------------------------- /** * Get current time in the site's configured timezone * This replaces the problematic gmdate() calls */ protected function getCurrentLocalTime() { // Always store in UTC to avoid double timezone conversion $utc_timezone = new DateTimeZone('UTC'); $datetime = new DateTime('now', $utc_timezone); $result = array( 'date' => $datetime->format('Y-m-d'), 'time' => $datetime->format('H:i:s'), 'full' => $datetime->format('Y-m-d H:i:s'), 'timezone' => 'UTC' ); //error_log('Storing in UTC: ' . json_encode($result)); return $result; } public static function schedule_cleanup() { if (!wp_next_scheduled('ahc_cleanup_event')) { wp_schedule_event(time() + 300, 'daily', 'ahc_cleanup_event'); } } public static function unschedule_cleanup() { $timestamp = wp_next_scheduled('ahc_cleanup_event'); if ($timestamp) { wp_unschedule_event($timestamp, 'ahc_cleanup_event'); } } public static function run_cleanup() { if (!isset($_SERVER['HTTP_USER_AGENT'])) $_SERVER['HTTP_USER_AGENT'] = 'wp-cron'; if (!isset($_SERVER['REQUEST_URI'])) $_SERVER['REQUEST_URI'] = '/wp-cron.php'; $counter = new self(0); $counter->cleanHitsTable(); } }