Skip to content

Commit 4b4c10d

Browse files
committed
Add video blocker config, DEV-1111
Signed-off-by: Iman Aboheydary <[email protected]>
1 parent 33c1998 commit 4b4c10d

File tree

7 files changed

+175
-132
lines changed

7 files changed

+175
-132
lines changed

Model/Config.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Config
1414
public const XML_PATH_DATA_CULTURE = 'web/cookiebot/data_culture';
1515
public const XML_PATH_USE_EU_CDN = 'web/cookiebot/use_eu_cdn';
1616
public const XML_PATH_USE_GOOGLE_CONSENT_MODE = 'web/cookiebot/use_google_consent_mode';
17+
public const XML_PATH_BLOCK_VIDEOS_UNTIL_CONSENT = 'web/cookiebot/block_videos_until_consent';
1718

1819
/**
1920
* @var ScopeConfigInterface
@@ -49,4 +50,9 @@ public function isGoogleConsentModeEnabled(): bool
4950
{
5051
return $this->scopeConfig->isSetFlag(self::XML_PATH_USE_GOOGLE_CONSENT_MODE, ScopeInterface::SCOPE_STORE);
5152
}
53+
54+
public function isBlockVideosUntilConsentEnabled(): bool
55+
{
56+
return $this->scopeConfig->isSetFlag(self::XML_PATH_BLOCK_VIDEOS_UNTIL_CONSENT, ScopeInterface::SCOPE_STORE);
57+
}
5258
}

ViewModel/Script.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ public function isGoogleConsentModeEnabled(): bool
3939
{
4040
return $this->config->isGoogleConsentModeEnabled();
4141
}
42+
43+
public function isBlockVideosUntilConsentEnabled(): bool
44+
{
45+
return $this->config->isBlockVideosUntilConsentEnabled();
46+
}
4247
}

etc/adminhtml/system.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
<label>Google Consent Mode</label>
3030
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
3131
</field>
32+
<field id="block_videos_until_consent" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
33+
<label>Block YouTube / Vimeo Videos Until Marketing Consent</label>
34+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
35+
</field>
3236
</group>
3337
</section>
3438
</system>

etc/config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<data_culture/>
1010
<use_eu_cdn>0</use_eu_cdn>
1111
<use_google_consent_mode>1</use_google_consent_mode>
12+
<block_videos_until_consent>0</block_videos_until_consent>
1213
</cookiebot>
1314
</web>
1415
</default>

view/frontend/layout/default.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@
77
<argument name="view_model" xsi:type="object">CustomGento\Cookiebot\ViewModel\Script</argument>
88
</arguments>
99
</block>
10+
<block name="customgento.cookiebot.config" template="CustomGento_Cookiebot::config.phtml">
11+
<arguments>
12+
<argument name="view_model" xsi:type="object">CustomGento\Cookiebot\ViewModel\Script</argument>
13+
</arguments>
14+
</block>
1015
</referenceBlock>
1116
<referenceContainer name="before.body.end">
12-
<block name="customgento.cookiebot.iframe.handler" template="CustomGento_Cookiebot::iframe-handler.phtml" />
17+
<block name="customgento.cookiebot.iframe.handler" template="CustomGento_Cookiebot::iframe-handler.phtml">
18+
<arguments>
19+
<argument name="view_model" xsi:type="object">CustomGento\Cookiebot\ViewModel\Script</argument>
20+
</arguments>
21+
</block>
1322
</referenceContainer>
1423
</body>
1524
</page>
Lines changed: 100 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,118 @@
11
<?php
22

33
use Magento\Framework\View\Helper\SecureHtmlRenderer;
4+
use CustomGento\Cookiebot\ViewModel\Script;
45

56
/** @var SecureHtmlRenderer $secureRenderer */
7+
/** @var Script $viewModel */
8+
$viewModel = $block->getData('view_model');
69

