diff --git a/Setup/Patch/Data/PersonalizationData.php b/Setup/Patch/Data/PersonalizationData.php new file mode 100644 index 0000000..cd85641 --- /dev/null +++ b/Setup/Patch/Data/PersonalizationData.php @@ -0,0 +1,63 @@ +cookieGroupFactory = $cookieGroupFactory; + $this->cookieGroupRepository = $cookieGroupRepository; + } + + public static function getDependencies() + { + return [ + CookieGroupAttribute::class, + DefaultCookieData::class, + ]; + } + + public function getAliases() + { + return []; + } + + public function apply() + { + $this->createDefaultGroups(); + } + + private function createDefaultGroups(): void + { + /** @var CookieGroupInterface $group */ + $personalization = $this->cookieGroupFactory->create(); + $personalization->setStoreId(Store::DEFAULT_STORE_ID); + $personalization->setSystemName('personalization'); + $personalization->setName('Personalization'); + $personalization->setActive(true); + $personalization->setEssential(false); + $personalization->setDescription('Personalization cookies are used for ad personalization and remarketing.'); + + $this->cookieGroupRepository->save($personalization); + } +} diff --git a/composer.json b/composer.json index 9680b6e..fc9034e 100644 --- a/composer.json +++ b/composer.json @@ -36,15 +36,16 @@ "sort-packages": true, "allow-plugins": { "phpro/grumphp-shim": true, - "magento/composer-dependency-version-audit-plugin": true + "magento/composer-dependency-version-audit-plugin": true, + "dealerdirect/phpcodesniffer-composer-installer": true } }, "scripts": { "post-install-cmd": [ - "([ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard,../../phpcompatibility/php-compatibility/PHPCompatibility)" + "([ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard,../../magento/php-compatibility-fork,../../phpcompatibility/php-compatibility)" ], "post-update-cmd": [ - "([ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard,../../phpcompatibility/php-compatibility/PHPCompatibility)" + "([ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard,../../magento/php-compatibility-fork,../../phpcompatibility/php-compatibility)" ] } } diff --git a/docs/Configuration.md b/docs/Configuration.md index 14448b7..fea62b8 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -26,7 +26,7 @@ To delete any group, click the dropdown in the Action column and select Delete. To create a new group, click Add new Cookie Group. -The **essential**, **analytical** & **marketing** cookie groups are created automatically on installation of the module. +The **essential**, **analytical**, **marketing** & **personalization** cookie groups are created automatically on installation of the module. These groups can be altered to your needs. ### Create @@ -56,5 +56,8 @@ store views for that specific cookie group. **Only the Name & Description field More information for GTM configuration can be found [here](./GTM.md) +### Google Consent + +More information for Google consent configuration can be found [here](Consent.md) diff --git a/docs/Consent.md b/docs/Consent.md new file mode 100644 index 0000000..fb57edb --- /dev/null +++ b/docs/Consent.md @@ -0,0 +1,17 @@ +# Consent Mode V2 + +## Configuration +### Enable the Google Consent feature +**Stores > Settings > Configuration > General > Cookie Consent -> Google Consent** + +### Remarks +- Make sure you are using the default system names of the cookie groups: + - essential + - analytical + - marketing + - personalization +- Make sure your Google Tag Manager instance is injected AFTER the 'phpro_cookie_gtag' block. It's important to have the consent first be set to 'DENIED' before loading Google Tag Manager. + + + + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 8aef732..9213732 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -24,6 +24,14 @@ The value represent the expiration of the cookie in days.. + + + + + Magento\Config\Model\Config\Source\Yesno + Enable the module to send the consent to Google using Gtag. It's important to have your Google Tag Manager initiated AFTER the 'phpro_cookie_gtag' block. This feature relies on the cookie groups with the following system names: 'essential', 'analytical', 'marketing' and 'personalization' + + diff --git a/etc/config.xml b/etc/config.xml index 2a90e69..cc4fecf 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -7,6 +7,9 @@ cookieConsentPrefs 182 + + 0 + diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index d1ec3c6..28be596 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -1,6 +1,13 @@ + + + + + window.dataLayer = window.dataLayer || []; + + function gtag() { + dataLayer.push(arguments); + } + + if (localStorage.getItem('consentMode') === null) { + gtag('consent', 'default', { + 'ad_storage': 'denied', + 'analytics_storage': 'denied', + 'personalization_storage': 'denied', + 'functionality_storage': 'denied', + 'security_storage': 'denied', + 'ad_user_data': 'denied', + 'ad_personalization': 'denied', + }); + } else { + gtag('consent', 'default', JSON.parse(localStorage.getItem('consentMode'))); + } + + document.addEventListener('consent-changed', function (event) { + const consent = event.detail; + const consentMode = { + 'ad_storage': consent.cg_marketing ? 'granted': 'denied', + 'analytics_storage': consent.cg_analytical ? 'granted': 'denied', + 'personalization_storage': consent.cg_personalization ? 'granted': 'denied', + 'functionality_storage': consent.cg_essential ? 'granted': 'denied', + 'security_storage': consent.cg_essential ? 'granted': 'denied', + 'ad_user_data': consent.cg_marketing ? 'granted': 'denied', + 'ad_personalization': consent.cg_marketing && consent.cg_personalization ? 'granted': 'denied', + }; + + gtag('consent', 'update', consentMode); + localStorage.setItem('consentMode', JSON.stringify(consentMode)); + }) + diff --git a/view/frontend/web/js/model/cookie.js b/view/frontend/web/js/model/cookie.js index 16c06af..e3880bf 100644 --- a/view/frontend/web/js/model/cookie.js +++ b/view/frontend/web/js/model/cookie.js @@ -9,7 +9,7 @@ define([ return (!!$.cookie(name)); }, - getConsentCookieObject: function(name) { + getConsentCookieObject: function (name) { return $.cookie(name); }, @@ -24,6 +24,7 @@ define([ data['expire'] = expiration; data['secure'] = secure; $.cookie(name, JSON.stringify(data), {expires: this.getExpiration(expiration)}); + document.dispatchEvent(new CustomEvent('consent-changed', {detail: data})); }, saveSelected: function (name, expiration, secure, systemNames) { @@ -36,6 +37,7 @@ define([ data['expire'] = expiration; data['secure'] = secure; $.cookie(name, JSON.stringify(data), {expires: this.getExpiration(expiration)}); + document.dispatchEvent(new CustomEvent('consent-changed', {detail: data})); }, closeCookieNotice: function () { @@ -45,7 +47,7 @@ define([ getExpiration: function (expiration) { var today = new Date(); var expireDate = new Date(today); - expireDate.setDate(today.getDate()+expiration); + expireDate.setDate(today.getDate() + expiration); return expireDate; }