EU cookie implementation in Drupal 8

We have recently been working on a Drupal 8 project for a European client. We have had the opportunity to implement numerous interesting functionalities in Drupal 8. 

DRUPAL1
In this blog we are going to talk about one such functionality. We were required to implement EU cookie functionality in Drupal 8. EU cookie is mandatory for all European websites. There are many solutions available online to implement this feature, I used JavaScript for this task and it worked like a charm.
This is how it works.
 
First we need to get the required JavaScript code from https://cookieconsent.insites.com/ as per our required consent popup. Once the code is retrieved, we need to convert this plain JavaScript into the Drupal 8 format.
 
For our implementation we needed to create a configuration form for settings. Along with that we were also required to add configuration to change scroll length after which the cookie popup would disappear. To make it EU specific we had to get the continent code from the API.
 

Step 1: Create form.php in src/form containing form of settings in your module:

<?php
/**
* @file
* Contains \Drupal\module\Form\SettingsForm.
*/
namespace Drupal\module\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Form builder for the module basic settings form.
*/
class SettingsForm extends ConfigFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'module_settings_form';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['module.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('module .settings');
$form['activate'] = array(
'#type' => 'checkbox',
'#title' => $this->t('Activate Cookie Consent'),
'#default_value' => $config->get('activate'),
'#description' => $this->t('Cookie consent notification for site can be enabled or disabled from here.'),
);
$form['eu_consent_pop_msg'] = array(
'#type' => 'textarea',
'#title' => $this->t('Set message for cookie consent popup'),
'#default_value' => $config->get('eu_consent_pop_msg'),
'#description' => $this->t('Cookie consent pop up message can be set from here.'),
);
$form['eu_consent_pop_scroll'] = array(
'#type' => 'textfield',
'#title' => $this->t('Set scroll length (pixels)'),
'#default_value' => $config->get('eu_consent_pop_scroll'),
'#description' => $this->t('Set after scrolling how many pixels the popup should disappear. Ex: 500'),
);
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$config = $this->config('module.settings');
$config->set('activate', $form_state->getValue('activate'));
$config->set('eu_consent_pop_msg', $form_state->getValue('eu_consent_pop_msg'));
$config->set('eu_consent_pop_scroll', $form_state->getValue('eu_consent_pop_scroll'));
$config->save();
}
}
 

Step 2: Define a controller in module/src/controller. This will have functions that retrieve country code from API. The config setting determines if EU cookie is enabled or not:

<?php
/**
* @file
* Contains \Drupal\module\Controller\EuCookie.
*/
namespace Drupal\module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use GuzzleHttp\Client;
/**
* Class EuCookie.
*
* @package Drupal\module\Controller
*/
class EuCookie extends ControllerBase {
/**
* Autocomplete.
*/
public function continent() {
$ip_eu_consent = \Drupal::request()->getClientIp();
$config_status = \Drupal::config('module .settings')->get('activate');
if($config_status == 1) {
$continent_code['consent'] = $this::eucookie_get_country_code($ip_eu_consent);
if (\Drupal::currentUser()->isAnonymous()) {
$continent_code['isanon'] = true;
} else {
$continent_code['isanon'] = false;
}
}
return JsonResponse::create($continent_code);
}
/**
* Get continent code from external free service for eu consent.
*/
function eucookie_get_country_code($ip_eu_consent) {
try {
$uri = 'http://www.geoplugin.net/json.gp?ip=' . $ip_eu_consent;
$client = \Drupal::httpClient(['base_url' => $uri]);
$request = $client->request('GET', $uri, ['timeout' => 5, 'headers' => ['Accept' => 'application/json']]);
if ($request->getStatusCode() == 200) {
$response = json_decode($request->getBody());
if (empty($response)) {
return [];
}
else {
return ($response->geoplugin_continentCode);
}
}
else {
return [];
}
}
catch (\GuzzleHttp\Exception\ClientException $e) {
$message = $e->getMessage() . '. Make sure you provided correct IP to get country code .';
\Drupal::logger('module_get_country_code')->notice($message);
return [];
}
}
}
 

Step 3: Add hook page attachment alter to get variables defined in config and send them to js:

<?php
function hook_page_attachments_alter(&$page) {
$ip_eu_consent = \Drupal::request()->getClientIp();
$config_status = \Drupal::config('module.settings')->get('activate');
$mesage_consent = \Drupal::config('module.settings')->get('eu_consent_pop_msg');
$scroll_length = \Drupal::config('module.settings')->get('eu_consent_pop_scroll');
if($config_status == 1) {
 
 
$page['#attached']['library'][] = 'path to library';
$page['#attached']['drupalSettings']['message_eu_consent'] = $mesage_consent;
$page['#attached']['drupalSettings']['eu_consent_pop_scroll'] = $scroll_length;
}
}
?>

Step 4: Routing file, with route to retrieve settings form and get the continent code via ajax:

module.admin_settings:
path: '/admin/config/eucookie'
defaults:
_form: '\Drupal\module\Form\SettingsForm'
_title: 'EUCookie settings'
requirements:
_permission: 'administer site configuration'
module.ajax_continent:
path: '/ajax/continent'
defaults:
_controller: '\Drupal\module\Controller\EuCookie::continent'
_title: 'ajax continent'
requirements:
_permission: 'access content'

Step 5: Add js below in custom/js as condition for scroll, get defined variables from config and display EU cookie popup.

(function($) {
'use strict';
Drupal.behaviors.moduleeuconsent = {
attach: function(context, settings) {
$(document).scroll(function() {
var scroll_len = drupalSettings.eu_consent_pop_scroll;
var scrollBottom = $(window).scrollTop() + $(window).height();
scrollBottom > scroll_len ? $('.cc-window').fadeOut() : $('.cc-window').fadeIn();
});
var msg = drupalSettings..message_eu_consent;
$.ajax({url: "/ajax/continent", success: function(result){
if (result['consent'] == 'EU' && result['isanon']==true) {
window.cookieconsent.initialise({
palette: {
popup: {
background: '#252e39'
},
button: {
background: '#14a7d0'
}
},
content: {
message: msg,
dismiss: 'Close',
link: 'Show Cookie Policy'
}
});
}
}});
}
};
}(jQuery));
 

Step 6: External js needs to be defined in libraries.yml which creates popup

module_lib:
version: v3.14
css:
theme:
//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.1/cookieconsent.min.css: { type: external }
js:
//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.1/cookieconsent.min.js: { type: external, scope: footer }
js/module.js: { scope: footer }
dependencies:
- core/jquery
- core/drupal
- core/drupalSettings
 
And hence the EU Cookie functionality will be implemented in your Drupal 8 website. Please do comment if you have any feedback or if this code does not work for you.
 
EU cookie
cookie drupal 8
d8 cookie

Get in Touch

Get Aggregated Monthly Industry News