7-
$addRequiredAttributesScript = '
8-
document.addEventListener("DOMContentLoaded", function() {
9-
const videoIframes = document.querySelectorAll(".pagebuilder-video-container iframe");
10-
11-
videoIframes.forEach((iframe) => {
12-
if (!Cookiebot?.consent?.marketing) {
13-
iframe.setAttribute("data-cookieblock-src", iframe.src);
14-
iframe.setAttribute("data-cookieconsent", "marketing");
15-
iframe.removeAttribute("src");
16-
iframe.closest("[data-content-type=\"video\"]").setAttribute("data-content-type", "image");
17-
}
10+
// Only add scripts if video blocking is enabled
11+
if ($viewModel && $viewModel->isBlockVideosUntilConsentEnabled()) {
12+
$addRequiredAttributesScript = '
13+
document.addEventListener("DOMContentLoaded", function() {
14+
const videoIframes = document.querySelectorAll(".pagebuilder-video-container iframe");
15+
16+
videoIframes.forEach((iframe) => {
17+
if (!Cookiebot?.consent?.marketing) {
18+
iframe.setAttribute("data-cookieblock-src", iframe.src);
19+
iframe.setAttribute("data-cookieconsent", "marketing");
20+
iframe.removeAttribute("src");
21+
iframe.closest("[data-content-type=\"video\"]").setAttribute("data-content-type", "image");
22+
}
23+
});
1824
});
19-
});
2025
21-
addEventListener("CookiebotOnAccept", () => {
22-
const videoIframes = document.querySelectorAll(".pagebuilder-video-container iframe");
23-
24-
videoIframes.forEach((iframe) => {
25-
if (Cookiebot?.consent?.marketing) {
26-
if (iframe.closest("[data-content-type=\"image\"]")) {
27-
iframe.closest("[data-content-type=\"image\"]").setAttribute("data-content-type", "video");
26+
addEventListener("CookiebotOnAccept", () => {
27+
const videoIframes = document.querySelectorAll(".pagebuilder-video-container iframe");
28+
29+
videoIframes.forEach((iframe) => {
30+
if (Cookiebot?.consent?.marketing) {
31+
if (iframe.closest("[data-content-type=\"image\"]")) {
32+
iframe.closest("[data-content-type=\"image\"]").setAttribute("data-content-type", "video");
33+
}
2834
}
29-
}
35+
});
3036
});
31-
});
3237
33-
addEventListener("CookiebotOnDecline", () => {
34-
const videoIframes = document.querySelectorAll(".pagebuilder-video-container iframe");
35-
36-
videoIframes.forEach((iframe) => {
37-
if (!Cookiebot?.consent?.marketing) {
38-
if (iframe.closest("[data-content-type=\"video\"]")) {
39-
iframe.closest("[data-content-type=\"video\"]").setAttribute("data-content-type", "image");
38+
addEventListener("CookiebotOnDecline", () => {
39+
const videoIframes = document.querySelectorAll(".pagebuilder-video-container iframe");
40+
41+
videoIframes.forEach((iframe) => {
42+
if (!Cookiebot?.consent?.marketing) {
43+
if (iframe.closest("[data-content-type=\"video\"]")) {
44+
iframe.closest("[data-content-type=\"video\"]").setAttribute("data-content-type", "image");
45+
}
4046
}
41-
}
47+
});
4248
});
43-
});
44-
';
49+
';
4550

46-
$placeholderScript = '
47-
document.addEventListener("DOMContentLoaded", function() {
48-
((document, selector, consentType) => {
49-
const createTextNode = text => document.createTextNode(text);
50-
const createElement = element => document.createElement(element);
51-
console.log("here");
52-
document.querySelectorAll(selector).forEach(iframe => {
53-
const linkElement = createElement("a");
54-
const divElement = createElement("div");
55-
const paragraphElement = createElement("p");
56-
const iframeSrc = iframe.dataset.cookieblockSrc;
57-
58-
// Detect service provider type
59-
const serviceProvider =
60-
/google\.com\/maps\/embed/.test(iframeSrc) ? "Google Maps" :
61-
/player\.vimeo\.com\/video\//.test(iframeSrc) ? "Vimeo" :
62-
/youtube(-nocookie)?\.com\/embed\//.test(iframeSrc) ? "YouTube" :
63-
undefined;
64-
65-
if (!serviceProvider) {
66-
return;
67-
}
68-
69-
const iframeHeight = iframe.getBoundingClientRect().height;
70-
const iframeWidth = iframe.getBoundingClientRect().width;
71-
72-
// Create placeholder content
73-
divElement.innerHTML = `
74-
<div style="background-color:#CCC;display:inline-block;height:${iframeHeight}px;position:relative;width:${iframeWidth}px;">
75-
<div style="background-color:#848484;border-radius:15px;height:50%;position:absolute;transform:translate(50%,50%);width:50%;">
76-
<p style="color:#FFF;font-size:7.5em;position:relative;top:50%;left:50%;margin:0;text-align:center;transform:translate(-50%,-50%);">&ctdot;</p>
51+
$placeholderScript = '
52+
document.addEventListener("DOMContentLoaded", function() {
53+
((document, selector, consentType) => {
54+
const createTextNode = text => document.createTextNode(text);
55+
const createElement = element => document.createElement(element);
56+
console.log("here");
57+
document.querySelectorAll(selector).forEach(iframe => {
58+
const linkElement = createElement("a");
59+
const divElement = createElement("div");
60+
const paragraphElement = createElement("p");
61+
const iframeSrc = iframe.dataset.cookieblockSrc;
62+
63+
// Detect service provider type
64+
const serviceProvider =
65+
/google\.com\/maps\/embed/.test(iframeSrc) ? "Google Maps" :
66+
/player\.vimeo\.com\/video\//.test(iframeSrc) ? "Vimeo" :
67+
/youtube(-nocookie)?\.com\/embed\//.test(iframeSrc) ? "YouTube" :
68+
undefined;
69+
70+
if (!serviceProvider) {
71+
return;
72+
}
73+
74+
const iframeHeight = iframe.getBoundingClientRect().height;
75+
const iframeWidth = iframe.getBoundingClientRect().width;
76+
77+
// Create placeholder content
78+
divElement.innerHTML = `
79+
<div style="background-color:#CCC;display:inline-block;height:${iframeHeight}px;position:relative;width:${iframeWidth}px;">
80+
<div style="background-color:#848484;border-radius:15px;height:50%;position:absolute;transform:translate(50%,50%);width:50%;">
81+
<p style="color:#FFF;font-size:7.5em;position:relative;top:50%;left:50%;margin:0;text-align:center;transform:translate(-50%,-50%);">&ctdot;</p>
82+
</div>
7783
</div>
78-
</div>
79-
`;
80-
81-
// Setup consent message and button
82-
divElement.classList.add(`cookieconsent-optout-${consentType}`);
83-
linkElement.textContent = `accept ${consentType} cookies`;
84-
linkElement.href = "javascript:Cookiebot.renew()";
85-
paragraphElement.append(
86-
createTextNode("Please "),
87-
linkElement,
88-
createTextNode(` to view this ${serviceProvider} content.`)
89-
);
90-
91-
divElement.append(paragraphElement);
92-
iframe.parentNode.insertBefore(divElement, iframe);
93-
});
94-
})(document, "iframe[data-cookieblock-src]", "marketing");
95-
});
96-
';
84+
`;
85+
86+
// Setup consent message and button
87+
divElement.classList.add(`cookieconsent-optout-${consentType}`);
88+
linkElement.textContent = `accept ${consentType} cookies`;
89+
linkElement.href = "javascript:Cookiebot.renew()";
90+
paragraphElement.append(
91+
createTextNode("Please "),
92+
linkElement,
93+
createTextNode(` to view this ${serviceProvider} content.`)
94+
);
95+
96+
divElement.append(paragraphElement);
97+
iframe.parentNode.insertBefore(divElement, iframe);
98+
});
99+
})(document, "iframe[data-cookieblock-src]", "marketing");
100+
});
101+
';
97102

98-
// Render scripts with secure renderer
99-
echo $secureRenderer->renderTag(
100-
'script',
101-
['type' => 'text/javascript', 'data-cookieconsent' => 'ignore'],
102-
$addRequiredAttributesScript,
103-
false
104-
);
103+
// Render scripts with secure renderer
104+
echo $secureRenderer->renderTag(
105+
'script',
106+
['type' => 'text/javascript', 'data-cookieconsent' => 'ignore'],
107+
$addRequiredAttributesScript,
108+
false
109+
);
105110

106-
echo $secureRenderer->renderTag(
107-
'script',
108-
['type' => 'text/javascript', 'data-cookieconsent' => 'ignore'],
109-
$placeholderScript,
110-
false
111-
);
111+
echo $secureRenderer->renderTag(
112+
'script',
113+
['type' => 'text/javascript', 'data-cookieconsent' => 'ignore'],
114+
$placeholderScript,
115+
false
116+
);
117+
}
112118
?>

view/frontend/web/js/load-player-mixin.js

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ define([
2020
}
2121

2222
return function (originalWidget) {
23+
var blockVideosUntilConsent = window.cookiebotConfig && window.cookiebotConfig.blockVideosUntilConsent;
2324

2425
$.widget('mage.videoYoutube', $.mage.videoYoutube, {
2526
_create: function () {
@@ -63,17 +64,19 @@ define([
6364
self.element.closest('.fotorama__stage__frame')
6465
.addClass('fotorama__product-video--loaded');
6566

66-
// Add Cookiebot integration
67-
const iframes = document.querySelectorAll('.product-video[data-type="youtube"] iframe');
68-
iframes.forEach((iframe) => {
69-
if (!Cookiebot.consent.marketing) {
70-
iframe.setAttribute('data-cookieblock-src', iframe.src);
71-
iframe.setAttribute('data-cookieconsent', 'marketing');
72-
iframe.removeAttribute('src');
73-
}
74-
});
75-
76-
createCookiebotPlaceholders();
67+
// Add Cookiebot integration only if configured
68+
if (blockVideosUntilConsent) {
69+
const iframes = document.querySelectorAll('.product-video[data-type="youtube"] iframe');
70+
iframes.forEach((iframe) => {
71+
if (!Cookiebot.consent.marketing) {
72+
iframe.setAttribute('data-cookieblock-src', iframe.src);
73+
iframe.setAttribute('data-cookieconsent', 'marketing');
74+
iframe.removeAttribute('src');
75+
}
76+
});
77+
78+
createCookiebotPlaceholders();
79+
}
7780
},
7881
onStateChange: function (data) {
7982
switch (window.parseInt(data.data, 10)) {
@@ -124,40 +127,49 @@ define([
124127
timestamp +
125128
additionalParams;
126129
id = 'vimeo' + this._code + timestamp;
127-
this.element.append(
128-
$('<iframe></iframe>')
129-
.attr('frameborder', 0)
130-
.attr('id', id)
131-
.attr('width', this._width)
132-
.attr('height', this._height)
133-
.attr('src', src)
134-
.attr('data-cookieblock-src', src)
135-
.attr('data-cookieconsent', 'marketing')
136-
.attr('webkitallowfullscreen', '')
137-
.attr('mozallowfullscreen', '')
138-
.attr('allowfullscreen', '')
139-
.attr('referrerPolicy', 'origin')
140-
.attr('allow', 'autoplay')
141-
);
130+
131+
var iframeAttrs = {
132+
'frameborder': 0,
133+
'id': id,
134+
'width': this._width,
135+
'height': this._height,
136+
'src': src,
137+
'webkitallowfullscreen': '',
138+
'mozallowfullscreen': '',
139+
'allowfullscreen': '',
140+
'referrerPolicy': 'origin',
141+
'allow': 'autoplay'
142+
};
143+
144+
// Only add Cookiebot attributes if configured
145+
if (blockVideosUntilConsent) {
146+
iframeAttrs['data-cookieblock-src'] = src;
147+
iframeAttrs['data-cookieconsent'] = 'marketing';
148+
}
149+
150+
var $iframe = $('<iframe></iframe>').attr(iframeAttrs);
151+
this.element.append($iframe);
142152

143153
/* eslint-disable no-undef */
144154
this._player = new Vimeo.Player(this.element.children(':first')[0]);
145155

146156
this._player.ready().then(function () {
147157
$('#' + id).closest('.fotorama__stage__frame').addClass('fotorama__product-video--loaded');
148158

149-
// Add Cookiebot integration
150-
const iframes = document.querySelectorAll('.product-video[data-type="vimeo"] iframe');
151-
152-
iframes.forEach((iframe) => {
153-
if (!Cookiebot.consent.marketing) {
154-
iframe.setAttribute('data-cookieblock-src', iframe.src);
155-
iframe.setAttribute('data-cookieconsent', 'marketing');
156-
iframe.removeAttribute('src');
157-
}
158-
});
159+
// Add Cookiebot integration only if configured
160+
if (blockVideosUntilConsent) {
161+
const iframes = document.querySelectorAll('.product-video[data-type="vimeo"] iframe');
162+
163+
iframes.forEach((iframe) => {
164+
if (!Cookiebot.consent.marketing) {
165+
iframe.setAttribute('data-cookieblock-src', iframe.src);
166+
iframe.setAttribute('data-cookieconsent', 'marketing');
167+
iframe.removeAttribute('src');
168+
}
169+
});
159170

160-
createCookiebotPlaceholders();
171+
createCookiebotPlaceholders();
172+
}
161173
});
162174
}
163175
});

0 commit comments

Comments
 (0)