From 5172966eb26b6bc1464b149b539af83d071e6372 Mon Sep 17 00:00:00 2001 From: Walz Date: Mon, 7 Apr 2025 17:12:31 +0200 Subject: [PATCH] Improved GDPR compliance - Add more customization TODO: Update styling --- gdprcookieconsent.php | 75 ++++++++++++++++++++++++-- views/css/gdpr_cookie.css | 69 ++++++++++++++++++++++++ views/js/gdpr_cookie.js | 53 ++++++++++++++---- views/templates/hook/footer.tpl | 15 ++++++ views/templates/hook/manage_button.tpl | 11 ++++ 5 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 views/templates/hook/manage_button.tpl diff --git a/gdprcookieconsent.php b/gdprcookieconsent.php index 1f6d4b5..fdd337f 100644 --- a/gdprcookieconsent.php +++ b/gdprcookieconsent.php @@ -1,4 +1,5 @@ registerHook('displayHeader') && $this->registerHook('displayFooter') && Configuration::updateValue('GDPR_COOKIE_ENABLED', 1) && - Configuration::updateValue('GDPR_COOKIE_MESSAGE', 'This website uses cookies to ensure you get the best experience on our website.') && + Configuration::updateValue('GDPR_COOKIE_MESSAGE', 'This website uses cookies to ensure you get the best experience. We collect and process your data for website functionality, analytics, and personalized advertising.') && Configuration::updateValue('GDPR_COOKIE_ACCEPT', 'Accept All Cookies') && - Configuration::updateValue('GDPR_COOKIE_DECLINE', 'Decline') && + Configuration::updateValue('GDPR_COOKIE_DECLINE', 'Decline Non-Essential') && Configuration::updateValue('GDPR_COOKIE_SETTINGS', 'Cookie Settings') && Configuration::updateValue('GDPR_COOKIE_MORE_INFO', 'More Information') && - Configuration::updateValue('GDPR_COOKIE_MORE_INFO_URL', 'content/2-privacy-policy'); + Configuration::updateValue('GDPR_COOKIE_MORE_INFO_URL', 'content/2-privacy-policy') && + // New configuration values + Configuration::updateValue('GDPR_COOKIE_DATA_CONTROLLER', 'Your Company Name') && + 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'); } + /** * Uninstall the module */ @@ -62,7 +69,12 @@ class GdprCookieConsent extends Module Configuration::deleteByName('GDPR_COOKIE_DECLINE') && Configuration::deleteByName('GDPR_COOKIE_SETTINGS') && Configuration::deleteByName('GDPR_COOKIE_MORE_INFO') && - Configuration::deleteByName('GDPR_COOKIE_MORE_INFO_URL'); + Configuration::deleteByName('GDPR_COOKIE_MORE_INFO_URL') && + // New configuration values + Configuration::deleteByName('GDPR_COOKIE_DATA_CONTROLLER') && + Configuration::deleteByName('GDPR_COOKIE_RETENTION_PERIOD') && + Configuration::deleteByName('GDPR_COOKIE_THIRD_PARTIES') && + Configuration::deleteByName('GDPR_COOKIE_MANAGE_TEXT'); } /** @@ -137,6 +149,27 @@ class GdprCookieConsent extends Module 'name' => 'GDPR_COOKIE_MESSAGE', 'required' => true, ], + [ + 'type' => 'text', + 'label' => $this->l('Data Controller'), + 'name' => 'GDPR_COOKIE_DATA_CONTROLLER', + 'desc' => $this->l('Your company/organization name'), + 'required' => true, + ], + [ + 'type' => 'text', + 'label' => $this->l('Cookie Retention Period'), + 'name' => 'GDPR_COOKIE_RETENTION_PERIOD', + 'desc' => $this->l('How long cookies will be stored (e.g., 365 days)'), + 'required' => true, + ], + [ + 'type' => 'textarea', + 'label' => $this->l('Third-Party Recipients'), + 'name' => 'GDPR_COOKIE_THIRD_PARTIES', + 'desc' => $this->l('List third parties that receive cookie data'), + 'required' => true, + ], [ 'type' => 'text', 'label' => $this->l('Accept Button Text'), @@ -155,6 +188,13 @@ class GdprCookieConsent extends Module 'name' => 'GDPR_COOKIE_SETTINGS', 'required' => true, ], + [ + 'type' => 'text', + 'label' => $this->l('Manage Preferences Text'), + 'name' => 'GDPR_COOKIE_MANAGE_TEXT', + 'desc' => $this->l('Text for the manage preferences button (displayed after consent is given)'), + 'required' => true, + ], [ 'type' => 'text', 'label' => $this->l('More Info Button Text'), @@ -202,6 +242,11 @@ class GdprCookieConsent extends Module $helper->fields_value['GDPR_COOKIE_SETTINGS'] = Configuration::get('GDPR_COOKIE_SETTINGS'); $helper->fields_value['GDPR_COOKIE_MORE_INFO'] = Configuration::get('GDPR_COOKIE_MORE_INFO'); $helper->fields_value['GDPR_COOKIE_MORE_INFO_URL'] = Configuration::get('GDPR_COOKIE_MORE_INFO_URL'); + // New fields + $helper->fields_value['GDPR_COOKIE_DATA_CONTROLLER'] = Configuration::get('GDPR_COOKIE_DATA_CONTROLLER'); + $helper->fields_value['GDPR_COOKIE_RETENTION_PERIOD'] = Configuration::get('GDPR_COOKIE_RETENTION_PERIOD'); + $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'); return $helper->generateForm([$form]); } @@ -231,7 +276,22 @@ class GdprCookieConsent extends Module 'gdprCookieMoreInfoUrl' => $this->context->link->getCMSLink( Configuration::get('GDPR_COOKIE_MORE_INFO_URL') ), + // New variables + 'gdprCookieDataController' => Configuration::get('GDPR_COOKIE_DATA_CONTROLLER', ''), + 'gdprCookieRetentionPeriod' => Configuration::get('GDPR_COOKIE_RETENTION_PERIOD', '365 days'), + 'gdprCookieThirdParties' => Configuration::get('GDPR_COOKIE_THIRD_PARTIES', ''), + 'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT', 'Manage Cookies'), ]); + + // Assign variables to Smarty for the manage button template + $this->context->smarty->assign([ + 'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT', 'Manage Cookies'), + ]); + + // 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'); + } } /** @@ -252,8 +312,13 @@ class GdprCookieConsent extends Module 'gdprCookieMoreInfoUrl' => $this->context->link->getCMSLink( Configuration::get('GDPR_COOKIE_MORE_INFO_URL') ), + // New variables + 'gdprCookieDataController' => Configuration::get('GDPR_COOKIE_DATA_CONTROLLER'), + 'gdprCookieRetentionPeriod' => Configuration::get('GDPR_COOKIE_RETENTION_PERIOD'), + 'gdprCookieThirdParties' => Configuration::get('GDPR_COOKIE_THIRD_PARTIES'), + 'gdprCookieManageText' => Configuration::get('GDPR_COOKIE_MANAGE_TEXT'), ]); return $this->display(__FILE__, 'views/templates/hook/footer.tpl'); } -} \ No newline at end of file +} diff --git a/views/css/gdpr_cookie.css b/views/css/gdpr_cookie.css index 2cb4050..0e79b8a 100644 --- a/views/css/gdpr_cookie.css +++ b/views/css/gdpr_cookie.css @@ -224,4 +224,73 @@ .gdpr-cookie-more-info { margin-bottom: 10px; } +} + +.gdpr-cookie-info-block { + margin: 15px 0; + padding: 15px; + background-color: #f9f9f9; + border: 1px solid #eee; + border-radius: 5px; +} + +.gdpr-cookie-info-block p { + margin: 5px 0; + font-size: 13px; + color: #666; +} + +.gdpr-cookie-banner-info { + margin: 5px 0 10px; +} + +.gdpr-cookie-banner-info p { + font-size: 12px; + opacity: 0.9; + margin: 0; +} + +/* Equal prominence for buttons */ +.gdpr-cookie-banner-decline, +.gdpr-cookie-banner-accept { + font-weight: 400; + padding: 8px 15px; + border-radius: 3px; + /* Make both buttons similar size but distinctive */ + min-width: 120px; +} + +.gdpr-cookie-banner-decline { + background-color: #f1f1f1; + color: #333; + border: 1px solid #ccc; +} + +.gdpr-cookie-banner-accept { + background-color: #4caf50; + color: white; + border: 1px solid #4caf50; +} + +/* Manage button styles */ +.gdpr-cookie-manage-button { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 9990; +} + +.gdpr-cookie-manage { + padding: 8px 12px; + background-color: #f1f1f1; + color: #333; + border: 1px solid #ccc; + border-radius: 3px; + font-size: 12px; + cursor: pointer; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +.gdpr-cookie-manage:hover { + background-color: #e5e5e5; } \ No newline at end of file diff --git a/views/js/gdpr_cookie.js b/views/js/gdpr_cookie.js index 21131fd..3871c45 100644 --- a/views/js/gdpr_cookie.js +++ b/views/js/gdpr_cookie.js @@ -29,6 +29,21 @@ document.addEventListener('DOMContentLoaded', function() { return null; } + // Show manage preferences button when cookies are already set + function showManageButton() { + document.getElementById('gdpr-cookie-manage-button').style.display = 'block'; + } + + // After user consents, hide banner and modal and show the manage button + function afterConsent() { + // Hide banner and modal + hideModal(); + document.getElementById('gdpr-cookie-banner').style.display = 'none'; + + // Show manage button + showManageButton(); + } + // Check if cookie consent is already set var cookieConsent = getCookie('gdpr_cookie_consent'); @@ -39,6 +54,9 @@ document.addEventListener('DOMContentLoaded', function() { // Apply cookie preferences var consentPreferences = JSON.parse(cookieConsent); applyConsentPreferences(consentPreferences); + + // Show the manage button since consent was already given + showManageButton(); } // Banner buttons @@ -67,6 +85,11 @@ document.addEventListener('DOMContentLoaded', function() { acceptSelectedCookies(); }); + // Manage button (for after consent is given) + document.getElementById('gdpr-cookie-manage').addEventListener('click', function() { + showModal(); + }); + // Functions function showModal() { document.getElementById('gdpr-cookie-banner').style.display = 'none'; @@ -103,8 +126,7 @@ document.addEventListener('DOMContentLoaded', function() { setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365); applyConsentPreferences(preferences); - hideModal(); - document.getElementById('gdpr-cookie-banner').style.display = 'none'; + afterConsent(); // Use the new function for consistent post-consent behavior } function declineAllCookies() { @@ -117,8 +139,7 @@ document.addEventListener('DOMContentLoaded', function() { setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365); applyConsentPreferences(preferences); - hideModal(); - document.getElementById('gdpr-cookie-banner').style.display = 'none'; + afterConsent(); // Use the new function for consistent post-consent behavior } function acceptSelectedCookies() { @@ -134,8 +155,7 @@ document.addEventListener('DOMContentLoaded', function() { setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365); applyConsentPreferences(preferences); - hideModal(); - document.getElementById('gdpr-cookie-banner').style.display = 'none'; + afterConsent(); // Use the new function for consistent post-consent behavior } function applyConsentPreferences(preferences) { @@ -179,6 +199,11 @@ document.addEventListener('DOMContentLoaded', function() { function disableAnalytics() { // Example: Disable Google Analytics window['ga-disable-UA-XXXXXXXX-X'] = true; + + // Remove existing GA cookies + document.cookie = '_ga=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=.' + window.location.hostname; + document.cookie = '_gid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=.' + window.location.hostname; + document.cookie = '_gat=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=.' + window.location.hostname; } function enableAnalytics() { @@ -187,12 +212,20 @@ document.addEventListener('DOMContentLoaded', function() { } function disableMarketing() { - // Example implementation - // You would implement according to your specific marketing cookies + // Example implementation for common marketing cookies + var marketingCookies = ['_fbp', 'fr', 'IDE', 'MUID', 'personalization_id']; + var domains = [window.location.hostname, '.' + window.location.hostname]; + + marketingCookies.forEach(function(cookie) { + domains.forEach(function(domain) { + document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain; + }); + }); } function enableMarketing() { - // Example implementation - // You would implement according to your specific marketing cookies + // For enabling marketing, we typically don't need to do anything special + // The marketing scripts will set their cookies when they load + // Just ensure the marketing scripts are loaded after checking consent } }); \ No newline at end of file diff --git a/views/templates/hook/footer.tpl b/views/templates/hook/footer.tpl index aac84df..f845643 100644 --- a/views/templates/hook/footer.tpl +++ b/views/templates/hook/footer.tpl @@ -14,6 +14,13 @@