215 lines
6.5 KiB
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';
|
|
}
|
|
}
|