etracker-8.x-3.x-dev/modules/cookies_etracker/cookies_etracker.module
modules/cookies_etracker/cookies_etracker.module
<?php
/**
* @file
* Contains cookies_etracker.module.
*/
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\etracker\Helper\Constants;
/**
* Implements hook_help().
*/
function cookies_etracker_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the cookies_etracker module.
case 'help.page.cookies_etracker':
return t('
<h3>About</h3>
<p>Submodule to manage cookies consent provided by COOKiES and
eTracker tracking behavior if a user should be tracked or not.</p>
<h4>Options explanations</h4>
<p>This module introduces the following options for handling tracking and consent behavior.</p>
<dl>
<dt>Most accuracy</dt>
<dd>Tracks user <em>without cookies</em>, before any consent is confirmed. Tracks user <em>with cookies</em>, after consent is confirmed.</dd>
<dt>Most privacy</dt>
<dd>Does <em>not track user before</em> any consent is confirmed. Tracks <em>without cookies</em>, after consent is confirmed.</dd>
<dt>Mixed</dt>
<dd>Does <em>not track user before</em> any consent is confirmed. Tracks <em>with cookies</em> after consent is confirmed.</dd>
<dt>Ignore consent</dt>
<dd>Tracks user without cookies, ignores any consent confirmationSah. Just the same behavior as without <em>cookies_etracker</em> installed.</dd>
</dl>');
}
}
/**
* Implements hook_library_info_alter().
*/
function cookies_etracker_library_info_alter(array &$libraries, string $extension): void {
$eTrackerConfig = \Drupal::config(Constants::ETRACKER_SETTINGS_CONFIG_NAME);
$etracker_script_settings = $eTrackerConfig->get('etracker_script_settings');
if (empty($etracker_script_settings['data_block_cookies'])) {
// Cookie blocking is completely disabled.
// No cookies_etracker action required. Do nothing.
return;
}
// Cookie blocking is enabled!
$doKo = \Drupal::service('cookies.knock_out')->doKnockOut();
if ($doKo && isset($libraries[Constants::ETRACKER_LIBRARY_NAME])) {
$cookiesEtrackerConfig = \Drupal::config('cookies_etracker.settings');
$knockout_mode = $cookiesEtrackerConfig->get('knockout_mode');
// Cookie blocking is enabled!
switch ($knockout_mode) {
case 'knockout_without_consent_block_cookies_false':
case 'knockout_without_consent_block_cookies_true':
// Preprocess libraries for knockout healing:
if (!empty($libraries[Constants::ETRACKER_LIBRARY_NAME]['js']['js/etracker.js'])) {
// Avoid that the javascript you want to knock-out will be combined.
$libraries[Constants::ETRACKER_LIBRARY_NAME]['js']['js/etracker.js']['preprocess'] = FALSE;
// Prevent JS execution. src attribute will be ignored this way:
$libraries[Constants::ETRACKER_LIBRARY_NAME]['js']['js/etracker.js']['attributes'] = array_merge($libraries[Constants::ETRACKER_LIBRARY_NAME]['js']['js/etracker.js']['attributes'], [
'id' => 'etracker_script',
'type' => 'application/json',
]);
}
// Merge some attributes to prepare the script tag.
$libraries[Constants::ETRACKER_LIBRARY_NAME]['js'][Constants::ETRACKER_JS_URL]['attributes'] = array_merge($libraries[Constants::ETRACKER_LIBRARY_NAME]['js'][Constants::ETRACKER_JS_URL]['attributes'], [
'id' => '_etLoader',
// Prevent JS execution. src attribute will be ignored this way:
'type' => 'application/json',
]);
return;
case 'block_cookies_true_without_consent':
// No library alteration required.
return;
case 'block_cookies_true':
// Cookie blocking is permanently enabled.
// This is already being handled in etracker.module.
// No cookies_etracker action required. Do nothing.
return;
}
}
}
/**
* Implements hook_page_attachments().
*/
function cookies_etracker_page_attachments(array &$page): void {
$eTrackerConfig = \Drupal::config(Constants::ETRACKER_SETTINGS_CONFIG_NAME);
if (!_etracker_request_should_be_tracked($eTrackerConfig)) {
// eTracker is not tracking, so we also shouldn't do anything here:
return;
}
$etracker_script_settings = $eTrackerConfig->get('etracker_script_settings');
if (empty($etracker_script_settings['data_block_cookies'])) {
// Cookie blocking is completely disabled.
// No cookies_etracker action required. Do nothing.
return;
}
// Cookie blocking is enabled!
$doKo = \Drupal::service('cookies.knock_out')->doKnockOut();
if ($doKo) {
$cookiesEtrackerConfig = \Drupal::config('cookies_etracker.settings');
$knockout_mode = $cookiesEtrackerConfig->get('knockout_mode');
// Cookie blocking is enabled!
switch ($knockout_mode) {
case 'knockout_without_consent_block_cookies_true':
case 'knockout_without_consent_block_cookies_false':
// Make the settings available in JS:
$script_settings = [
'knockout_mode' => $knockout_mode,
];
$page['#attached']['drupalSettings']['cookies_etracker'] = $script_settings;
// Heal the libraries knockout in JavaScript:
$page['#attached']['library'][] = 'cookies_etracker/knockout_without_consent';
return;
case 'block_cookies_true_without_consent':
// Enable cookies in JavaScript after consent was given:
$page['#attached']['library'][] = 'cookies_etracker/block_cookies_true_without_consent';
return;
case 'block_cookies_true':
// Cookie blocking is permanently enabled.
// This is already being handled in etracker.module.
// No cookies_etracker action required. Do nothing.
return;
}
// We should never reach here, as all cases should have been matched.
// If we get here, something must be wrong with the chosen $knockout_mode.
// So we better log a warning to recognize this:
\Drupal::logger('cookies_etracker')->warning('Unknown cookies_etracker knockout mode: @knockout_mode. This should not happen.', ['@knockout_mode' => $knockout_mode]);
}
}
/**
* Implements hook_form_MODULE_admin_settings_alter().
*/
function cookies_etracker_form_etracker_admin_settings_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
// Show a warning if cookies_etracker module is enabled,
// but "Disable cookies" setting is false:
$etrackerConfig = \Drupal::config('etracker.settings');
$etracker_script_settings = $etrackerConfig->get('etracker_script_settings');
if (empty($etracker_script_settings['data_block_cookies'])) {
\Drupal::messenger()->addWarning(t('You have enabled the COOKiES eTracker (sub)module, but your "Privacy: Disable cookies" setting is not checked.
<br /><strong>COOKiES eTracker will not block anything this way!</strong>'));
}
$config = \Drupal::config('cookies_etracker.settings');
// Add options for eTracker cookie handling:
$form['tracking']['privacy']['knockout'] = [
'#type' => 'details',
'#open' => TRUE,
'#title' => t('Advanced "Disable cookies" handling'),
];
$form['tracking']['privacy']['knockout']['knockout_mode'] = [
'#type' => 'radios',
'#title' => t('Blocking mode'),
'#description' => t('Additional options provided by the <em>cookies_etracker</em> integration for eTracker cookie handling based on COOKiES cookie consent. eTracker knocked-out means the eTracker tracking snippet is not run and the user is not tracked at all until condition is met.'),
'#options' => [
'block_cookies_true_without_consent' => t('<strong>Most accuracy</strong><br/>eTracker tracking <em>enabled</em> without cookies <code>[data-block-cookies=true]</code> <em>before COOKiES consent</em>. eTracker tracking enabled with cookies <code>[data-block-cookies=false]</code> <em>after COOKiES consent</em>.'),
'knockout_without_consent_block_cookies_true' => t('<strong>Most privacy</strong><br/>eTracker tracking <em>disabled</em> (knocked-out) <em>before COOKiES consent</em>. eTracker tracking enabled without cookies <code>[data-block-cookies=true]</code> <em>after COOKiES consent</em>.'),
'knockout_without_consent_block_cookies_false' => t('<strong>Mixed</strong><br/>eTracker tracking <em>disabled</em> (knocked-out) <em>before COOKiES consent</em>. eTracker tracking enabled with cookies <code>[data-block-cookies=false]</code> <em>after COOKiES consent</em>.'),
'block_cookies_true' => t('<strong>Ignore consent</strong><br/>eTracker tracking <em>always enabled</em>, without cookies <code>[data-block-cookies=true]</code>. <em>Same behavior as without cookies_etracker installed.</em>'),
],
'#default_value' => $config->get('knockout_mode'),
'#states' => [
'visible' => [
':input[name="data_block_cookies"]' => ['checked' => TRUE],
],
],
];
// Show information if "Disable Cookies is checked":
$form['tracking']['privacy']['knockout']['knockout_mode_info'] = [
'#type' => 'item',
'#title' => t('Blocking mode'),
'#markup' => '<div class="messages messages--warning"><p>'
. t('You have enabled the COOKiES eTracker submodule, but your "Privacy: Disable cookies" setting is not checked. <br /><strong>COOKiES eTracker will not block anything this way!</strong>') . '</p><p>'
. t('With "Disable cookies" unchecked, eTracker uses cookies enabled mode [data-block-cookies="false"]. Uncheck to enable cookie blocking and see COOKiES eTracker advanced options.') . '</p></div>',
'#description' => t('Additional options provided by the cookies_etracker submodule for eTracker cookie handling based on COOKiES cookie consent.'),
'#states' => [
'visible' => [
':input[name="data_block_cookies"]' => ['checked' => FALSE],
],
],
];
$form['#submit'][] = '_cookies_etracker_form_etracker_admin_settings_save';
}
/**
* Cookies etracker save helper.
*
* @param array $form
* The form array.
* @param Drupal\Core\Form\FormStateInterface $form_state
* The form state object.
*/
function _cookies_etracker_form_etracker_admin_settings_save(array &$form, FormStateInterface $form_state): void {
$config = \Drupal::service('config.factory')->getEditable('cookies_etracker.settings');
$config->set('knockout_mode', $form_state->getValue('knockout_mode'))->save();
}
