Compare commits
1 Commits
main
...
extend/thi
Author | SHA1 | Date | |
---|---|---|---|
be9d00565d |
214
classes/GdprScriptDetector.php
Normal file
214
classes/GdprScriptDetector.php
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
<?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';
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ class GdprCookieConsent extends Module
|
|||||||
{
|
{
|
||||||
$this->name = 'gdprcookieconsent';
|
$this->name = 'gdprcookieconsent';
|
||||||
$this->tab = 'front_office_features';
|
$this->tab = 'front_office_features';
|
||||||
$this->version = '1.0.0';
|
$this->version = '1.0.1';
|
||||||
$this->author = 'Walzen665';
|
$this->author = 'Walzen665';
|
||||||
$this->need_instance = 0;
|
$this->need_instance = 0;
|
||||||
$this->ps_versions_compliancy = [
|
$this->ps_versions_compliancy = [
|
||||||
@ -53,7 +53,11 @@ class GdprCookieConsent extends Module
|
|||||||
Configuration::updateValue('GDPR_COOKIE_RETENTION_PERIOD', '365 days') &&
|
Configuration::updateValue('GDPR_COOKIE_RETENTION_PERIOD', '365 days') &&
|
||||||
Configuration::updateValue('GDPR_COOKIE_THIRD_PARTIES', 'Google Analytics, Facebook, etc.') &&
|
Configuration::updateValue('GDPR_COOKIE_THIRD_PARTIES', 'Google Analytics, Facebook, etc.') &&
|
||||||
Configuration::updateValue('GDPR_COOKIE_MANAGE_TEXT', 'Manage Cookie Preferences') &&
|
Configuration::updateValue('GDPR_COOKIE_MANAGE_TEXT', 'Manage Cookie Preferences') &&
|
||||||
Configuration::updateValue('GDPR_COOKIE_ONLY_REQUIRED', 1);
|
Configuration::updateValue('GDPR_COOKIE_ONLY_REQUIRED', 1) &&
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_NECESSARY_DESC', 'Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas. The website cannot function properly without these cookies.') &&
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_FUNCTIONAL_DESC', 'Functional cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region you are in.') &&
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_ANALYTICS_DESC', 'Analytics cookies help website owners understand how visitors interact with websites by collecting and reporting information anonymously.') &&
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_MARKETING_DESC', 'Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +78,11 @@ class GdprCookieConsent extends Module
|
|||||||
Configuration::deleteByName('GDPR_COOKIE_RETENTION_PERIOD') &&
|
Configuration::deleteByName('GDPR_COOKIE_RETENTION_PERIOD') &&
|
||||||
Configuration::deleteByName('GDPR_COOKIE_THIRD_PARTIES') &&
|
Configuration::deleteByName('GDPR_COOKIE_THIRD_PARTIES') &&
|
||||||
Configuration::deleteByName('GDPR_COOKIE_MANAGE_TEXT') &&
|
Configuration::deleteByName('GDPR_COOKIE_MANAGE_TEXT') &&
|
||||||
Configuration::deleteByName('GDPR_COOKIE_ONLY_REQUIRED');
|
Configuration::deleteByName('GDPR_COOKIE_ONLY_REQUIRED') &&
|
||||||
|
Configuration::deleteByName('GDPR_COOKIE_NECESSARY_DESC') &&
|
||||||
|
Configuration::deleteByName('GDPR_COOKIE_FUNCTIONAL_DESC') &&
|
||||||
|
Configuration::deleteByName('GDPR_COOKIE_ANALYTICS_DESC') &&
|
||||||
|
Configuration::deleteByName('GDPR_COOKIE_MARKETING_DESC');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,6 +107,10 @@ class GdprCookieConsent extends Module
|
|||||||
$thirdParties = Tools::getValue('GDPR_COOKIE_THIRD_PARTIES');
|
$thirdParties = Tools::getValue('GDPR_COOKIE_THIRD_PARTIES');
|
||||||
$manageText = Tools::getValue('GDPR_COOKIE_MANAGE_TEXT');
|
$manageText = Tools::getValue('GDPR_COOKIE_MANAGE_TEXT');
|
||||||
$onlyRequired = Tools::getValue('GDPR_COOKIE_ONLY_REQUIRED');
|
$onlyRequired = Tools::getValue('GDPR_COOKIE_ONLY_REQUIRED');
|
||||||
|
$necessaryDesc = Tools::getValue('GDPR_COOKIE_NECESSARY_DESC');
|
||||||
|
$functionalDesc = Tools::getValue('GDPR_COOKIE_FUNCTIONAL_DESC');
|
||||||
|
$analyticsDesc = Tools::getValue('GDPR_COOKIE_ANALYTICS_DESC');
|
||||||
|
$marketingDesc = Tools::getValue('GDPR_COOKIE_MARKETING_DESC');
|
||||||
|
|
||||||
// Update configuration values
|
// Update configuration values
|
||||||
Configuration::updateValue('GDPR_COOKIE_ENABLED', $enabled);
|
Configuration::updateValue('GDPR_COOKIE_ENABLED', $enabled);
|
||||||
@ -113,6 +125,10 @@ class GdprCookieConsent extends Module
|
|||||||
Configuration::updateValue('GDPR_COOKIE_THIRD_PARTIES', $thirdParties);
|
Configuration::updateValue('GDPR_COOKIE_THIRD_PARTIES', $thirdParties);
|
||||||
Configuration::updateValue('GDPR_COOKIE_MANAGE_TEXT', $manageText);
|
Configuration::updateValue('GDPR_COOKIE_MANAGE_TEXT', $manageText);
|
||||||
Configuration::updateValue('GDPR_COOKIE_ONLY_REQUIRED', $onlyRequired);
|
Configuration::updateValue('GDPR_COOKIE_ONLY_REQUIRED', $onlyRequired);
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_NECESSARY_DESC', $necessaryDesc);
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_FUNCTIONAL_DESC', $functionalDesc);
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_ANALYTICS_DESC', $analyticsDesc);
|
||||||
|
Configuration::updateValue('GDPR_COOKIE_MARKETING_DESC', $marketingDesc);
|
||||||
|
|
||||||
// Display confirmation
|
// Display confirmation
|
||||||
$output .= $this->displayConfirmation($this->l('Settings updated'));
|
$output .= $this->displayConfirmation($this->l('Settings updated'));
|
||||||
@ -238,6 +254,34 @@ class GdprCookieConsent extends Module
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'type' => 'textarea',
|
||||||
|
'label' => $this->l('Necessary Cookies Description'),
|
||||||
|
'name' => 'GDPR_COOKIE_NECESSARY_DESC',
|
||||||
|
'desc' => $this->l('Description for necessary cookies shown in the modal'),
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type' => 'textarea',
|
||||||
|
'label' => $this->l('Functional Cookies Description'),
|
||||||
|
'name' => 'GDPR_COOKIE_FUNCTIONAL_DESC',
|
||||||
|
'desc' => $this->l('Description for functional cookies shown in the modal'),
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type' => 'textarea',
|
||||||
|
'label' => $this->l('Analytics Cookies Description'),
|
||||||
|
'name' => 'GDPR_COOKIE_ANALYTICS_DESC',
|
||||||
|
'desc' => $this->l('Description for analytics cookies shown in the modal'),
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type' => 'textarea',
|
||||||
|
'label' => $this->l('Marketing Cookies Description'),
|
||||||
|
'name' => 'GDPR_COOKIE_MARKETING_DESC',
|
||||||
|
'desc' => $this->l('Description for marketing cookies shown in the modal'),
|
||||||
|
'required' => true,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'submit' => [
|
'submit' => [
|
||||||
'title' => $this->l('Save'),
|
'title' => $this->l('Save'),
|
||||||
@ -277,6 +321,10 @@ class GdprCookieConsent extends Module
|
|||||||
$helper->fields_value['GDPR_COOKIE_THIRD_PARTIES'] = Configuration::get('GDPR_COOKIE_THIRD_PARTIES');
|
$helper->fields_value['GDPR_COOKIE_THIRD_PARTIES'] = Configuration::get('GDPR_COOKIE_THIRD_PARTIES');
|
||||||
$helper->fields_value['GDPR_COOKIE_MANAGE_TEXT'] = Configuration::get('GDPR_COOKIE_MANAGE_TEXT');
|
$helper->fields_value['GDPR_COOKIE_MANAGE_TEXT'] = Configuration::get('GDPR_COOKIE_MANAGE_TEXT');
|
||||||
$helper->fields_value['GDPR_COOKIE_ONLY_REQUIRED'] = Configuration::get('GDPR_COOKIE_ONLY_REQUIRED');
|
$helper->fields_value['GDPR_COOKIE_ONLY_REQUIRED'] = Configuration::get('GDPR_COOKIE_ONLY_REQUIRED');
|
||||||
|
$helper->fields_value['GDPR_COOKIE_NECESSARY_DESC'] = Configuration::get('GDPR_COOKIE_NECESSARY_DESC');
|
||||||
|
$helper->fields_value['GDPR_COOKIE_FUNCTIONAL_DESC'] = Configuration::get('GDPR_COOKIE_FUNCTIONAL_DESC');
|
||||||
|
$helper->fields_value['GDPR_COOKIE_ANALYTICS_DESC'] = Configuration::get('GDPR_COOKIE_ANALYTICS_DESC');
|
||||||
|
$helper->fields_value['GDPR_COOKIE_MARKETING_DESC'] = Configuration::get('GDPR_COOKIE_MARKETING_DESC');
|
||||||
|
|
||||||
return $helper->generateForm([$form]);
|
return $helper->generateForm([$form]);
|
||||||
}
|
}
|
||||||
@ -316,6 +364,11 @@ class GdprCookieConsent extends Module
|
|||||||
'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT', 'Manage Cookies'),
|
'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT', 'Manage Cookies'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// If not in required-only mode, add script for tagging known third-party scripts
|
||||||
|
if (!Configuration::get('GDPR_COOKIE_ONLY_REQUIRED')) {
|
||||||
|
$this->tagThirdPartyScripts();
|
||||||
|
}
|
||||||
|
|
||||||
// Return the template content - but don't throw an error if it doesn't exist yet
|
// Return the template content - but don't throw an error if it doesn't exist yet
|
||||||
if (file_exists(_PS_MODULE_DIR_ . $this->name . '/views/templates/hook/manage_button.tpl')) {
|
if (file_exists(_PS_MODULE_DIR_ . $this->name . '/views/templates/hook/manage_button.tpl')) {
|
||||||
return $this->display(__FILE__, 'views/templates/hook/manage_button.tpl');
|
return $this->display(__FILE__, 'views/templates/hook/manage_button.tpl');
|
||||||
@ -343,8 +396,80 @@ class GdprCookieConsent extends Module
|
|||||||
'gdprCookieThirdParties' => Configuration::get('GDPR_COOKIE_THIRD_PARTIES'),
|
'gdprCookieThirdParties' => Configuration::get('GDPR_COOKIE_THIRD_PARTIES'),
|
||||||
'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT'),
|
'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT'),
|
||||||
'gdprCookieOnlyRequired' => Configuration::get('GDPR_COOKIE_ONLY_REQUIRED'),
|
'gdprCookieOnlyRequired' => Configuration::get('GDPR_COOKIE_ONLY_REQUIRED'),
|
||||||
|
'gdprCookieNecessaryDesc' => Configuration::get('GDPR_COOKIE_NECESSARY_DESC'),
|
||||||
|
'gdprCookieFunctionalDesc' => Configuration::get('GDPR_COOKIE_FUNCTIONAL_DESC'),
|
||||||
|
'gdprCookieAnalyticsDesc' => Configuration::get('GDPR_COOKIE_ANALYTICS_DESC'),
|
||||||
|
'gdprCookieMarketingDesc' => Configuration::get('GDPR_COOKIE_MARKETING_DESC'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->display(__FILE__, 'views/templates/hook/footer.tpl');
|
return $this->display(__FILE__, 'views/templates/hook/footer.tpl');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to tag third-party scripts with appropriate consent categories
|
||||||
|
*/
|
||||||
|
protected function tagThirdPartyScripts()
|
||||||
|
{
|
||||||
|
// Require the script detector class
|
||||||
|
require_once(dirname(__FILE__).'/classes/GdprScriptDetector.php');
|
||||||
|
|
||||||
|
// Get PrestaShop's currently registered JS files
|
||||||
|
$jsFiles = $this->context->controller->js_files;
|
||||||
|
|
||||||
|
// Loop through JS files and add consent attributes based on patterns
|
||||||
|
foreach ($jsFiles as $key => $jsFile) {
|
||||||
|
// Use the detector class
|
||||||
|
$category = GdprScriptDetector::detectCategory($jsFile);
|
||||||
|
|
||||||
|
// Add attribute to the script
|
||||||
|
$this->context->smarty->assign([
|
||||||
|
'js_' . md5($jsFile) . '_attributes' => 'data-cookieconsent="' . $category . '"'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject a helper script to tag inline scripts as well
|
||||||
|
$this->context->controller->registerJavascript(
|
||||||
|
'gdpr-cookie-helper',
|
||||||
|
$this->_path . 'views/js/gdpr_cookie_helper.js',
|
||||||
|
['position' => 'head', 'priority' => 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies scripts in the HTML head
|
||||||
|
*/
|
||||||
|
public function hookActionHtmlHeadFooter($params)
|
||||||
|
{
|
||||||
|
if (!Configuration::get('GDPR_COOKIE_ENABLED') || Configuration::get('GDPR_COOKIE_ONLY_REQUIRED')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current HTML content
|
||||||
|
$html = $params['html_content'];
|
||||||
|
|
||||||
|
// Modify script tags to add data-cookieconsent attribute
|
||||||
|
$patterns = [
|
||||||
|
// Google Analytics pattern
|
||||||
|
'/<script([^>]*)(gtag|googletagmanager|google-analytics)([^>]*)>/' => '<script$1$2$3 data-cookieconsent="analytics">',
|
||||||
|
|
||||||
|
// Facebook Pixel pattern
|
||||||
|
'/<script([^>]*)(connect\.facebook\.net|fbevents\.js)([^>]*)>/' => '<script$1$2$3 data-cookieconsent="marketing">',
|
||||||
|
|
||||||
|
// Generic analytics patterns
|
||||||
|
'/<script([^>]*)(analytics|piwik|matomo|stats)([^>]*)>/' => '<script$1$2$3 data-cookieconsent="analytics">',
|
||||||
|
|
||||||
|
// Marketing patterns
|
||||||
|
'/<script([^>]*)(ads|adsbygoogle|doubleclick|googlesyndication)([^>]*)>/' => '<script$1$2$3 data-cookieconsent="marketing">',
|
||||||
|
|
||||||
|
// Functional patterns (more conservative, as these might be necessary)
|
||||||
|
'/<script([^>]*)(recaptcha|chat)([^>]*)>/' => '<script$1$2$3 data-cookieconsent="functional">',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($patterns as $pattern => $replacement) {
|
||||||
|
$html = preg_replace($pattern, $replacement, $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the HTML content
|
||||||
|
$params['html_content'] = $html;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Store for blocked scripts
|
||||||
|
const scriptStore = {
|
||||||
|
functional: [],
|
||||||
|
analytics: [],
|
||||||
|
marketing: []
|
||||||
|
};
|
||||||
|
|
||||||
// Cookie functions
|
// Cookie functions
|
||||||
function setCookie(name, value, days) {
|
function setCookie(name, value, days) {
|
||||||
var expires = '';
|
var expires = '';
|
||||||
@ -44,9 +51,161 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
showManageButton();
|
showManageButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Block scripts based on type
|
||||||
|
function blockScripts() {
|
||||||
|
// Find and process script tags with data-cookieconsent attribute
|
||||||
|
const scripts = document.querySelectorAll('script[data-cookieconsent]');
|
||||||
|
|
||||||
|
scripts.forEach(script => {
|
||||||
|
const consentType = script.getAttribute('data-cookieconsent');
|
||||||
|
|
||||||
|
if (!consentType || consentType === 'necessary') {
|
||||||
|
// Necessary scripts always run
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store script information
|
||||||
|
const scriptData = {
|
||||||
|
src: script.getAttribute('src'),
|
||||||
|
content: script.innerHTML,
|
||||||
|
type: script.getAttribute('type') || 'text/javascript',
|
||||||
|
async: script.async,
|
||||||
|
defer: script.defer
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add to appropriate store
|
||||||
|
if (scriptStore[consentType]) {
|
||||||
|
scriptStore[consentType].push(scriptData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the script from DOM
|
||||||
|
script.parentNode.removeChild(script);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also block iframe embeds with data-cookieconsent attribute
|
||||||
|
const iframes = document.querySelectorAll('iframe[data-cookieconsent]');
|
||||||
|
|
||||||
|
iframes.forEach(iframe => {
|
||||||
|
const consentType = iframe.getAttribute('data-cookieconsent');
|
||||||
|
|
||||||
|
if (!consentType || consentType === 'necessary') {
|
||||||
|
// Necessary iframes always load
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create placeholder
|
||||||
|
const placeholder = document.createElement('div');
|
||||||
|
placeholder.className = 'gdpr-blocked-content-placeholder';
|
||||||
|
placeholder.setAttribute('data-cookieconsent', consentType);
|
||||||
|
placeholder.setAttribute('data-src', iframe.getAttribute('src'));
|
||||||
|
placeholder.style.width = iframe.width + 'px' || '100%';
|
||||||
|
placeholder.style.height = iframe.height + 'px' || '150px';
|
||||||
|
placeholder.style.border = '1px dashed #ccc';
|
||||||
|
placeholder.style.display = 'flex';
|
||||||
|
placeholder.style.alignItems = 'center';
|
||||||
|
placeholder.style.justifyContent = 'center';
|
||||||
|
placeholder.style.backgroundColor = '#f9f9f9';
|
||||||
|
placeholder.style.color = '#666';
|
||||||
|
placeholder.innerHTML = `<div>
|
||||||
|
<p>Content blocked due to ${consentType} cookies preferences</p>
|
||||||
|
<button class="gdpr-load-blocked-content" data-type="${consentType}">Load content</button>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
// Replace iframe with placeholder
|
||||||
|
iframe.parentNode.replaceChild(placeholder, iframe);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add event listeners to load content buttons
|
||||||
|
document.querySelectorAll('.gdpr-load-blocked-content').forEach(button => {
|
||||||
|
button.addEventListener('click', function(e) {
|
||||||
|
const type = this.getAttribute('data-type');
|
||||||
|
const placeholder = this.closest('.gdpr-blocked-content-placeholder');
|
||||||
|
|
||||||
|
if (placeholder) {
|
||||||
|
// Get iframe src
|
||||||
|
const src = placeholder.getAttribute('data-src');
|
||||||
|
|
||||||
|
// Create iframe
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.src = src;
|
||||||
|
iframe.width = placeholder.style.width;
|
||||||
|
iframe.height = placeholder.style.height;
|
||||||
|
iframe.frameBorder = '0';
|
||||||
|
|
||||||
|
// Replace placeholder with iframe
|
||||||
|
placeholder.parentNode.replaceChild(iframe, placeholder);
|
||||||
|
|
||||||
|
// Update consent for this content type
|
||||||
|
const preferences = JSON.parse(getCookie('gdpr_cookie_consent') || '{"necessary":true}');
|
||||||
|
preferences[type] = true;
|
||||||
|
setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365);
|
||||||
|
|
||||||
|
// Update checkboxes in modal if it exists
|
||||||
|
const checkbox = document.querySelector(`#gdpr-cookie-${type}`);
|
||||||
|
if (checkbox) {
|
||||||
|
checkbox.checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load scripts based on consent
|
||||||
|
function loadConsentedScripts(preferences) {
|
||||||
|
// For each script type
|
||||||
|
Object.keys(scriptStore).forEach(type => {
|
||||||
|
if (preferences[type]) {
|
||||||
|
// Load all scripts of this type
|
||||||
|
scriptStore[type].forEach(scriptData => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
|
||||||
|
if (scriptData.src) {
|
||||||
|
script.src = scriptData.src;
|
||||||
|
}
|
||||||
|
|
||||||
|
script.type = scriptData.type;
|
||||||
|
script.async = scriptData.async;
|
||||||
|
script.defer = scriptData.defer;
|
||||||
|
|
||||||
|
if (scriptData.content) {
|
||||||
|
script.innerHTML = scriptData.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear the store for this type
|
||||||
|
scriptStore[type] = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also load blocked iframes
|
||||||
|
document.querySelectorAll('.gdpr-blocked-content-placeholder').forEach(placeholder => {
|
||||||
|
const type = placeholder.getAttribute('data-cookieconsent');
|
||||||
|
|
||||||
|
if (preferences[type]) {
|
||||||
|
// Get iframe src
|
||||||
|
const src = placeholder.getAttribute('data-src');
|
||||||
|
|
||||||
|
// Create iframe
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.src = src;
|
||||||
|
iframe.width = placeholder.style.width;
|
||||||
|
iframe.height = placeholder.style.height;
|
||||||
|
iframe.frameBorder = '0';
|
||||||
|
|
||||||
|
// Replace placeholder with iframe
|
||||||
|
placeholder.parentNode.replaceChild(iframe, placeholder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Check if cookie consent is already set
|
// Check if cookie consent is already set
|
||||||
var cookieConsent = getCookie('gdpr_cookie_consent');
|
var cookieConsent = getCookie('gdpr_cookie_consent');
|
||||||
|
|
||||||
|
// Always block non-necessary scripts first
|
||||||
|
blockScripts();
|
||||||
|
|
||||||
if (!cookieConsent) {
|
if (!cookieConsent) {
|
||||||
// Show the cookie banner if consent is not set
|
// Show the cookie banner if consent is not set
|
||||||
document.getElementById('gdpr-cookie-banner').style.display = 'block';
|
document.getElementById('gdpr-cookie-banner').style.display = 'block';
|
||||||
@ -163,8 +322,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyConsentPreferences(preferences) {
|
function applyConsentPreferences(preferences) {
|
||||||
// Example implementation
|
// Load consented scripts
|
||||||
// You would need to adapt this based on your specific cookie usage
|
loadConsentedScripts(preferences);
|
||||||
|
|
||||||
// Functional cookies
|
// Functional cookies
|
||||||
if (!preferences.functional) {
|
if (!preferences.functional) {
|
||||||
@ -194,31 +353,42 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Helper functions to implement consent preferences
|
// Helper functions to implement consent preferences
|
||||||
function removeFunctionalCookies() {
|
function removeFunctionalCookies() {
|
||||||
// This is just an example - implement based on your specific needs
|
// This is just an example - implement based on your specific needs
|
||||||
var functionalCookies = ['prefs', 'language', 'theme'];
|
var functionalCookies = ['prefs', 'language', 'theme', 'user_preferences'];
|
||||||
|
var domains = [window.location.hostname, '.' + window.location.hostname];
|
||||||
|
|
||||||
functionalCookies.forEach(function(cookie) {
|
functionalCookies.forEach(function(cookie) {
|
||||||
document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
domains.forEach(function(domain) {
|
||||||
|
document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableAnalytics() {
|
function disableAnalytics() {
|
||||||
// Example: Disable Google Analytics
|
// Google Analytics
|
||||||
window['ga-disable-UA-XXXXXXXX-X'] = true;
|
window['ga-disable-UA-XXXXXXXX-X'] = true;
|
||||||
|
window['ga-disable-G-XXXXXXXX'] = true;
|
||||||
|
|
||||||
// Remove existing GA cookies
|
// Remove existing GA cookies
|
||||||
document.cookie = '_ga=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=.' + window.location.hostname;
|
var analyticsCookies = ['_ga', '_gid', '_gat', '__utma', '__utmb', '__utmc', '__utmt', '__utmz', '_hjid', '_hjAbsoluteSessionInProgress'];
|
||||||
document.cookie = '_gid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=.' + window.location.hostname;
|
var domains = [window.location.hostname, '.' + window.location.hostname];
|
||||||
document.cookie = '_gat=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=.' + window.location.hostname;
|
|
||||||
|
analyticsCookies.forEach(function(cookie) {
|
||||||
|
domains.forEach(function(domain) {
|
||||||
|
document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableAnalytics() {
|
function enableAnalytics() {
|
||||||
// Example: Enable Google Analytics
|
// Google Analytics
|
||||||
window['ga-disable-UA-XXXXXXXX-X'] = false;
|
window['ga-disable-UA-XXXXXXXX-X'] = false;
|
||||||
|
window['ga-disable-G-XXXXXXXX'] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableMarketing() {
|
function disableMarketing() {
|
||||||
// Example implementation for common marketing cookies
|
// Common marketing cookies
|
||||||
var marketingCookies = ['_fbp', 'fr', 'IDE', 'MUID', 'personalization_id'];
|
var marketingCookies = ['_fbp', 'fr', 'IDE', 'MUID', 'personalization_id', 'VISITOR_INFO1_LIVE', 'YSC', 'NID'];
|
||||||
var domains = [window.location.hostname, '.' + window.location.hostname];
|
var domains = [window.location.hostname, '.' + window.location.hostname, '.google.com', '.facebook.com', '.youtube.com'];
|
||||||
|
|
||||||
marketingCookies.forEach(function(cookie) {
|
marketingCookies.forEach(function(cookie) {
|
||||||
domains.forEach(function(domain) {
|
domains.forEach(function(domain) {
|
||||||
@ -228,8 +398,60 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function enableMarketing() {
|
function enableMarketing() {
|
||||||
// For enabling marketing, we typically don't need to do anything special
|
// For enabling marketing, we load the scripts that were blocked
|
||||||
// The marketing scripts will set their cookies when they load
|
// This happens in the loadConsentedScripts function
|
||||||
// Just ensure the marketing scripts are loaded after checking consent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to detect which script is associated with each cookie category
|
||||||
|
function detectThirdPartyScripts() {
|
||||||
|
// This function would scan the page for known third-party scripts
|
||||||
|
// and auto-assign data-cookieconsent attributes
|
||||||
|
const knownScriptPatterns = {
|
||||||
|
analytics: [
|
||||||
|
/google-analytics\.com\/analytics\.js/i,
|
||||||
|
/googletagmanager\.com\/gtag/i,
|
||||||
|
/google-analytics\.com\/ga\.js/i,
|
||||||
|
/hotjar\.com/i,
|
||||||
|
/analytics/i,
|
||||||
|
/matomo/i,
|
||||||
|
/stats/i
|
||||||
|
],
|
||||||
|
marketing: [
|
||||||
|
/facebook\.net/i,
|
||||||
|
/doubleclick\.net/i,
|
||||||
|
/googlesyndication\.com/i,
|
||||||
|
/ads/i,
|
||||||
|
/adservices/i,
|
||||||
|
/pixel/i,
|
||||||
|
/track/i
|
||||||
|
],
|
||||||
|
functional: [
|
||||||
|
/recaptcha/i,
|
||||||
|
/fonts\.googleapis\.com/i,
|
||||||
|
/cloudflare/i,
|
||||||
|
/cdn/i,
|
||||||
|
/livechat/i,
|
||||||
|
/chat/i,
|
||||||
|
/support/i
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const scripts = document.querySelectorAll('script:not([data-cookieconsent])');
|
||||||
|
|
||||||
|
scripts.forEach(script => {
|
||||||
|
if (!script.src) return; // Skip inline scripts
|
||||||
|
|
||||||
|
for (const [category, patterns] of Object.entries(knownScriptPatterns)) {
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
if (pattern.test(script.src)) {
|
||||||
|
script.setAttribute('data-cookieconsent', category);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run script detection
|
||||||
|
detectThirdPartyScripts();
|
||||||
});
|
});
|
211
views/js/gdpr_cookie_helper.js
Normal file
211
views/js/gdpr_cookie_helper.js
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/**
|
||||||
|
* GDPR Cookie Consent Helper for PrestaShop
|
||||||
|
*
|
||||||
|
* @author Walzen665
|
||||||
|
* @copyright Copyright (c) 2025
|
||||||
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This script runs early in the page load to tag inline scripts with appropriate consent categories
|
||||||
|
(function() {
|
||||||
|
// Known script patterns to identify analytics, marketing and functional scripts
|
||||||
|
const scriptPatterns = {
|
||||||
|
analytics: [
|
||||||
|
/google[\s\-_]?analytics/i,
|
||||||
|
/ga\s*\(\s*['"]create/i,
|
||||||
|
/googletagmanager/i,
|
||||||
|
/gtag/i,
|
||||||
|
/\_gaq/i,
|
||||||
|
/matomo/i,
|
||||||
|
/piwik/i,
|
||||||
|
/mixpanel/i,
|
||||||
|
/hotjar/i,
|
||||||
|
/clarity/i
|
||||||
|
],
|
||||||
|
marketing: [
|
||||||
|
/facebook[\s\-_]?pixel/i,
|
||||||
|
/fbq\s*\(\s*['"]init/i,
|
||||||
|
/doubleclick/i,
|
||||||
|
/adwords/i,
|
||||||
|
/google[\s\-_]?ad[\s\-_]?services/i,
|
||||||
|
/google[\s\-_]?tag[\s\-_]?manager/i,
|
||||||
|
/gtm/i,
|
||||||
|
/twitter[\s\-_]?pixel/i,
|
||||||
|
/pinterest[\s\-_]?tag/i
|
||||||
|
],
|
||||||
|
functional: [
|
||||||
|
/recaptcha/i,
|
||||||
|
/chat/i,
|
||||||
|
/livechat/i,
|
||||||
|
/support/i,
|
||||||
|
/feedback/i,
|
||||||
|
/preference/i,
|
||||||
|
/usercentrics/i
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to process and tag a script element
|
||||||
|
function processScript(script) {
|
||||||
|
// Skip if it already has a consent attribute
|
||||||
|
if (script.hasAttribute('data-cookieconsent')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip our own scripts
|
||||||
|
if (script.src && script.src.indexOf('gdpr_cookie') !== -1) {
|
||||||
|
script.setAttribute('data-cookieconsent', 'necessary');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check content for patterns
|
||||||
|
const content = script.innerHTML || '';
|
||||||
|
const src = script.src || '';
|
||||||
|
|
||||||
|
// Determine script category
|
||||||
|
let category = 'necessary'; // Default category
|
||||||
|
|
||||||
|
for (const [cat, patterns] of Object.entries(scriptPatterns)) {
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
if (pattern.test(content) || pattern.test(src)) {
|
||||||
|
category = cat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category !== 'necessary') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag the script
|
||||||
|
script.setAttribute('data-cookieconsent', category);
|
||||||
|
|
||||||
|
// For non-necessary scripts, we'll create a duplicate with the correct attribute
|
||||||
|
// but disabled until consent is given
|
||||||
|
if (category !== 'necessary') {
|
||||||
|
const originalScript = script;
|
||||||
|
const newScript = document.createElement('script');
|
||||||
|
|
||||||
|
// Copy attributes
|
||||||
|
Array.from(originalScript.attributes).forEach(attr => {
|
||||||
|
if (attr.name !== 'data-cookieconsent') {
|
||||||
|
newScript.setAttribute(attr.name, attr.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set consent attribute
|
||||||
|
newScript.setAttribute('data-cookieconsent', category);
|
||||||
|
|
||||||
|
// Copy content if it's an inline script
|
||||||
|
if (!originalScript.src && originalScript.innerHTML) {
|
||||||
|
newScript.innerHTML = originalScript.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the original script
|
||||||
|
originalScript.parentNode.replaceChild(newScript, originalScript);
|
||||||
|
|
||||||
|
// Prevent execution by removing src and content
|
||||||
|
newScript.removeAttribute('src');
|
||||||
|
newScript.innerHTML = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process existing scripts
|
||||||
|
document.querySelectorAll('script').forEach(processScript);
|
||||||
|
|
||||||
|
// Use a MutationObserver to catch dynamically added scripts
|
||||||
|
const observer = new MutationObserver(mutations => {
|
||||||
|
mutations.forEach(mutation => {
|
||||||
|
mutation.addedNodes.forEach(node => {
|
||||||
|
if (node.tagName === 'SCRIPT') {
|
||||||
|
processScript(node);
|
||||||
|
} else if (node.querySelectorAll) {
|
||||||
|
node.querySelectorAll('script').forEach(processScript);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start observing the document
|
||||||
|
observer.observe(document.documentElement, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also process iframes
|
||||||
|
function processIframe(iframe) {
|
||||||
|
// Skip if it already has a consent attribute
|
||||||
|
if (iframe.hasAttribute('data-cookieconsent')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const src = iframe.src || '';
|
||||||
|
|
||||||
|
// Common third-party iframe sources
|
||||||
|
const iframePatterns = {
|
||||||
|
marketing: [
|
||||||
|
/youtube/i,
|
||||||
|
/vimeo/i,
|
||||||
|
/facebook\.com\/plugins/i,
|
||||||
|
/twitter\.com\/widgets/i,
|
||||||
|
/instagram\.com/i,
|
||||||
|
/pinterest\.com/i,
|
||||||
|
/doubleclick/i,
|
||||||
|
/ads/i
|
||||||
|
],
|
||||||
|
analytics: [
|
||||||
|
/googletagmanager/i,
|
||||||
|
/analytics/i
|
||||||
|
],
|
||||||
|
functional: [
|
||||||
|
/recaptcha/i,
|
||||||
|
/maps\.google/i,
|
||||||
|
/google\.com\/maps/i,
|
||||||
|
/disqus/i,
|
||||||
|
/livechat/i,
|
||||||
|
/chat/i
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Determine iframe category
|
||||||
|
let category = 'necessary'; // Default category
|
||||||
|
|
||||||
|
for (const [cat, patterns] of Object.entries(iframePatterns)) {
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
if (pattern.test(src)) {
|
||||||
|
category = cat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category !== 'necessary') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag the iframe
|
||||||
|
iframe.setAttribute('data-cookieconsent', category);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process existing iframes
|
||||||
|
document.querySelectorAll('iframe').forEach(processIframe);
|
||||||
|
|
||||||
|
// Use the observer to catch dynamically added iframes
|
||||||
|
const iframeObserver = new MutationObserver(mutations => {
|
||||||
|
mutations.forEach(mutation => {
|
||||||
|
mutation.addedNodes.forEach(node => {
|
||||||
|
if (node.tagName === 'IFRAME') {
|
||||||
|
processIframe(node);
|
||||||
|
} else if (node.querySelectorAll) {
|
||||||
|
node.querySelectorAll('iframe').forEach(processIframe);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start observing for iframes
|
||||||
|
iframeObserver.observe(document.documentElement, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true
|
||||||
|
});
|
||||||
|
})();
|
@ -25,23 +25,23 @@
|
|||||||
<div class="gdpr-cookie-category">
|
<div class="gdpr-cookie-category">
|
||||||
<input type="checkbox" id="gdpr-cookie-necessary" checked disabled>
|
<input type="checkbox" id="gdpr-cookie-necessary" checked disabled>
|
||||||
<label for="gdpr-cookie-necessary">{l s='Necessary' mod='gdprcookieconsent'}</label>
|
<label for="gdpr-cookie-necessary">{l s='Necessary' mod='gdprcookieconsent'}</label>
|
||||||
<p>{l s='Necessary cookies help make a website usable by enabling basic functions like page navigation. The website cannot function properly without these cookies.' mod='gdprcookieconsent'}</p>
|
<p>{$gdprCookieNecessaryDesc}</p>
|
||||||
</div>
|
</div>
|
||||||
{if !$gdprCookieOnlyRequired}
|
{if !$gdprCookieOnlyRequired}
|
||||||
<div class="gdpr-cookie-category">
|
<div class="gdpr-cookie-category">
|
||||||
<input type="checkbox" id="gdpr-cookie-functional" class="gdpr-cookie-checkbox" data-cookie-category="functional">
|
<input type="checkbox" id="gdpr-cookie-functional" class="gdpr-cookie-checkbox" data-cookie-category="functional">
|
||||||
<label for="gdpr-cookie-functional">{l s='Functional' mod='gdprcookieconsent'}</label>
|
<label for="gdpr-cookie-functional">{l s='Functional' mod='gdprcookieconsent'}</label>
|
||||||
<p>{l s='Functional cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region you are in.' mod='gdprcookieconsent'}</p>
|
<p>{$gdprCookieFunctionalDesc}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="gdpr-cookie-category">
|
<div class="gdpr-cookie-category">
|
||||||
<input type="checkbox" id="gdpr-cookie-analytics" class="gdpr-cookie-checkbox" data-cookie-category="analytics">
|
<input type="checkbox" id="gdpr-cookie-analytics" class="gdpr-cookie-checkbox" data-cookie-category="analytics">
|
||||||
<label for="gdpr-cookie-analytics">{l s='Analytics' mod='gdprcookieconsent'}</label>
|
<label for="gdpr-cookie-analytics">{l s='Analytics' mod='gdprcookieconsent'}</label>
|
||||||
<p>{l s='Analytics cookies help website owners understand how visitors interact with websites by collecting and reporting information anonymously.' mod='gdprcookieconsent'}</p>
|
<p>{$gdprCookieAnalyticsDesc}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="gdpr-cookie-category">
|
<div class="gdpr-cookie-category">
|
||||||
<input type="checkbox" id="gdpr-cookie-marketing" class="gdpr-cookie-checkbox" data-cookie-category="marketing">
|
<input type="checkbox" id="gdpr-cookie-marketing" class="gdpr-cookie-checkbox" data-cookie-category="marketing">
|
||||||
<label for="gdpr-cookie-marketing">{l s='Marketing' mod='gdprcookieconsent'}</label>
|
<label for="gdpr-cookie-marketing">{l s='Marketing' mod='gdprcookieconsent'}</label>
|
||||||
<p>{l s='Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user.' mod='gdprcookieconsent'}</p>
|
<p>{$gdprCookieMarketingDesc}</p>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user