gdprcookieconsent/classes/GdprScriptDetector.php

215 lines
6.5 KiB
PHP

<?php
/**
* GDPR Cookie Consent Module for PrestaShop
*
* @author Walzen665
* @copyright Copyright (c) 2025
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
*/
if (!defined('_PS_VERSION_')) {
exit;
}
/**
* Helper class for detecting third-party scripts and assigning them to cookie categories
*/
class GdprScriptDetector
{
// Common script signatures and their cookie categories
private static $scriptPatterns = [
'analytics' => [
'/google-analytics\.com/i',
'/googletagmanager\.com/i',
'/gtag/i',
'/analytics/i',
'/matomo/i',
'/piwik/i',
'/statcounter/i',
'/hotjar/i',
'/clarity\.ms/i',
'/stats/i'
],
'marketing' => [
'/facebook\.net/i',
'/connect\.facebook\.com/i',
'/fbevents\.js/i',
'/doubleclick\.net/i',
'/googlesyndication\.com/i',
'/google.*ads/i',
'/twitter\.com\/widgets/i',
'/platform\.twitter\.com/i',
'/pixel/i',
'/ads/i',
'/adservice/i',
'/criteo/i',
'/pinterest/i',
'/taboola/i',
'/outbrain/i'
],
'functional' => [
'/recaptcha/i',
'/hcaptcha/i',
'/fonts\.googleapis\.com/i',
'/cloudflare/i',
'/unpkg\.com/i',
'/cdn/i',
'/chat/i',
'/live.*/i',
'/support/i',
'/feedback/i',
'/maps\.google/i',
'/disqus/i',
'/zendesk/i',
'/intercom/i'
]
];
/**
* Check if a script URL or content matches any pattern
*
* @param string $scriptText The script URL or content to check
* @return string The cookie category ('necessary', 'functional', 'analytics', 'marketing')
*/
public static function detectCategory($scriptText)
{
foreach (self::$scriptPatterns as $category => $patterns) {
foreach ($patterns as $pattern) {
if (preg_match($pattern, $scriptText)) {
return $category;
}
}
}
return 'necessary'; // Default category if no match found
}
/**
* Get common third-party domains and their categories
*
* @return array Associative array of domains and their categories
*/
public static function getCommonThirdPartyDomains()
{
return [
// Analytics
'google-analytics.com' => 'analytics',
'googletagmanager.com' => 'analytics',
'analytics.google.com' => 'analytics',
'matomo.org' => 'analytics',
'matomo.cloud' => 'analytics',
'piwik.pro' => 'analytics',
'statcounter.com' => 'analytics',
'hotjar.com' => 'analytics',
'clarity.ms' => 'analytics',
'mixpanel.com' => 'analytics',
// Marketing
'facebook.com' => 'marketing',
'facebook.net' => 'marketing',
'fbcdn.net' => 'marketing',
'doubleclick.net' => 'marketing',
'googlesyndication.com' => 'marketing',
'adservice.google.com' => 'marketing',
'twitter.com' => 'marketing',
'linkedin.com' => 'marketing',
'pinterest.com' => 'marketing',
'ads-twitter.com' => 'marketing',
'criteo.com' => 'marketing',
'criteo.net' => 'marketing',
'taboola.com' => 'marketing',
'outbrain.com' => 'marketing',
// Functional
'google.com/recaptcha' => 'functional',
'gstatic.com/recaptcha' => 'functional',
'hcaptcha.com' => 'functional',
'fonts.googleapis.com' => 'functional',
'cloudflare.com' => 'functional',
'cdn.jsdelivr.net' => 'functional',
'unpkg.com' => 'functional',
'cdnjs.cloudflare.com' => 'functional',
'maps.google.com' => 'functional',
'maps.googleapis.com' => 'functional',
'disqus.com' => 'functional',
'zendesk.com' => 'functional',
'intercom.io' => 'functional'
];
}
/**
* Check if a domain matches any known third-party domain
*
* @param string $domain The domain to check
* @return string|false The cookie category or false if no match
*/
public static function matchDomain($domain)
{
$thirdPartyDomains = self::getCommonThirdPartyDomains();
foreach ($thirdPartyDomains as $thirdPartyDomain => $category) {
if (strpos($domain, $thirdPartyDomain) !== false) {
return $category;
}
}
return false;
}
/**
* Detect inline script content category
*
* @param string $content The script content to analyze
* @return string The cookie category
*/
public static function detectInlineScriptCategory($content)
{
// Common script signatures in inline scripts
$inlinePatterns = [
'analytics' => [
'/googleAnalytics/i',
'/gtag\s*\(/i',
'/_gaq\s*\./i',
'/ga\s*\(\s*[\'"]create/i',
'/analytics/i',
'/matomo/i',
'/piwik/i',
'/hotjar/i',
'/clarity/i'
],
'marketing' => [
'/fbq\s*\(/i',
'/FB\.init/i',
'/facebook-jssdk/i',
'/twttr\s*\./i',
'/twitter-widgets/i',
'/pintrk/i',
'/adsbygoogle/i',
'/googletag/i',
'/pixel/i',
'/track/i'
],
'functional' => [
'/grecaptcha/i',
'/hcaptcha/i',
'/maps\.googleapis/i',
'/gapi\.load/i',
'/disqus/i',
'/LiveChat/i',
'/intercom/i',
'/zendesk/i'
]
];
foreach ($inlinePatterns as $category => $patterns) {
foreach ($patterns as $pattern) {
if (preg_match($pattern, $content)) {
return $category;
}
}
}
return 'necessary';
}
}