├── .gitignore ├── docs ├── assets │ ├── popup.png │ ├── notice.png │ ├── cookie_policy.png │ ├── general_config.png │ ├── gtm_cookie_var.png │ ├── overview_widget.png │ ├── privacy_policy.png │ ├── button_widget_btn.png │ ├── button_widget_link.png │ ├── consent_overview.png │ ├── cookie_group_grid.png │ ├── gtm_analytics_var.png │ ├── button_widget_config.png │ ├── cookie_group_create.png │ └── gtm_analytics_trigger.png ├── Description.md ├── Installation.md ├── GTM.md ├── Content.md └── Configuration.md ├── view ├── adminhtml │ ├── web │ │ ├── images │ │ │ └── phpro-logo-menu.png │ │ └── css │ │ │ └── source │ │ │ └── _module.less │ ├── layout │ │ ├── phpro_cookie_consent_cookiegroup_new.xml │ │ ├── phpro_cookie_consent_cookiegroup_index.xml │ │ └── phpro_cookie_consent_cookiegroup_edit.xml │ └── ui_component │ │ ├── phpro_cookie_consent_cookie_group_listing.xml │ │ └── phpro_cookie_consent_cookie_group_form.xml └── frontend │ ├── templates │ ├── widget │ │ ├── preferences │ │ │ └── button.phtml │ │ └── overview.phtml │ ├── notice.phtml │ └── modal │ │ └── preferences.phtml │ ├── web │ ├── js │ │ ├── notice.js │ │ ├── model │ │ │ └── cookie.js │ │ └── modal │ │ │ └── preferences.js │ └── css │ │ └── source │ │ └── _module.less │ └── layout │ └── default.xml ├── Model ├── CookieGroupAttribute.php ├── Source │ └── Widget │ │ └── Button.php ├── ResourceModel │ ├── CookieGroup.php │ ├── CookieGroup │ │ └── Collection.php │ ├── AbstractResource.php │ └── AbstractCollection.php ├── CookieGroup.php ├── CookieGroupRepository.php └── Eav │ └── ScopeOverriddenValue.php ├── registration.php ├── etc ├── module.xml ├── adminhtml │ ├── routes.xml │ ├── menu.xml │ ├── di.xml │ └── system.xml ├── config.xml ├── acl.xml ├── widget.xml ├── di.xml └── db_schema.xml ├── Block ├── Widget │ ├── Preferences │ │ └── Button.php │ └── Overview.php └── Adminhtml │ └── Store │ └── Edit │ ├── BackButton.php │ ├── SaveButton.php │ ├── GenericButton.php │ ├── SaveAndContinueButton.php │ └── DeleteButton.php ├── CHANGELOG.md ├── Api ├── Data │ ├── EavModelInterface.php │ └── CookieGroupInterface.php └── CookieGroupRepositoryInterface.php ├── grumphp.yml ├── .github └── workflows │ └── grumphp.yml ├── Controller └── Adminhtml │ └── CookieGroup │ ├── Index.php │ ├── NewAction.php │ ├── Delete.php │ ├── Edit.php │ └── Save.php ├── LICENSE ├── README.md ├── Setup ├── Patch │ └── Data │ │ ├── CookieGroupAttribute.php │ │ └── DefaultCookieData.php └── CookieGroupSetup.php ├── composer.json ├── Config └── CookieConsentConfig.php ├── Ui ├── Component │ └── Listing │ │ └── Column │ │ └── CookieGroupActions.php └── DataProvider │ └── CookieGroup │ └── Form │ ├── DataProvider.php │ └── Modifier │ └── Fields.php ├── ViewModel └── Cookie.php └── Helper ├── AttributesHelper.php └── UiComponentHelper.php /.gitignore: -------------------------------------------------------------------------------- 1 | /composer.lock 2 | /vendor 3 | .idea/ -------------------------------------------------------------------------------- /docs/assets/popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/popup.png -------------------------------------------------------------------------------- /docs/assets/notice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/notice.png -------------------------------------------------------------------------------- /docs/assets/cookie_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/cookie_policy.png -------------------------------------------------------------------------------- /docs/assets/general_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/general_config.png -------------------------------------------------------------------------------- /docs/assets/gtm_cookie_var.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/gtm_cookie_var.png -------------------------------------------------------------------------------- /docs/assets/overview_widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/overview_widget.png -------------------------------------------------------------------------------- /docs/assets/privacy_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/privacy_policy.png -------------------------------------------------------------------------------- /docs/assets/button_widget_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/button_widget_btn.png -------------------------------------------------------------------------------- /docs/assets/button_widget_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/button_widget_link.png -------------------------------------------------------------------------------- /docs/assets/consent_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/consent_overview.png -------------------------------------------------------------------------------- /docs/assets/cookie_group_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/cookie_group_grid.png -------------------------------------------------------------------------------- /docs/assets/gtm_analytics_var.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/gtm_analytics_var.png -------------------------------------------------------------------------------- /docs/assets/button_widget_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/button_widget_config.png -------------------------------------------------------------------------------- /docs/assets/cookie_group_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/cookie_group_create.png -------------------------------------------------------------------------------- /docs/assets/gtm_analytics_trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/docs/assets/gtm_analytics_trigger.png -------------------------------------------------------------------------------- /view/adminhtml/web/images/phpro-logo-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpro/phpro-mage2-module-cookie-consent/HEAD/view/adminhtml/web/images/phpro-logo-menu.png -------------------------------------------------------------------------------- /Model/CookieGroupAttribute.php: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /docs/Description.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | The user’s preferences are stored in a cookie, which then can be used in Google Tag Manager to actually block and allow certain cookies. 4 | 5 | ![notice](./assets/notice.png "Consent Notice Bar") 6 | ![popup](./assets/popup.png "Consent Preference Popup") -------------------------------------------------------------------------------- /docs/Installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | The module has the following requirement for installation: 4 | * Magento 2.4 5 | * PHP >=7.4/8.1 6 | 7 | `composer require phpro/mage2-module-cookie-consent` 8 | 9 | Make sure to run bin/magento setup:upgrade after the composer installation. 10 | -------------------------------------------------------------------------------- /view/adminhtml/layout/phpro_cookie_consent_cookiegroup_new.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Model/Source/Widget/Button.php: -------------------------------------------------------------------------------- 1 | 'Button', 13 | 1 => 'Link', 14 | ]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /view/adminhtml/web/css/source/_module.less: -------------------------------------------------------------------------------- 1 | .admin__menu [data-ui-id="menu-phpro-cookieconsent-cookie-consent"] .submenu-group-title span:before { 2 | background-image: url("../Phpro_CookieConsent/images/phpro-logo-menu.png"); 3 | background-repeat: no-repeat; 4 | background-size: contain; 5 | width: 50px; 6 | height: 20px; 7 | content: ''; 8 | display: inline-block; 9 | margin-right: 7px; 10 | vertical-align: top; 11 | } -------------------------------------------------------------------------------- /view/frontend/templates/widget/preferences/button.phtml: -------------------------------------------------------------------------------- 1 | getButtonType(); 4 | ?> 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /view/adminhtml/layout/phpro_cookie_consent_cookiegroup_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Model/ResourceModel/CookieGroup.php: -------------------------------------------------------------------------------- 1 | _type)) { 12 | $this->setType(CookieGroupModel::ENTITY); 13 | } 14 | 15 | return parent::getEntityType(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /view/frontend/templates/widget/overview.phtml: -------------------------------------------------------------------------------- 1 | getCookieGroups(); 4 | ?> 5 | 13 | -------------------------------------------------------------------------------- /Block/Widget/Preferences/Button.php: -------------------------------------------------------------------------------- 1 | getData('preferences_button_type'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 0 7 | cookieConsentPrefs 8 | 182 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [3.0.1] 4 | * Replaced deprecated javascript library 5 | 6 | ## [3.0.0] 7 | * Support PHP 8.1 8 | * Remove Support Lower Than Magento 2.4.4 9 | 10 | ## [2.0.5] 11 | * Fixed typo in less variable 12 | 13 | ## [2.0.4] 14 | * Replace H3 tags with P tags 15 | * Update toggle slider status after visitors accept all cookies. 16 | 17 | ## [2.0.3] 18 | * Replace H1 tags with H3 tags 19 | 20 | ## [2.0.2] 21 | * Fixes an issue when running setup:upgrade 22 | 23 | ## [2.0.0] 24 | * Added Cookie Consent module that allows customers to select their cookie preference 25 | -------------------------------------------------------------------------------- /Model/ResourceModel/CookieGroup/Collection.php: -------------------------------------------------------------------------------- 1 | _init( 14 | CookieGroupModel::class, 15 | CookieGroupResourceModel::class 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /view/frontend/web/js/notice.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'Phpro_CookieConsent/js/model/cookie' 4 | ], function ($, cookie) { 5 | return function (options) { 6 | if (!cookie.consentCookieExists(options.cookie_name)) { 7 | $('.phpro-cookie-notice').css('display', 'block'); 8 | } 9 | $(document).on('click', '.phpro-cookie-notice .notice__btn-accept', function (event) { 10 | event.preventDefault(); 11 | cookie.saveAll(options.cookie_name, options.expiration, options.secure, options.cookie_groups_data.system_names); 12 | cookie.closeCookieNotice(); 13 | }); 14 | } 15 | }); -------------------------------------------------------------------------------- /Api/Data/EavModelInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Block/Adminhtml/Store/Edit/BackButton.php: -------------------------------------------------------------------------------- 1 | __('Back'), 13 | 'on_click' => sprintf("location.href='%s'", $this->getBackUrl()), 14 | 'class' => 'back', 15 | 'sort_order' => 10, 16 | ]; 17 | } 18 | 19 | public function getBackUrl(): string 20 | { 21 | return $this->getUrl('*/*/'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Block/Adminhtml/Store/Edit/SaveButton.php: -------------------------------------------------------------------------------- 1 | __('Save Cookie Group'), 13 | 'class' => 'save primary', 14 | 'data_attribute' => [ 15 | 'mage-init' => ['button' => ['event' => 'save']], 16 | 'form-role' => 'save', 17 | ], 18 | 'sort_order' => 90, 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Block/Adminhtml/Store/Edit/GenericButton.php: -------------------------------------------------------------------------------- 1 | context = $context; 17 | } 18 | 19 | public function getModelId() 20 | { 21 | return $this->context->getRequest()->getParam('entity_id'); 22 | } 23 | 24 | public function getUrl($route = '', $params = []): string 25 | { 26 | return $this->context->getUrlBuilder()->getUrl($route, $params); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Block/Adminhtml/Store/Edit/SaveAndContinueButton.php: -------------------------------------------------------------------------------- 1 | __('Save and Continue Edit'), 13 | 'class' => 'save', 14 | 'data_attribute' => [ 15 | 'mage-init' => [ 16 | 'button' => ['event' => 'saveAndContinueEdit'], 17 | ], 18 | ], 19 | 'sort_order' => 80, 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /view/adminhtml/layout/phpro_cookie_consent_cookiegroup_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/workflows/grumphp.yml: -------------------------------------------------------------------------------- 1 | on: [ push, pull_request ] 2 | 3 | jobs: 4 | build: 5 | name: Checking coding standards 6 | runs-on: ubuntu-latest 7 | strategy: 8 | fail-fast: true 9 | matrix: 10 | php-versions: 11 | - "7.4" 12 | - "8.1" 13 | dependencies: 14 | - "lowest" 15 | - "highest" 16 | steps: 17 | - name: Checkout repo 18 | uses: actions/checkout@v2 19 | 20 | - name: Configure PHP 21 | uses: shivammathur/setup-php@v2 22 | with: 23 | php-version: ${{ matrix.php-versions }} 24 | tools: composer:v2 25 | coverage: xdebug 26 | extensions: bcmath, gd 27 | 28 | - name: Install Composer dependencies 29 | run: composer install 30 | 31 | - name: GrumPHP 32 | run: ./vendor/bin/grumphp run -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Controller/Adminhtml/CookieGroup/Index.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 24 | } 25 | 26 | public function execute() 27 | { 28 | $resultPage = $this->resultPageFactory->create(); 29 | $resultPage->getConfig()->getTitle()->prepend('Cookie Groups'); 30 | 31 | return $resultPage; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Controller/Adminhtml/CookieGroup/NewAction.php: -------------------------------------------------------------------------------- 1 | resultForwardFactory = $resultForwardFactory; 23 | } 24 | 25 | public function execute() 26 | { 27 | /** @var Forward $resultForward */ 28 | $resultForward = $this->resultForwardFactory->create(); 29 | 30 | return $resultForward->forward('edit'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Block/Adminhtml/Store/Edit/DeleteButton.php: -------------------------------------------------------------------------------- 1 | getModelId()) { 13 | $data = [ 14 | 'label' => __('Delete Cookie Group'), 15 | 'class' => 'delete', 16 | 'on_click' => 'deleteConfirm(\'' . __( 17 | 'Are you sure you want to do this?' 18 | ) . '\', \'' . $this->getDeleteUrl() . '\')', 19 | 'sort_order' => 20, 20 | ]; 21 | } 22 | 23 | return $data; 24 | } 25 | 26 | public function getDeleteUrl(): string 27 | { 28 | return $this->getUrl('*/*/delete', ['entity_id' => $this->getModelId()]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /etc/widget.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Listing of cookie groups 6 | 7 | 8 | 9 | Button to open the cookie preferences modal 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Phpro\CookieConsent\Ui\DataProvider\CookieGroup\Form\Modifier\Fields 8 | 10 9 | 10 | 11 | 12 | 13 | 14 | 15 | Phpro\CookieConsent\DataProvider\Modifier\CookieGroupPool 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Phpro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > We deprecated this module as we can not guarantee GDPR compliance. We advise to look into other solutions like Cookiebot. 2 | 3 | ![](https://github.com/phpro/phpro-mage2-module-cookie-consent/workflows/.github/workflows/grumphp.yml/badge.svg) 4 | 5 | # Cookie Consent for Magento 2 6 | ![popup](./docs/assets/popup.png "Consent Preference Popup") 7 | 8 | ![notice](./docs/assets/notice.png "Consent Notice Bar") 9 | 10 | With this module your store can become GDPR compliant in no time. 11 | As a store-owner, you can now divide cookies into categories and have a quick overview of what cookies are being used by your store. 12 | Your customers can select their cookie preferences from within a customizable popup. 13 | 14 | ## Key features 15 | * Customizable consent pop-up 16 | * Cookie consent overview widget 17 | * Customers can manage their preferences with the preference popup 18 | * Customizable cookie/privacy policy 19 | 20 | ## Get started 21 | Install the module using composer 22 | 23 | `composer require phpro/mage2-module-cookie-consent` 24 | 25 | Execute patches 26 | 27 | `bin/magento setup:upgrade` 28 | 29 | ## Read more 30 | [Documentation](docs) 31 | -------------------------------------------------------------------------------- /view/frontend/templates/notice.phtml: -------------------------------------------------------------------------------- 1 | getViewModel(); 4 | ?> 5 | 21 | 33 | -------------------------------------------------------------------------------- /view/frontend/layout/default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | Phpro\CookieConsent\ViewModel\Cookie 12 | 13 | 14 | 19 | 20 | Phpro\CookieConsent\ViewModel\Cookie 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Block/Widget/Overview.php: -------------------------------------------------------------------------------- 1 | collectionFactory = $collectionFactory; 32 | $this->storeManager = $storeManager; 33 | parent::__construct($context, $data); 34 | } 35 | 36 | public function getCookieGroups(): array 37 | { 38 | $collection = $this->collectionFactory->create(); 39 | $collection->setStoreId($this->storeManager->getStore()->getId()) 40 | ->addAttributeToSelect('*') 41 | ->addAttributeToFilter('is_active', 1); 42 | 43 | return $collection->getItems(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/GTM.md: -------------------------------------------------------------------------------- 1 | # GTM 2 | 3 | Cookie consent can be arranged via Google Tag Manager by reading the cookie data in GTM and making decisions based on the choice of the user. 4 | 5 | ## Example 6 | 7 | Google Analytics setup example for Analytics Cookie Group. 8 | 9 | ### Variables 10 | 11 | Following variables are set to determine other variables and to activate triggers or exclude tags. 12 | 13 | #### Cookie Consent Data 14 | 15 | Create a new 1st-Party Cookie variable. 16 | 17 | **Url-decode cookie** - this has to be selected, the cookie needs to be url-decoded 18 | 19 | **Format value** - define the value format of the cookie. 20 | 21 | ![gtm-cookie-var](./assets/gtm_cookie_var.png "GTM cookie variable") 22 | 23 | #### isAllowedAnalytics 24 | 25 | Create a new Lookup Table variable 26 | 27 | **Input variable** - The earlier created 1st-Party Cookie variable is used here 28 | 29 | **Input** - All possible values of the cookie are used here with their outputs 30 | 31 | **Default value** - Set a default value which is used whenever none of the inputs occur 32 | 33 | ![gtm-analytics-var](./assets/gtm_analytics_var.png "GTM analytics variable") 34 | 35 | ### Triggers 36 | 37 | The new variables offer the possibility to fine-tune triggers in Google Tag Manager. They can be used as conditions for activating certain tags. Below is an example of a trigger that is activated when a button is clicked, but only if the user indicates that he / she accepts analytical cookies. 38 | 39 | ![gtm-analytics-trigger](./assets/gtm_analytics_trigger.png "GTM analytics trigger") 40 | -------------------------------------------------------------------------------- /Api/CookieGroupRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | moduleDataSetup = $moduleDataSetup; 34 | $this->cookieGroupSetupFactory = $cookieGroupSetupFactory; 35 | $this->eavConfig = $eavConfig; 36 | } 37 | 38 | public static function getDependencies() 39 | { 40 | return []; 41 | } 42 | 43 | public function getAliases() 44 | { 45 | return []; 46 | } 47 | 48 | public function apply() 49 | { 50 | /** @var CookieGroupSetup $cookieGroupSetup */ 51 | $cookieGroupSetup = $this->cookieGroupSetupFactory->create(['setup' => $this->moduleDataSetup]); 52 | 53 | $cookieGroupSetup->installEntities(); 54 | $this->eavConfig->clear(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phpro/mage2-module-cookie-consent", 3 | "description": "Manage and set the categories and list of cookies", 4 | "type": "magento2-module", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "PHPro NV", 9 | "email": "info@phpro.be", 10 | "homepage": "https://www.phpro.be/" 11 | } 12 | ], 13 | "require": { 14 | "php": "^7.4|^8.1", 15 | "magento/framework": "^103.0" 16 | }, 17 | "require-dev": { 18 | "magento/magento-coding-standard": "*", 19 | "phpro/grumphp-shim": "^1.5" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Phpro\\CookieConsent\\": "" 24 | }, 25 | "files": [ 26 | "registration.php" 27 | ] 28 | }, 29 | "repositories": [ 30 | { 31 | "type": "composer", 32 | "url": "https://repo-magento-mirror.fooman.co.nz" 33 | } 34 | ], 35 | "config": { 36 | "sort-packages": true, 37 | "allow-plugins": { 38 | "phpro/grumphp-shim": true, 39 | "magento/composer-dependency-version-audit-plugin": true 40 | } 41 | }, 42 | "scripts": { 43 | "post-install-cmd": [ 44 | "([ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard,../../phpcompatibility/php-compatibility/PHPCompatibility)" 45 | ], 46 | "post-update-cmd": [ 47 | "([ $COMPOSER_DEV_MODE -eq 0 ] || vendor/bin/phpcs --config-set installed_paths ../../magento/magento-coding-standard,../../phpcompatibility/php-compatibility/PHPCompatibility)" 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Controller/Adminhtml/CookieGroup/Delete.php: -------------------------------------------------------------------------------- 1 | cookieGroupRepository = $cookieGroupRepository; 26 | } 27 | 28 | public function execute() 29 | { 30 | /** @var Redirect $resultRedirect */ 31 | $resultRedirect = $this->resultRedirectFactory->create(); 32 | 33 | $id = (int) $this->getRequest()->getParam('entity_id'); 34 | if (!$id) { 35 | $this->messageManager->addErrorMessage(__('We can\'t find a Cookie Group to delete.')); 36 | 37 | return $resultRedirect->setPath('*/*/'); 38 | } 39 | 40 | try { 41 | $this->cookieGroupRepository->deleteById($id); 42 | $this->messageManager->addSuccessMessage(__('You deleted the Cookie Group.')); 43 | 44 | return $resultRedirect->setPath('*/*/'); 45 | } catch (Exception $e) { 46 | $this->messageManager->addErrorMessage($e->getMessage()); 47 | 48 | return $resultRedirect->setPath('*/*/', ['entity_id' => $id]); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Config/CookieConsentConfig.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 30 | $this->storeManagement = $storeManagement; 31 | } 32 | 33 | public function getCookieName(): string 34 | { 35 | return $this->scopeConfig->getValue( 36 | self::CONFIG_PATH_COOKIE_NAME, 37 | ScopeInterface::SCOPE_STORE, 38 | $this->storeManagement->getStore()->getId() 39 | ); 40 | } 41 | 42 | public function getExpirationDays(): int 43 | { 44 | return (int) $this->scopeConfig->getValue( 45 | self::CONFIG_PATH_COOKIE_EXPIRATION, 46 | ScopeInterface::SCOPE_STORE, 47 | $this->storeManagement->getStore()->getId() 48 | ); 49 | } 50 | 51 | public function isEnabled(): bool 52 | { 53 | return (bool) $this->scopeConfig->getValue( 54 | self::CONFIG_PATH_ENABLED, 55 | ScopeInterface::SCOPE_STORE, 56 | $this->storeManagement->getStore()->getId() 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /etc/adminhtml/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Api/Data/CookieGroupInterface.php: -------------------------------------------------------------------------------- 1 | Elements > Blocks** and are used in the preferences popup. 11 | 12 | ### Cookie Policy 13 | 14 | Identifier: **phpro_cookie_consent_cookie_policy_content** 15 | 16 | This CMS block displays the description for the cookie policy tab in the preferences popup. This content can be altered 17 | to your needs. 18 | 19 | ![cookie-policy](./assets/cookie_policy.png "Cookie Policy") 20 | 21 | 22 | ### Privacy Policy 23 | 24 | Identifier: **phpro_cookie_consent_privacy_policy_content** 25 | 26 | This CMS block displays the description for the privacy policy tab in the preferences popup. This content can be altered 27 | to your needs. 28 | 29 | ![privacy-policy](./assets/privacy_policy.png "Privacy Policy") 30 | 31 | ## Widgets 32 | 33 | ### Cookie consent overview 34 | 35 | The cookie consent overview widget can be used to display an overview of the active cookie groups and their description. 36 | 37 | This widget contains no arguments. 38 | 39 | ![overview-widget](./assets/overview_widget.png "Overview Widget") 40 | 41 | ### Cookie preferences button 42 | 43 | The cookie preferences button widget can be used to display a button/link which opens the preferences popup. This way the 44 | users are able to change their preferences. 45 | 46 | This widget contains 1 argument: 47 | 48 | * **Button/Link** - depending on your choice the widget will be shown as a generic link or button. 49 | 50 | **Config** 51 | ![button-widget-config](./assets/button_widget_config.png "Preferences Button Widget Config") 52 | 53 | **Result** 54 | ![button-widget-btn](./assets/button_widget_btn.png "Preferences Button Widget Button Config") 55 | ![button-widget-link](./assets/button_widget_link.png "Preferences Button Widget Link Config") 56 | 57 | 58 | ## Cms Page 59 | 60 | A CMS page containing the [Cookie consent overview widget](#cookie-consent-overview) & 61 | [Cookie preferences button widget](#cookie-preferences-button) is created on the module installation. 62 | 63 | url key: **consent-overview** 64 | 65 | ![consent-overview](./assets/consent_overview.png "Consent Overview CMS Page") 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /docs/Configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | ## General Configuration 4 | 5 | The module configuration can be found at **Stores > Settings > Configuration > General > Cookie Consent**: 6 | 7 | ![general-config](./assets/general_config.png "General Config") 8 | 9 | **Enabled** - Set to yes to enable the module 10 | 11 | **Name of cookie** - Enter the preferred cookie name which contains the preferences. (**Default=cookieConsentPrefs**) 12 | 13 | **Expiration of cookie** - Enter the amount of days to pass for the cookie to expire (**Default=182**) 14 | 15 | ## Cookie Group Management 16 | 17 | The cookie group grid can be found at **Customers > Cookie Consent > Cookie Groups** 18 | 19 | ![cookie-group-grid](./assets/cookie_group_grid.png "Cookie Group Grid") 20 | 21 | On the grid the ID and System name are displayed. Also you can see if each group Is Essential and Is Enabled. 22 | 23 | To configure any group, click the dropdown in the Action column and select Edit. 24 | 25 | To delete any group, click the dropdown in the Action column and select Delete. 26 | 27 | To create a new group, click Add new Cookie Group. 28 | 29 | The **essential**, **analytical** & **marketing** cookie groups are created automatically on installation of the module. 30 | These groups can be altered to your needs. 31 | 32 | ### Create 33 | 34 | 5 fields are available on the create form for the cookie group: 35 | 36 | **System name** - This field is used for background processes of te module. This is a required field 37 | 38 | **Name** - This is the actual name of the cookie which will be displayed to the users. This is a required field. 39 | 40 | **Description** - The description of the cookie group. 41 | 42 | **Essential** - Toggle this if the cookie group is essential for your website. When toggled this cookie group 43 | will automatically be enabled for the user. 44 | 45 | **Is Active** - Toggle this is the cookie group has to be active. When this is not toggled the cookie group will not be 46 | visible to the customers. 47 | 48 | ![cookie-group-create](./assets/cookie_group_create.png "Cookie Group Create") 49 | 50 | ### Edit 51 | 52 | The edit form is the same as the create form. You are able to switch between store views to save data for the different 53 | store views for that specific cookie group. **Only the Name & Description field can be stored for a specific store view** 54 | 55 | ### GTM 56 | 57 | More information for GTM configuration can be found [here](./GTM.md) 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Ui/Component/Listing/Column/CookieGroupActions.php: -------------------------------------------------------------------------------- 1 | urlBuilder = $urlBuilder; 26 | } 27 | 28 | public function prepareDataSource(array $dataSource) 29 | { 30 | if (isset($dataSource['data']['items'])) { 31 | foreach ($dataSource['data']['items'] as &$item) { 32 | if (isset($item['entity_id'])) { 33 | $item[$this->getData('name')] = [ 34 | 'edit' => [ 35 | 'href' => $this->urlBuilder->getUrl( 36 | static::URL_PATH_EDIT, 37 | [ 38 | 'entity_id' => $item['entity_id'], 39 | ] 40 | ), 41 | 'label' => __('Edit'), 42 | ], 43 | 'delete' => [ 44 | 'href' => $this->urlBuilder->getUrl( 45 | static::URL_PATH_DELETE, 46 | [ 47 | 'entity_id' => $item['entity_id'], 48 | ] 49 | ), 50 | 'label' => __('Delete'), 51 | 'confirm' => [ 52 | 'title' => __('Delete Cookie Group'), 53 | 'message' => __('Are you sure you wan\'t to delete this record?'), 54 | ], 55 | ], 56 | ]; 57 | } 58 | } 59 | } 60 | 61 | return $dataSource; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | phpro_cc_cookie_group_entity 14 | Phpro\CookieConsent\Model\ResourceModel\CookieGroup\Collection 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | phpro_cc_cookie_group_entity 25 | phpro_cc_cookie_group 26 | entity_id 27 | 28 | 29 | 30 | 31 | 32 | 33 | Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor 34 | 35 | 36 | 37 | 38 | 39 | 40 | Phpro\CookieConsent\Model\ResourceModel\CookieGroup\Grid\Collection 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Setup/CookieGroupSetup.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'type' => 'static', 19 | 'group' => CookieGroupInterface::ATTRIBUTE_GROUP_GENERAL, 20 | 'label' => 'System name', 21 | 'input' => 'text', 22 | 'sort_order' => 5, 23 | 'required' => true, 24 | ], 25 | CookieGroupInterface::FIELD_NAME => [ 26 | 'type' => 'varchar', 27 | 'group' => CookieGroupInterface::ATTRIBUTE_GROUP_GENERAL, 28 | 'label' => 'Name', 29 | 'input' => 'text', 30 | 'sort_order' => 10, 31 | 'required' => true, 32 | ], 33 | CookieGroupInterface::FIELD_DESCRIPTION => [ 34 | 'type' => 'text', 35 | 'group' => CookieGroupInterface::ATTRIBUTE_GROUP_GENERAL, 36 | 'label' => 'Description', 37 | 'input' => 'textarea', 38 | 'sort_order' => 15, 39 | 'required' => false, 40 | ], 41 | CookieGroupInterface::FIELD_IS_ESSENTIAL => [ 42 | 'type' => 'static', 43 | 'group' => CookieGroupInterface::ATTRIBUTE_GROUP_GENERAL, 44 | 'label' => 'Essential', 45 | 'input' => 'boolean', 46 | 'sort_order' => 20, 47 | 'required' => false, 48 | ], 49 | CookieGroupInterface::FIELD_IS_ACTIVE => [ 50 | 'type' => 'static', 51 | 'group' => CookieGroupInterface::ATTRIBUTE_GROUP_GENERAL, 52 | 'label' => 'Is Active', 53 | 'input' => 'boolean', 54 | 'sort_order' => 25, 55 | 'required' => false, 56 | ], 57 | ]; 58 | 59 | $entities = [ 60 | $entity => [ 61 | 'entity_model' => CookieGroupResourceModel::class, 62 | 'attribute_model' => CookieGroupAttribute::class, 63 | 'table' => CookieGroupInterface::ENTITY_TABLE, 64 | 'attributes' => $attributes, 65 | ], 66 | ]; 67 | 68 | return $entities; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Model/CookieGroup.php: -------------------------------------------------------------------------------- 1 | _init(ResourceModel\CookieGroup::class); 16 | } 17 | 18 | public function getId(): int 19 | { 20 | return (int) parent::getId(); 21 | } 22 | 23 | public function getSystemName(): string 24 | { 25 | return (string) $this->getData(self::FIELD_SYSTEM_NAME); 26 | } 27 | 28 | public function setSystemName(string $systemName): CookieGroupInterface 29 | { 30 | $this->setData(self::FIELD_SYSTEM_NAME, $systemName); 31 | 32 | return $this; 33 | } 34 | 35 | public function getName(): string 36 | { 37 | return (string) $this->getData(self::FIELD_NAME); 38 | } 39 | 40 | public function setName(string $name): CookieGroupInterface 41 | { 42 | $this->setData(self::FIELD_NAME, $name); 43 | 44 | return $this; 45 | } 46 | 47 | public function getDescription(): string 48 | { 49 | return (string) $this->getData(self::FIELD_DESCRIPTION); 50 | } 51 | 52 | public function setDescription(string $description): CookieGroupInterface 53 | { 54 | $this->setData(self::FIELD_DESCRIPTION, $description); 55 | 56 | return $this; 57 | } 58 | 59 | public function isEssential(): bool 60 | { 61 | return (bool) $this->getData(self::FIELD_IS_ESSENTIAL); 62 | } 63 | 64 | public function setEssential(bool $essential): CookieGroupInterface 65 | { 66 | $this->setData(self::FIELD_IS_ESSENTIAL, $essential); 67 | 68 | return $this; 69 | } 70 | 71 | public function isActive(): bool 72 | { 73 | return (bool) $this->getData(self::FIELD_IS_ACTIVE); 74 | } 75 | 76 | public function setActive(bool $active): CookieGroupInterface 77 | { 78 | $this->setData(self::FIELD_IS_ACTIVE, $active); 79 | 80 | return $this; 81 | } 82 | 83 | public function getStoreId(): int 84 | { 85 | return (int) $this->getData(self::FIELD_STORE_ID); 86 | } 87 | 88 | public function setStoreId(int $storeId): EavModelInterface 89 | { 90 | $this->setData(self::FIELD_STORE_ID, $storeId); 91 | 92 | return $this; 93 | } 94 | 95 | public function getEntityType(): string 96 | { 97 | return self::ENTITY; 98 | } 99 | 100 | public function getDefaultAttributeSetId(): int 101 | { 102 | return (int) $this->getResource()->getEntityType()->getDefaultAttributeSetId(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /view/frontend/templates/modal/preferences.phtml: -------------------------------------------------------------------------------- 1 | getViewModel(); 4 | $cookieGroups = $viewModel->getCookieGroups(); 5 | ?> 6 | 49 | 61 | -------------------------------------------------------------------------------- /ViewModel/Cookie.php: -------------------------------------------------------------------------------- 1 | cookieManagement = $cookieManagement; 49 | $this->config = $cookieConsentConfig; 50 | $this->storeManagement = $storeManagement; 51 | $this->collectionFactory = $collectionFactory; 52 | } 53 | 54 | public function getCookieGroups(): array 55 | { 56 | if (!$this->groups) { 57 | $collection = $this->collectionFactory->create(); 58 | $collection->setStoreId($this->storeManagement->getStore()->getId()) 59 | ->addAttributeToSelect('*') 60 | ->addAttributeToFilter('is_active', 1); 61 | $this->groups = $collection->getItems(); 62 | } 63 | 64 | return $this->groups; 65 | } 66 | 67 | public function getGroupsData(): string 68 | { 69 | $data = []; 70 | $groups = $this->getCookieGroups(); 71 | 72 | /** @var CookieGroupInterface $group */ 73 | foreach ($groups as $group) { 74 | $data[] = $group->getSystemName(); 75 | } 76 | $result = [ 77 | 'system_names' => $data, 78 | ]; 79 | 80 | return json_encode($result); 81 | } 82 | 83 | public function getCookieName(): string 84 | { 85 | return $this->config->getCookieName(); 86 | } 87 | 88 | public function getExpirationDays(): int 89 | { 90 | return $this->config->getExpirationDays(); 91 | } 92 | 93 | public function isFrontUrlSecure(): int 94 | { 95 | return (int) $this->storeManagement->getStore()->isFrontUrlSecure(); 96 | } 97 | 98 | public function getCookiePolicyIdentifier(): string 99 | { 100 | return self::IDENTIFIER_COOKIE_POLICY_CONTENT; 101 | } 102 | 103 | public function getPrivacyPolicyIdentifier(): string 104 | { 105 | return self::IDENTIFIER_PRIVACY_POLICY_CONTENT; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Controller/Adminhtml/CookieGroup/Edit.php: -------------------------------------------------------------------------------- 1 | resultPageFactory = $resultPageFactory; 47 | $this->cookieGroupRepository = $cookieGroupRepository; 48 | $this->cookieGroupFactory = $cookieGroupFactory; 49 | $this->registry = $registry; 50 | } 51 | 52 | public function execute() 53 | { 54 | $id = (int) $this->getRequest()->getParam('entity_id'); 55 | $storeId = (int) $this->getRequest()->getParam('store', Store::DEFAULT_STORE_ID); 56 | 57 | /** @var \Magento\Backend\Model\View\Result\Page $resultPage */ 58 | $resultPage = $this->resultPageFactory->create(); 59 | $resultPage->setActiveMenu(self::ADMIN_RESOURCE) 60 | ->addBreadcrumb(__('Content'), __('Content')) 61 | ->addBreadcrumb(__('Cookie Consent'), __('Cookie Consent')) 62 | ->addBreadcrumb(__('Cookie Group'), __('Cookie Group')); 63 | 64 | // New action: 65 | if (!$id) { 66 | /** @var CookieGroup $model */ 67 | $model = $this->cookieGroupFactory->create(); 68 | $model->setStoreId($storeId); 69 | $this->registry->register('phpro_cookie_consent_cookie_group', $model); 70 | 71 | $pageTitle = __('New Cookie Group'); 72 | $resultPage->addBreadcrumb($pageTitle, $pageTitle); 73 | $resultPage->getConfig()->getTitle()->prepend($pageTitle); 74 | 75 | return $resultPage; 76 | } 77 | 78 | // Edit action: 79 | try { 80 | $model = $this->cookieGroupRepository->getById($id, $storeId); 81 | $model->setStoreId($storeId); 82 | $this->registry->register('phpro_cookie_consent_cookie_group', $model); 83 | 84 | $pageTitle = __('Edit Cookie Group'); 85 | $resultPage->addBreadcrumb($pageTitle, $pageTitle); 86 | $resultPage->getConfig()->getTitle()->prepend(__('Edit Cookie Group: %1', $model->getName())); 87 | 88 | return $resultPage; 89 | } catch (\Exception $e) { 90 | $this->messageManager->addErrorMessage(__('This Cookie Group no longer exists.')); 91 | $resultRedirect = $this->resultRedirectFactory->create(); 92 | 93 | return $resultRedirect->setPath('*/*/'); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /view/frontend/web/js/modal/preferences.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'Phpro_CookieConsent/js/model/cookie' 4 | ], function ($, cookie) { 5 | return function (options) { 6 | const consentContentElement = '#modal-consent-content'; 7 | 8 | var consentModal = $(consentContentElement).modal({ 9 | type: 'popup', 10 | responsive: false, 11 | modalClass: 'cookie-consent-newsletter-modal', 12 | innerScroll: true, 13 | clickableOverlay: true, 14 | buttons: [ 15 | { 16 | text: $.mage.__('Allow all'), 17 | class: 'action primary consent-btn consent-btn-allow', 18 | click: function () { 19 | cookie.saveAll(options.cookie_name, options.expiration, options.secure, options.cookie_groups_data.system_names); 20 | cookie.closeCookieNotice(); 21 | consentModal.modal("closeModal"); 22 | } 23 | }, 24 | { 25 | text: $.mage.__('Save'), 26 | class: 'action primary consent-btn consent-btn-save', 27 | click: function () { 28 | cookie.saveSelected(options.cookie_name, options.expiration, options.secure, options.cookie_groups_data.system_names); 29 | cookie.closeCookieNotice(); 30 | consentModal.modal("closeModal"); 31 | } 32 | }, 33 | ] 34 | }); 35 | 36 | init(); 37 | 38 | $(document).on('click', '.notice__btn-settings, .btn-cookie-preferences-show', function (event) { 39 | event.preventDefault(); 40 | consentModal.modal('openModal'); 41 | }); 42 | 43 | $(document).on('click', '.consent-tab', function (event) { 44 | event.preventDefault(); 45 | onClickTab($(this)); 46 | }); 47 | 48 | // Fix for modal not closing when clicking overlay on mobile (magento bug) 49 | $(document).on('click', '.modal-popup.cookie-consent-newsletter-modal', function () { 50 | consentModal.modal("closeModal"); 51 | }); 52 | 53 | $(document).on('click', '.cookie-consent-newsletter-modal .modal-inner-wrap', function (event) { 54 | event.stopPropagation() 55 | }); 56 | 57 | function init() { 58 | var consent = cookie.getConsentCookieObject(options.cookie_name); 59 | onClickTab($('#cookie-policy')); 60 | if (consent !== undefined) { 61 | var values = Object.entries(JSON.parse(consent)); 62 | $.each(values, function (index, value) { 63 | if ('cg_' === value[0].substring(0, 3)) { 64 | var checkboxSelector = '.phpro-cookie-consent-modal .consent-tab-content.' + value[0].substring(3, value[0].length) + ' .cookie-toggle input[type="checkbox"]'; 65 | $(checkboxSelector).prop('checked', value[1]); 66 | } 67 | }); 68 | } 69 | } 70 | 71 | function onClickTab(tab) { 72 | $('.consent-tab').each(function () { 73 | $(this).removeClass('active'); 74 | }); 75 | tab.addClass('active'); 76 | $('.consent-tab-content').each(function () { 77 | $(this).css('display', 'none'); 78 | }); 79 | $('.consent-tab-content.' + tab.attr('id')).css('display', 'block'); 80 | } 81 | } 82 | }); 83 | -------------------------------------------------------------------------------- /Ui/DataProvider/CookieGroup/Form/DataProvider.php: -------------------------------------------------------------------------------- 1 | modifiersPool = $modifiersPool; 43 | $this->request = $request; 44 | $this->cookieGroupRepository = $cookieGroupRepository; 45 | $this->collection = $collectionFactory->create(); 46 | parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data); 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | * 52 | * @throws \Magento\Framework\Exception\LocalizedException 53 | */ 54 | public function getData() 55 | { 56 | /** @var ModifierInterface $modifier */ 57 | foreach ($this->modifiersPool->getModifiersInstances() as $modifier) { 58 | $this->data = $modifier->modifyData($this->data); 59 | } 60 | 61 | return $this->data; 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | * 67 | * @throws \Magento\Framework\Exception\LocalizedException 68 | */ 69 | public function getMeta() 70 | { 71 | $meta = parent::getMeta(); 72 | $storeId = $this->request->getParam('store'); 73 | $entityId = $this->request->getParam('entity_id'); 74 | 75 | /** @var ModifierInterface $modifier */ 76 | foreach ($this->modifiersPool->getModifiersInstances() as $modifier) { 77 | $meta = $modifier->modifyMeta($meta); 78 | } 79 | 80 | if ($storeId && $storeId !== 0) { 81 | $defaultModel = $this->cookieGroupRepository->getById((int) $entityId, (int) $storeId); 82 | $currentModel = $this->cookieGroupRepository->getById((int) $entityId, Store::DEFAULT_STORE_ID); 83 | $meta['general']['children']['system_name']['arguments']['data']['config']['disabled'] = true; 84 | $meta['general']['children']['is_essential']['arguments']['data']['config']['disabled'] = true; 85 | $meta['general']['children']['is_active']['arguments']['data']['config']['disabled'] = true; 86 | $meta['general']['children']['name']['arguments']['data']['config']['service']['template'] = 'ui/form/element/helper/service'; 87 | $meta['general']['children']['name']['arguments']['data']['config']['disabled'] = $this->isAttributeDisabled('name', $defaultModel, $currentModel); 88 | $meta['general']['children']['description']['arguments']['data']['config']['service']['template'] = 'ui/form/element/helper/service'; 89 | $meta['general']['children']['description']['arguments']['data']['config']['disabled'] = $this->isAttributeDisabled('description', $defaultModel, $currentModel); 90 | } 91 | 92 | return $meta; 93 | } 94 | 95 | private function isAttributeDisabled(string $attributeCode, CookieGroupInterface $default, CookieGroupInterface $current): bool 96 | { 97 | return $current->getData($attributeCode) === $default->getData($attributeCode); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Model/CookieGroupRepository.php: -------------------------------------------------------------------------------- 1 | resourceModel = $resourceModel; 48 | $this->collectionFactory = $collectionFactory; 49 | $this->searchResultsFactory = $searchResultsFactory; 50 | $this->collectionProcessor = $collectionProcessor; 51 | } 52 | 53 | public function save(CookieGroupInterface $cookieGroup): CookieGroupInterface 54 | { 55 | try { 56 | $this->resourceModel->save($cookieGroup); 57 | } catch (Exception $e) { 58 | throw new CouldNotSaveException(__('Unable to save Cookie Group'), $e); 59 | } 60 | 61 | return $this->getById((int) $cookieGroup->getId()); 62 | } 63 | 64 | public function getById(int $cookieGroupId, int $storeId = null): CookieGroupInterface 65 | { 66 | /** @var Collection $collection */ 67 | $collection = $this->collectionFactory->create(); 68 | 69 | if ($storeId) { 70 | $collection->setStoreId($storeId); 71 | } 72 | 73 | $collection->addAttributeToSelect('*'); 74 | $collection->addFieldToFilter('entity_id', ['eq' => $cookieGroupId]); 75 | $collection->load(); 76 | 77 | $items = $collection->getItems(); 78 | if (count($items) <= 0) { 79 | throw new NoSuchEntityException(__('Requested Cookie Group entity with entity_id "%1" doesn\'t exist.', $cookieGroupId)); 80 | } 81 | 82 | return current($items); 83 | } 84 | 85 | public function getList(SearchCriteriaInterface $searchCriteria): SearchResultsInterface 86 | { 87 | /** @var Collection $collection */ 88 | $collection = $this->collectionFactory->create(); 89 | $collection->addAttributeToSelect('*'); 90 | $this->collectionProcessor->process($searchCriteria, $collection); 91 | 92 | /** @var SearchResultsInterface $searchResults */ 93 | $searchResults = $this->searchResultsFactory->create(); 94 | $searchResults->setSearchCriteria($searchCriteria); 95 | $searchResults->setItems($collection->getItems()); 96 | $searchResults->setTotalCount($collection->getSize()); 97 | 98 | return $searchResults; 99 | } 100 | 101 | public function delete(CookieGroupInterface $cookieGroup): bool 102 | { 103 | try { 104 | $this->resourceModel->delete($cookieGroup); 105 | } catch (Exception $e) { 106 | throw new StateException(__('Unable to remove Cookie Group %1', $cookieGroup->getId())); 107 | } 108 | 109 | return true; 110 | } 111 | 112 | public function deleteById(int $id): bool 113 | { 114 | return $this->delete($this->getById($id)); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Ui/DataProvider/CookieGroup/Form/Modifier/Fields.php: -------------------------------------------------------------------------------- 1 | registry = $registry; 57 | $this->cookieGroupFactory = $cookieGroupFactory; 58 | $this->urlBuilder = $urlBuilder; 59 | $this->attributesHelper = $attributesHelper; 60 | $this->uiComponentHelper = $uiComponentHelper; 61 | $this->resourceConnection = $resourceConnection; 62 | } 63 | 64 | /** 65 | * @return array 66 | * 67 | * @since 100.1.0 68 | */ 69 | public function modifyData(array $data) 70 | { 71 | $model = $this->getModel(); 72 | $parameters = [ 73 | 'id' => $model->getId(), 74 | 'store' => $model->getStoreId(), 75 | ]; 76 | 77 | $submitUrl = $this->urlBuilder->getUrl('phpro_cookie_consent/cookiegroup/save', $parameters); 78 | 79 | return array_replace_recursive( 80 | $data, 81 | [ 82 | 'config' => [ 83 | 'submit_url' => $submitUrl, 84 | 'data' => $model->getData(), 85 | ], 86 | ] 87 | ); 88 | } 89 | 90 | public function modifyMeta(array $meta) 91 | { 92 | $model = $this->getModel(); 93 | 94 | $attributesByGroup = $this->attributesHelper->getAttributes( 95 | CookieGroup::ENTITY, 96 | $model->getDefaultAttributeSetId() 97 | ); 98 | 99 | $groupSortOrder = 0; 100 | 101 | foreach ($attributesByGroup as $groupKey => $attributes) { 102 | $groupSortOrder += 10; 103 | $children = []; 104 | $attributeSortOrder = 0; 105 | /** @var Attribute $attribute */ 106 | foreach ($attributes as $attribute) { 107 | $attributeSortOrder += 10; 108 | $children[$attribute->getAttributeCode()] = $this->uiComponentHelper->createField($attribute, $model, $attributeSortOrder); 109 | } 110 | 111 | if (count($children) <= 0) { 112 | continue; 113 | } 114 | 115 | $meta[$groupKey] = [ 116 | 'arguments' => [ 117 | 'data' => [ 118 | 'config' => [ 119 | 'componentType' => 'fieldset', 120 | 'label' => __(ucfirst($groupKey)), 121 | 'sortOrder' => $groupSortOrder, 122 | 'collapsible' => true, 123 | 'opened' => true, 124 | ], 125 | ], 126 | ], 127 | 'children' => $children, 128 | ]; 129 | } 130 | 131 | return $meta; 132 | } 133 | 134 | public function getModel(): CookieGroup 135 | { 136 | /** @var CookieGroup $model */ 137 | $model = $this->registry->registry('phpro_cookie_consent_cookie_group'); 138 | 139 | return ($model instanceof CookieGroup) ? $model : $this->cookieGroupFactory->create(); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /Helper/AttributesHelper.php: -------------------------------------------------------------------------------- 1 | attributeGroupRepository = $attributeGroupRepository; 56 | $this->attributeRepository = $attributeRepository; 57 | $this->attributeCollectionFactory = $attributeCollectionFactory; 58 | $this->filterBuilder = $filterBuilder; 59 | $this->sortOrderBuilder = $sortOrderBuilder; 60 | $this->searchCriteriaBuilder = $searchCriteriaBuilder; 61 | } 62 | 63 | public function getAttributes(string $entityTypeCode, int $attributeSetId): array 64 | { 65 | /** @var AttributeGroupInterface[] $groups */ 66 | $groups = $this->getGroupsForAttributeSet($attributeSetId); 67 | 68 | $attributes = []; 69 | $groupIds = []; 70 | 71 | foreach ($groups as $group) { 72 | $groupIds[$group->getAttributeGroupId()] = $group->getAttributeGroupCode(); 73 | $attributes[$group->getAttributeGroupCode()] = []; 74 | } 75 | 76 | /** @var AttributeCollection $collection */ 77 | $collection = $this->attributeCollectionFactory->create(); 78 | $collection->setAttributeGroupFilter(array_keys($groupIds)); 79 | 80 | $mapAttributeToGroup = []; 81 | 82 | foreach ($collection->getItems() as $attribute) { 83 | $mapAttributeToGroup[$attribute->getAttributeId()] = $attribute->getAttributeGroupId(); 84 | } 85 | 86 | $sortOrder = $this->sortOrderBuilder 87 | ->setField('sort_order') 88 | ->setAscendingDirection() 89 | ->create(); 90 | 91 | $searchCriteria = $this->searchCriteriaBuilder 92 | ->addFilter(AttributeGroupInterface::GROUP_ID, array_keys($groupIds), 'in') 93 | ->addSortOrder($sortOrder) 94 | ->create(); 95 | 96 | $groupAttributes = $this->attributeRepository->getList($entityTypeCode, $searchCriteria)->getItems(); 97 | 98 | foreach ($groupAttributes as $attribute) { 99 | $attributeGroupId = $mapAttributeToGroup[$attribute->getAttributeId()]; 100 | $attributeGroupCode = $groupIds[$attributeGroupId]; 101 | $attributes[$attributeGroupCode][] = $attribute; 102 | } 103 | 104 | return $attributes; 105 | } 106 | 107 | private function getGroupsForAttributeSet(int $attributeSetId) 108 | { 109 | $attributeGroups = []; 110 | 111 | $this->searchCriteriaBuilder->addFilter( 112 | AttributeGroupInterface::ATTRIBUTE_SET_ID, 113 | $attributeSetId 114 | ); 115 | $searchCriteria = $this->searchCriteriaBuilder->create(); 116 | $attributeGroupSearchResult = $this->attributeGroupRepository->getList($searchCriteria); 117 | 118 | foreach ($attributeGroupSearchResult->getItems() as $group) { 119 | $attributeGroups[$group->getAttributeGroupCode()] = $group; 120 | } 121 | 122 | return $attributeGroups; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Controller/Adminhtml/CookieGroup/Save.php: -------------------------------------------------------------------------------- 1 | dataPersistor = $dataPersistor; 55 | $this->cookieGroupRepository = $cookieGroupRepository; 56 | $this->cookieGroupFactory = $cookieGroupFactory; 57 | $this->storeManager = $storeManager; 58 | } 59 | 60 | public function execute() 61 | { 62 | $id = (int) $this->getRequest()->getParam('entity_id'); 63 | $continueEditing = (bool) $this->getRequest()->getParam('back'); 64 | $data = $this->getRequest()->getPostValue(); 65 | $storeId = (isset($data['store_id'])) ? (int) $data['store_id'] : 0; 66 | 67 | $resultRedirect = $this->resultRedirectFactory->create(); 68 | 69 | // Redirect to the index page if no data was posted: 70 | if (!$data) { 71 | return $resultRedirect->setPath('*/*/'); 72 | } 73 | 74 | try { 75 | $model = $this->findOrCreateModel($id, $storeId); 76 | } catch (Exception $e) { 77 | $this->messageManager->addErrorMessage($e->getMessage() . __('This Cookie Group no longer exists.')); 78 | 79 | return $resultRedirect->setPath('*/*/'); 80 | } 81 | 82 | try { 83 | // Add the POST data to the model 84 | $model->setData($data); 85 | $model->setStoreId($storeId); 86 | // Check "Use Default Value" checkboxes values 87 | if (isset($data['use_default']) && !empty($data['use_default'])) { 88 | foreach ($data['use_default'] as $attributeCode => $attributeValue) { 89 | if ($attributeValue) { 90 | $model->setData($attributeCode, $this->getDefaultModel((int) $data['entity_id'])->getData($attributeCode)); 91 | } 92 | } 93 | } 94 | 95 | // Persist the data 96 | $this->cookieGroupRepository->save($model); 97 | $this->messageManager->addSuccessMessage(__('You saved the Cookie Group.')); 98 | $this->dataPersistor->clear('phpro_cookie_consent_cookie_group'); 99 | 100 | if ($continueEditing) { 101 | return $resultRedirect->setPath('*/*/edit', ['entity_id' => $model->getId(), 'store' => $storeId]); 102 | } 103 | 104 | return $resultRedirect->setPath('*/*/'); 105 | } catch (LocalizedException $e) { 106 | $this->messageManager->addErrorMessage($e->getMessage()); 107 | } catch (Exception $e) { 108 | $this->messageManager->addExceptionMessage($e, __('Something went wrong while saving the Cookie Group.')); 109 | } 110 | 111 | $this->dataPersistor->set('phpro_cookie_consent_cookie_group', $data); 112 | 113 | return $resultRedirect->setPath('*/*/edit', ['entity_id' => $this->getRequest()->getParam('entity_id')]); 114 | } 115 | 116 | private function findOrCreateModel(int $id, $storeId): CookieGroupInterface 117 | { 118 | if (!$id) { 119 | /** @var CookieGroup $model */ 120 | $model = $this->cookieGroupFactory->create(); 121 | 122 | return $model; 123 | } 124 | 125 | return $this->cookieGroupRepository->getById($id, $storeId); 126 | } 127 | 128 | private function getDefaultModel(int $id): CookieGroupInterface 129 | { 130 | if ($this->defaultModel) { 131 | return $this->defaultModel; 132 | } 133 | 134 | $this->defaultModel = $this->cookieGroupRepository->getById($id, Store::DEFAULT_STORE_ID); 135 | 136 | return $this->defaultModel; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /view/adminhtml/ui_component/phpro_cookie_consent_cookie_group_listing.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | phpro_cookie_consent_cookie_group_listing.phpro_cookie_consent_listing_data_source 6 | phpro_cookie_consent_cookie_group_listing.phpro_cookie_consent_listing_data_source 7 | 8 | phpro_cookie_consent_cookie_group_columns 9 | 10 | 11 | add 12 | Add new Cookie Group 13 | primary 14 | */*/new 15 | 16 | 17 | 18 | 19 | 20 | Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider 21 | phpro_cookie_consent_listing_data_source 22 | entity_id 23 | id 24 | 25 | 26 | Magento_Ui/js/grid/provider 27 | 28 | 29 | entity_id 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 20 42 | 43 | text 44 | asc 45 | ID 46 | 47 | 48 | 49 | 50 | 51 | Magento\Config\Model\Config\Source\Yesno 52 | 25 53 | 54 | select 55 | Magento_Ui/js/grid/columns/select 56 | select 57 | select 58 | Essential 59 | 60 | 61 | 62 | 63 | 64 | Magento\Config\Model\Config\Source\Yesno 65 | 30 66 | 67 | select 68 | Magento_Ui/js/grid/columns/select 69 | select 70 | select 71 | Active 72 | 73 | 74 | 75 | 76 | 77 | 35 78 | 79 | text 80 | System name 81 | 82 | 83 | 84 | 85 | 86 | 80 87 | 88 | entity_id 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Helper/UiComponentHelper.php: -------------------------------------------------------------------------------- 1 | arrayManager = $arrayManager; 58 | $this->eavAttributeFactory = $eavAttributeFactory; 59 | $this->scopeOverriddenValue = $scopeOverriddenValue; 60 | $this->backendUrl = $backendUrl; 61 | $this->assetRepo = $assetRepo; 62 | $this->filesystem = $filesystem; 63 | } 64 | 65 | public function createField(AttributeInterface $attribute, EavModelInterface $model, int $sortOrder, array $disabledFields = []) 66 | { 67 | $configPath = 'arguments/data/config'; 68 | 69 | $isDefaultStore = ((int) $model->getStoreId() === Store::DEFAULT_STORE_ID); 70 | $attributeData = $this->arrayManager->set($configPath, [], [ 71 | 'disabled' => !$isDefaultStore && ((bool) $attribute->getIsGlobal()) || in_array($attribute->getAttributeCode(), $disabledFields, true), 72 | 'componentType' => 'field', 73 | 'dataType' => $attribute->getFrontendInput(), 74 | 'formElement' => $this->mapElementType($attribute), 75 | 'required' => $attribute->getIsRequired(), 76 | 'notice' => $attribute->getNote(), 77 | 'default' => $attribute->getDefaultValue(), 78 | 'label' => ($attribute->getDefaultFrontendLabel()) ?? $attribute->getAttributeCode(), 79 | 'sortOrder' => $sortOrder, 80 | ]); 81 | 82 | $attributeModel = $this->getAttributeModel($attribute); 83 | if ($attributeModel->usesSource()) { 84 | $attributeData = $this->arrayManager->merge($configPath, $attributeData, [ 85 | 'options' => $attributeModel->getSource()->getAllOptions(), 86 | ]); 87 | } 88 | 89 | if ($attribute->getIsRequired()) { 90 | $attributeData = $this->arrayManager->merge($configPath, $attributeData, [ 91 | 'validation' => ['required-entry' => true], 92 | ]); 93 | } 94 | 95 | if ($attribute->getAttributeCode() === 'url_key') { 96 | $attributeData = $this->arrayManager->merge($configPath, $attributeData, [ 97 | 'validation' => ['no-whitespace' => true], 98 | ]); 99 | } 100 | 101 | if ($attribute->getFrontendInput() === 'boolean') { 102 | $attributeData = $this->arrayManager->merge($configPath, $attributeData, [ 103 | 'prefer' => 'toggle', 104 | 'checked' => ($attribute->getDefaultValue() === 1) ? true : false, 105 | 'valueMap' => ['true' => '1', 'false' => '0'], 106 | ]); 107 | } 108 | 109 | $attributeData = $this->addUseDefaultValueCheckbox($attribute, $model, $attributeData); 110 | 111 | return $attributeData; 112 | } 113 | 114 | private function getAttributeModel(AttributeInterface $attribute) 115 | { 116 | return $this->eavAttributeFactory->create()->load($attribute->getAttributeId()); 117 | } 118 | 119 | private function addUseDefaultValueCheckbox(AttributeInterface $attribute, EavModelInterface $model, array $meta) 120 | { 121 | $canDisplayService = $this->canDisplayUseDefault($attribute, $model); 122 | if ($canDisplayService) { 123 | $meta['arguments']['data']['config']['service'] = [ 124 | 'template' => 'ui/form/element/helper/service', 125 | ]; 126 | 127 | $meta['arguments']['data']['config']['disabled'] = !$this->scopeOverriddenValue->containsValue( 128 | $model->getEntityType(), 129 | $model, 130 | $attribute->getAttributeCode(), 131 | $model->getStoreId() 132 | ); 133 | } 134 | 135 | return $meta; 136 | } 137 | 138 | private function canDisplayUseDefault(AttributeInterface $attribute, EavModelInterface $model) 139 | { 140 | return 141 | (!(bool) $attribute->getIsGlobal()) 142 | && $model 143 | && $model->getId() 144 | && $model->getStoreId() 145 | ; 146 | } 147 | 148 | private function mapElementType(AttributeInterface $attribute): string 149 | { 150 | $elementType = $attribute->getFrontendInput(); 151 | 152 | if ($elementType === 'text') { 153 | return 'input'; 154 | } 155 | 156 | if ($elementType === 'boolean') { 157 | return 'checkbox'; 158 | } 159 | 160 | if (str_contains($elementType, 'wysiwyg')) { 161 | return 'wysiwyg'; 162 | } 163 | 164 | return $elementType; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /Setup/Patch/Data/DefaultCookieData.php: -------------------------------------------------------------------------------- 1 | cookieGroupFactory = $cookieGroupFactory; 56 | $this->cookieGroupRepository = $cookieGroupRepository; 57 | $this->pageFactory = $pageFactory; 58 | $this->pageRepository = $pageRepository; 59 | $this->blockFactory = $blockFactory; 60 | $this->blockRepository = $blockRepository; 61 | } 62 | 63 | public static function getDependencies() 64 | { 65 | return [ 66 | CookieGroupAttribute::class, 67 | ]; 68 | } 69 | 70 | public function getAliases() 71 | { 72 | return []; 73 | } 74 | 75 | public function apply() 76 | { 77 | $this->createDefaultGroups(); 78 | $this->createDefaultPage(); 79 | $this->createDefaultBlocks(); 80 | } 81 | 82 | private function createDefaultGroups(): void 83 | { 84 | /** @var CookieGroupInterface $group */ 85 | $essential = $this->cookieGroupFactory->create(); 86 | $essential->setStoreId(Store::DEFAULT_STORE_ID); 87 | $essential->setSystemName('essential'); 88 | $essential->setName('Essential'); 89 | $essential->setActive(true); 90 | $essential->setEssential(true); 91 | $essential->setDescription('Essential cookies are strictly necessary to guarantee the proper functioning of the website.'); 92 | 93 | /** @var CookieGroupInterface $group */ 94 | $analytical = $this->cookieGroupFactory->create(); 95 | $analytical->setStoreId(Store::DEFAULT_STORE_ID); 96 | $analytical->setSystemName('analytical'); 97 | $analytical->setName('Analytical'); 98 | $analytical->setActive(true); 99 | $analytical->setEssential(false); 100 | $analytical->setDescription('With this you allow us to collect anonymous data about the use ' . 101 | 'of the website with third party cookies, such as the number of clicks and the behavior of visitors ' . 102 | 'on the website. In addition, we can also perform marketing-related actions via this option.' . PHP_EOL . 103 | 'By activating this cookie, you help us to further improve your experience.'); 104 | 105 | /** @var CookieGroupInterface $group */ 106 | $marketing = $this->cookieGroupFactory->create(); 107 | $marketing->setStoreId(Store::DEFAULT_STORE_ID); 108 | $marketing->setSystemName('marketing'); 109 | $marketing->setName('Marketing'); 110 | $marketing->setActive(true); 111 | $marketing->setEssential(false); 112 | $marketing->setDescription('With this you allow us to collect marketing-related data via third party cookies.' . PHP_EOL . 113 | 'By activating this cookie, you help us to further improve your experience'); 114 | 115 | $this->cookieGroupRepository->save($essential); 116 | $this->cookieGroupRepository->save($analytical); 117 | $this->cookieGroupRepository->save($marketing); 118 | } 119 | 120 | private function createDefaultPage(): void 121 | { 122 | $page = $this->pageFactory->create(); 123 | $page->setStoreId(Store::DEFAULT_STORE_ID); 124 | $page->setIsActive(true); 125 | $page->setPageLayout('1column'); 126 | $page->setTitle('Cookie Consent Overview'); 127 | $page->setIdentifier('consent-overview'); 128 | $page->setContentHeading('Cookie Consent Overview'); 129 | $page->setContent('

{{widget type="Phpro\CookieConsent\Block\Widget\Overview"}}

' . PHP_EOL . 130 | '

{{widget type="Phpro\CookieConsent\Block\Widget\Preferences\Button" preferences_button_type="0"}}

'); 131 | 132 | $this->pageRepository->save($page); 133 | } 134 | 135 | private function createDefaultBlocks(): void 136 | { 137 | $cookiePolicyBlock = $this->blockFactory->create(); 138 | $cookiePolicyBlock->setStoreId(Store::DEFAULT_STORE_ID); 139 | $cookiePolicyBlock->setIsActive(true); 140 | $cookiePolicyBlock->setTitle('Cookie Policy Content'); 141 | $cookiePolicyBlock->setIdentifier('phpro_cookie_consent_cookie_policy_content'); 142 | $cookiePolicyBlock->setContent('

To make our website even better, we use functional and analytical cookies. ' . 143 | 'Information from this website and your preferences are stored in these cookies by your browser.

'); 144 | 145 | $privacyPolicyBlock = $this->blockFactory->create(); 146 | $privacyPolicyBlock->setStoreId(Store::DEFAULT_STORE_ID); 147 | $privacyPolicyBlock->setIsActive(true); 148 | $privacyPolicyBlock->setTitle('Privacy Policy Content'); 149 | $privacyPolicyBlock->setIdentifier('phpro_cookie_consent_privacy_policy_content'); 150 | $privacyPolicyBlock->setContent('

Read more about the use of cookies on this website in our privacy policy.

'); 151 | 152 | $this->blockRepository->save($cookiePolicyBlock); 153 | $this->blockRepository->save($privacyPolicyBlock); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /Model/Eav/ScopeOverriddenValue.php: -------------------------------------------------------------------------------- 1 | attributeRepository = $attributeRepository; 58 | $this->metadataPool = $metadataPool; 59 | $this->searchCriteriaBuilder = $searchCriteriaBuilder; 60 | $this->filterBuilder = $filterBuilder; 61 | $this->resourceConnection = $resourceConnection; 62 | } 63 | 64 | /** 65 | * Whether attribute value is overridden in specific store 66 | * 67 | * @param string $entityType 68 | * @param \Magento\Catalog\Model\AbstractModel $entity 69 | * @param string $attributeCode 70 | * @param int|string $storeId 71 | * 72 | * @throws \Magento\Framework\Exception\LocalizedException 73 | * 74 | * @return bool 75 | */ 76 | public function containsValue($entityType, $entity, $attributeCode, $storeId) 77 | { 78 | if ((int) $storeId === Store::DEFAULT_STORE_ID) { 79 | return false; 80 | } 81 | if ($this->attributesValues === null) { 82 | $this->initAttributeValues($entityType, $entity, (int) $storeId); 83 | } 84 | 85 | return isset($this->attributesValues[$storeId]) 86 | && array_key_exists($attributeCode, $this->attributesValues[$storeId]); 87 | } 88 | 89 | /** 90 | * Get attribute default values 91 | * 92 | * @param string $entityType 93 | * @param \Magento\Catalog\Model\AbstractModel $entity 94 | * 95 | * @throws \Magento\Framework\Exception\LocalizedException 96 | * 97 | * @return array 98 | */ 99 | public function getDefaultValues($entityType, $entity) 100 | { 101 | if ($this->attributesValues === null) { 102 | $this->initAttributeValues($entityType, $entity, (int) $entity->getStoreId()); 103 | } 104 | 105 | return isset($this->attributesValues[Store::DEFAULT_STORE_ID]) 106 | ? $this->attributesValues[Store::DEFAULT_STORE_ID] 107 | : []; 108 | } 109 | 110 | /** 111 | * @param string $entityType 112 | * @param \Magento\Catalog\Model\AbstractModel $entity 113 | * @param int $storeId 114 | * 115 | * @throws \Magento\Framework\Exception\LocalizedException 116 | * 117 | * @return void 118 | */ 119 | private function initAttributeValues($entityType, $entity, $storeId) 120 | { 121 | $metadata = $this->metadataPool->getMetadata($entityType); 122 | /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */ 123 | $attributeTables = []; 124 | if ($metadata->getEavEntityType()) { 125 | foreach ($this->getAttributes($entityType) as $attribute) { 126 | if (!$attribute->isStatic()) { 127 | $attributeTables[$attribute->getBackend()->getTable()][] = $attribute->getAttributeId(); 128 | } 129 | } 130 | $storeIds = [Store::DEFAULT_STORE_ID]; 131 | if ($storeId !== Store::DEFAULT_STORE_ID) { 132 | $storeIds[] = $storeId; 133 | } 134 | $selects = []; 135 | foreach ($attributeTables as $attributeTable => $attributeCodes) { 136 | $select = $metadata->getEntityConnection()->select() 137 | ->from(['t' => $attributeTable], ['value' => 't.value', 'store_id' => 't.store_id']) 138 | ->join( 139 | ['a' => $this->resourceConnection->getTableName('eav_attribute')], 140 | 'a.attribute_id = t.attribute_id', 141 | ['attribute_code' => 'a.attribute_code'] 142 | ) 143 | ->where($metadata->getLinkField() . ' = ?', $entity->getData($metadata->getLinkField())) 144 | ->where('t.attribute_id IN (?)', $attributeCodes) 145 | ->where('t.store_id IN (?)', $storeIds); 146 | $selects[] = $select; 147 | } 148 | 149 | $unionSelect = new \Magento\Framework\DB\Sql\UnionExpression( 150 | $selects, 151 | \Magento\Framework\DB\Select::SQL_UNION_ALL 152 | ); 153 | $attributes = $metadata->getEntityConnection()->fetchAll((string) $unionSelect); 154 | foreach ($attributes as $attribute) { 155 | $this->attributesValues[$attribute['store_id']][$attribute['attribute_code']] = $attribute['value']; 156 | } 157 | } 158 | } 159 | 160 | /** 161 | * @param string $entityType 162 | * 163 | * @throws \Exception 164 | * 165 | * @return \Magento\Eav\Api\Data\AttributeInterface[] 166 | */ 167 | private function getAttributes($entityType) 168 | { 169 | $metadata = $this->metadataPool->getMetadata($entityType); 170 | $searchResult = $this->attributeRepository->getList( 171 | $metadata->getEavEntityType(), 172 | $this->searchCriteriaBuilder->addFilters( 173 | [ 174 | $this->filterBuilder 175 | ->setField('backend_type') 176 | ->setConditionType('neq') 177 | ->setValue('static') 178 | ->create(), 179 | ] 180 | )->create() 181 | ); 182 | 183 | return $searchResult->getItems(); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /view/frontend/web/css/source/_module.less: -------------------------------------------------------------------------------- 1 | // 2 | // Common 3 | // _____________________________________________ 4 | 5 | & when (@media-common = true) { 6 | // 7 | // Notice bar 8 | // --------------------------------------------- 9 | .phpro-cookie-notice { 10 | width: 100vw; 11 | padding: 30px; 12 | background: @color-gray_light; 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | right: 0; 17 | z-index: 900; 18 | 19 | .notice-wrapper { 20 | display: flex; 21 | flex-direction: column; 22 | max-width: @layout__max-width; 23 | margin: auto; 24 | justify-content: space-around; 25 | align-items: center; 26 | 27 | .notice__description { 28 | span { 29 | display: block; 30 | } 31 | } 32 | } 33 | } 34 | 35 | // 36 | // Preferences popup 37 | // --------------------------------------------- 38 | .modals-wrapper { 39 | .modal-popup.cookie-consent-newsletter-modal { 40 | .modal-inner-wrap { 41 | background-color: @color-gray_light; 42 | 43 | .modal-header { 44 | height: 0; 45 | padding: 0; 46 | 47 | .action-close:before { 48 | color: @color-black; 49 | } 50 | } 51 | 52 | .modal-content { 53 | padding-left: 0; 54 | padding-right: 0; 55 | } 56 | 57 | .phpro-cookie-consent-modal { 58 | display: flex; 59 | flex-direction: column; 60 | 61 | .consent-tabs { 62 | display: inline-block; 63 | vertical-align: top; 64 | width: 100%; 65 | 66 | .consent-tab { 67 | background-color: @color-gray_light; 68 | width: 100%; 69 | cursor: pointer; 70 | padding: 5px 5px 5px 20px; 71 | box-shadow: 0 5px 10px 0 rgba(0,0,0,.1); 72 | position: relative; 73 | z-index: 10; 74 | 75 | &.active { 76 | background-color: @theme__color__primary; 77 | } 78 | 79 | span { 80 | font-weight: 700; 81 | } 82 | } 83 | 84 | &-content { 85 | display: inline-block; 86 | vertical-align: top; 87 | background-color: @color-white; 88 | padding: 20px 20px 0; 89 | 90 | .consent-tab-content { 91 | position: relative; 92 | 93 | p.title { 94 | margin-bottom: 20px; 95 | font-size: @font-size__l; 96 | } 97 | 98 | .cookie-toggle-wrapper { 99 | position: absolute; 100 | right: 0; 101 | top: 0; 102 | 103 | .cookie-toggle { 104 | position: relative; 105 | display: inline-block; 106 | width: 60px; 107 | height: 34px; 108 | 109 | input { 110 | display: none; 111 | 112 | &:checked + .cookie-toggle-slider { 113 | background-color: @theme__color__primary; 114 | } 115 | 116 | &:focus + .cookie-toggle-slider { 117 | box-shadow: 0 0 1px @theme__color__primary; 118 | } 119 | 120 | &:checked + .cookie-toggle-slider:before { 121 | -webkit-transform: translateX(26px); 122 | -ms-transform: translateX(26px); 123 | transform: translateX(26px); 124 | } 125 | } 126 | 127 | .cookie-toggle-slider { 128 | position: absolute; 129 | cursor: pointer; 130 | top: 0; 131 | left: 0; 132 | right: 0; 133 | bottom: 0; 134 | -webkit-transition: .4s; 135 | transition: .4s; 136 | border-radius: 34px; 137 | background-color: @color-very-dark-gray; 138 | 139 | &:before { 140 | position: absolute; 141 | content: ""; 142 | height: 26px; 143 | width: 26px; 144 | left: 4px; 145 | bottom: 4px; 146 | background-color: white; 147 | -webkit-transition: .4s; 148 | transition: .4s; 149 | border-radius: 50%; 150 | } 151 | 152 | &.disabled { 153 | opacity: 0.5; 154 | } 155 | } 156 | } 157 | } 158 | } 159 | } 160 | } 161 | } 162 | 163 | .modal-footer { 164 | text-align: right; 165 | background-color: @color-white; 166 | } 167 | } 168 | } 169 | } 170 | 171 | // 172 | // Cookie overview widget 173 | // --------------------------------------------- 174 | .cookie-consent-overview { 175 | p.title { 176 | margin-bottom: 20px; 177 | } 178 | 179 | .cookie-group-description { 180 | margin-bottom: 30px; 181 | } 182 | } 183 | 184 | // 185 | // Cookie preferences button widget 186 | // --------------------------------------------- 187 | .btn-cookie-preferences-show { 188 | cursor: pointer; 189 | } 190 | } 191 | 192 | // 193 | // Desktop 194 | // _____________________________________________ 195 | 196 | .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { 197 | // 198 | // Notice bar 199 | // --------------------------------------------- 200 | .phpro-cookie-notice { 201 | .notice-wrapper { 202 | flex-direction: row; 203 | } 204 | } 205 | 206 | // 207 | // Preferences popup 208 | // --------------------------------------------- 209 | .modals-wrapper { 210 | .modal-popup.cookie-consent-newsletter-modal { 211 | .modal-inner-wrap { 212 | background-color: @color-gray_light; 213 | 214 | .modal-content { 215 | padding-left: 0; 216 | } 217 | 218 | .phpro-cookie-consent-modal { 219 | flex-direction: row; 220 | 221 | .consent-tabs { 222 | width: 20%; 223 | padding-left: 3%; 224 | background-color: @color-white; 225 | padding-top: 30px; 226 | 227 | .consent-tab { 228 | width: 80%; 229 | border: 2px solid @theme__color__primary; 230 | border-radius: 3px; 231 | padding: 5px; 232 | margin-bottom: 20px; 233 | background-color: @color-white; 234 | box-shadow: none; 235 | } 236 | 237 | &-content { 238 | background-color: @color-gray_light; 239 | width: 65%; 240 | padding-top: 30px; 241 | padding-left: 30px; 242 | padding-bottom: 50px; 243 | } 244 | } 245 | } 246 | 247 | .modal-footer { 248 | height: 0; 249 | padding: 0; 250 | text-align: right; 251 | margin-right: 20px; 252 | 253 | .consent-btn { 254 | margin: -100px 0 0 0; 255 | } 256 | } 257 | } 258 | } 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /view/adminhtml/ui_component/phpro_cookie_consent_cookie_group_form.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | phpro_cookie_consent_cookie_group_form.cookie_group_form_data_source 6 | 7 | General Information 8 | templates/form/collapsible 9 | 10 | 11 | 12 |