Advanced third party cookie manager

This commit is contained in:
2025-04-09 01:25:08 +02:00
parent 20eacdf96c
commit be9d00565d
5 changed files with 811 additions and 39 deletions

View File

@ -18,7 +18,7 @@ class GdprCookieConsent extends Module
{
$this->name = 'gdprcookieconsent';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->version = '1.0.1';
$this->author = 'Walzen665';
$this->need_instance = 0;
$this->ps_versions_compliancy = [
@ -53,7 +53,11 @@ class GdprCookieConsent extends Module
Configuration::updateValue('GDPR_COOKIE_RETENTION_PERIOD', '365 days') &&
Configuration::updateValue('GDPR_COOKIE_THIRD_PARTIES', 'Google Analytics, Facebook, etc.') &&
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_THIRD_PARTIES') &&
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');
$manageText = Tools::getValue('GDPR_COOKIE_MANAGE_TEXT');
$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
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_MANAGE_TEXT', $manageText);
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
$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' => [
'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_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_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]);
}
@ -315,7 +363,12 @@ class GdprCookieConsent extends Module
$this->context->smarty->assign([
'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
if (file_exists(_PS_MODULE_DIR_ . $this->name . '/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'),
'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT'),
'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');
}
/**
* 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;
}
}