should_ignore_request()) { return; } if (! is_singular()) { return; } $post_id = get_queried_object_id(); if (! $post_id || 'publish' !== get_post_status($post_id)) { return; } if (is_user_logged_in()) { $settings = A360_Insights_Settings::get(); if (! empty($settings['exclude_logged_in_users'])) { return; } if (! empty($settings['exclude_administrators']) && current_user_can('manage_options')) { return; } } if (! A360_Insights_Settings::should_track_post($post_id)) { return; } A360_Insights_DB::insert_view($post_id, $this->source_data()); $tracked = true; } /** * Determine whether the current request should be ignored before tracking. * * @return bool */ private function should_ignore_request() { $settings = A360_Insights_Settings::get(); if (! empty($settings['exclude_cron']) && wp_doing_cron()) { return true; } if (! empty($settings['exclude_cli']) && defined('WP_CLI') && WP_CLI) { return true; } if (! empty($settings['ignore_prefetch']) && $this->is_prefetch_request()) { return true; } if (! empty($settings['exclude_bots']) && $this->is_bot_request()) { return true; } return false; } /** * Detect common browser prefetch, prerender and preview requests. * * @return bool */ private function is_prefetch_request() { $headers = array( 'HTTP_X_MOZ', 'HTTP_PURPOSE', 'HTTP_SEC_PURPOSE', 'HTTP_X_PURPOSE', ); foreach ($headers as $header) { if (empty($_SERVER[$header])) { continue; } $value = strtolower(sanitize_text_field(wp_unslash($_SERVER[$header]))); if (false !== strpos($value, 'prefetch') || false !== strpos($value, 'prerender') || false !== strpos($value, 'preview')) { return true; } } return false; } /** * Detect common bots, crawlers, link previewers and uptime monitors. * * @return bool */ private function is_bot_request() { if (empty($_SERVER['HTTP_USER_AGENT'])) { return false; } $user_agent = strtolower(sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT']))); if ('' === $user_agent) { return false; } $patterns = array( 'bot', 'crawler', 'spider', 'crawl', 'slurp', 'googlebot', 'bingbot', 'duckduckbot', 'baiduspider', 'yandex', 'sogou', 'exabot', 'facebot', 'facebookexternalhit', 'linkedinbot', 'twitterbot', 'pinterest', 'whatsapp', 'telegrambot', 'discordbot', 'skypeuripreview', 'vkshare', 'ahrefs', 'semrush', 'mj12bot', 'dotbot', 'petalbot', 'bytespider', 'uptimerobot', 'statuscake', 'pingdom', 'gtmetrix', 'pagespeed', 'lighthouse', 'headlesschrome', 'phantomjs', 'python-requests', 'curl/', 'wget/', 'httpclient', ); foreach ($patterns as $pattern) { if (false !== strpos($user_agent, $pattern)) { return true; } } return false; } /** * Source data. * * @return array */ private function source_data() { $settings = A360_Insights_Settings::get(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public read-only UTM tracking parameter. $utm_source = isset($_GET['utm_source']) && ! empty($settings['store_utm_parameters']) ? sanitize_text_field(wp_unslash($_GET['utm_source'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public read-only UTM tracking parameter. $utm_medium = isset($_GET['utm_medium']) && ! empty($settings['store_utm_parameters']) ? sanitize_text_field(wp_unslash($_GET['utm_medium'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public read-only UTM tracking parameter. $utm_campaign = isset($_GET['utm_campaign']) && ! empty($settings['store_utm_parameters']) ? sanitize_text_field(wp_unslash($_GET['utm_campaign'])) : ''; $referrer_url = isset($_SERVER['HTTP_REFERER']) && ! empty($settings['store_referrer_details']) ? esc_url_raw(wp_unslash($_SERVER['HTTP_REFERER'])) : ''; $referrer_host = $referrer_url ? wp_parse_url($referrer_url, PHP_URL_HOST) : ''; $referrer_host = is_string($referrer_host) ? strtolower(sanitize_text_field($referrer_host)) : ''; if ($referrer_host) { $source = $this->classify_referrer($referrer_host, $referrer_url); } elseif ($utm_source) { $source = $this->classify_source_value($utm_source); } else { $source = 'direct'; } if ('internal' === $source) { $source = 'direct'; $referrer_host = ''; $referrer_url = ''; } return array( 'source' => $source, 'referrer_host' => $referrer_host, 'referrer_url' => $referrer_url, 'utm_source' => $utm_source, 'utm_medium' => $utm_medium, 'utm_campaign' => $utm_campaign, ); } private function classify_source_value($value) { $value = strtolower(sanitize_text_field($value)); if (false !== strpos($value, 'codex')) { return 'codex'; } if (false !== strpos($value, 'chatgpt') || false !== strpos($value, 'openai')) { return 'chatgpt'; } if (false !== strpos($value, 'gemini') || false !== strpos($value, 'bard')) { return 'gemini'; } if (false !== strpos($value, 'copilot')) { return 'copilot'; } if (false !== strpos($value, 'perplexity')) { return 'perplexity'; } if (false !== strpos($value, 'claude') || false !== strpos($value, 'anthropic')) { return 'claude'; } if (false !== strpos($value, 'meta.ai') || false !== strpos($value, 'meta_ai')) { return 'meta_ai'; } if (false !== strpos($value, 'mistral') || false !== strpos($value, 'lechat')) { return 'mistral'; } if (false !== strpos($value, 'you.com') || 'you' === $value) { return 'you'; } if (false !== strpos($value, 'poe')) { return 'poe'; } if (false !== strpos($value, 'phind')) { return 'phind'; } if (false !== strpos($value, 'deepseek')) { return 'deepseek'; } if (false !== strpos($value, 'grok') || false !== strpos($value, 'x.ai')) { return 'grok'; } if (false !== strpos($value, 'google')) { return 'google'; } if (false !== strpos($value, 'bing')) { return 'bing'; } return sanitize_key($value); } /** * Classify referrer host. * * @param string $host Host. * @param string $url Full referrer URL. * @return string */ private function classify_referrer($host, $url = '') { $site_host = wp_parse_url(home_url(), PHP_URL_HOST); $site_host = is_string($site_host) ? strtolower(preg_replace('/^www\./', '', $site_host)) : ''; $host = strtolower(preg_replace('/^www\./', '', $host)); $path = $url ? wp_parse_url($url, PHP_URL_PATH) : ''; $path = is_string($path) ? strtolower($path) : ''; if ( $site_host && ( $host === $site_host || substr($host, -1 * (strlen($site_host) + 1)) === '.' . $site_host ) ) { return 'internal'; } if ( preg_match('/^codex\.openai\.com$/', $host) || ( preg_match('/(^|\.)chatgpt\.com$|(^|\.)openai\.com$/', $host) && false !== strpos($path, 'codex') ) ) { return 'codex'; } if (preg_match('/(^|\.)chatgpt\.com$|(^|\.)openai\.com$/', $host)) { return 'chatgpt'; } if (preg_match('/^gemini\.google\.com$|^bard\.google\.com$/', $host)) { return 'gemini'; } if (preg_match('/^copilot\.microsoft\.com$/', $host)) { return 'copilot'; } if (preg_match('/(^|\.)perplexity\.ai$/', $host)) { return 'perplexity'; } if (preg_match('/(^|\.)claude\.ai$|(^|\.)anthropic\.com$/', $host)) { return 'claude'; } if (preg_match('/(^|\.)meta\.ai$/', $host)) { return 'meta_ai'; } if (preg_match('/(^|\.)mistral\.ai$|(^|\.)chat\.mistral\.ai$/', $host)) { return 'mistral'; } if (preg_match('/(^|\.)you\.com$/', $host)) { return 'you'; } if (preg_match('/(^|\.)poe\.com$/', $host)) { return 'poe'; } if (preg_match('/(^|\.)phind\.com$/', $host)) { return 'phind'; } if (preg_match('/(^|\.)deepseek\.com$/', $host)) { return 'deepseek'; } if (preg_match('/(^|\.)grok\.com$|(^|\.)x\.ai$/', $host)) { return 'grok'; } if (preg_match('/(^|\.)google\./', $host)) { return 'google'; } if (preg_match('/(^|\.)facebook\.com$|(^|\.)fb\.com$|(^|\.)l\.facebook\.com$|(^|\.)m\.facebook\.com$/', $host)) { return 'facebook'; } if (preg_match('/(^|\.)youtube\.com$|(^|\.)youtu\.be$/', $host)) { return 'youtube'; } if (preg_match('/instagram\.com|x\.com|twitter\.com|linkedin\.com|tiktok\.com|pinterest\./', $host)) { return 'social'; } return 'referral'; } }