Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further changes required for GDPR compliance #131

Open
joepagan opened this issue Jan 17, 2023 · 8 comments
Open

Further changes required for GDPR compliance #131

joepagan opened this issue Jan 17, 2023 · 8 comments
Assignees

Comments

@joepagan
Copy link

Hey, this is a great plugin! I would love to use it but I think some more changes are required to make it GDPR compliant.

It appears the plugin will:

However, these changes do not consider cookies which may load from all over services which your plugin supports like an embedded tweet for example which will also load marketing cookies.

A GDPR setting implies being compliant when it might not be, especially where other services like twitter might be used which may load cookies via a different method.

Suggested solution

Having only really worked with CookieBot as a solution I feel their approach is good, but as it's not a standard approach though giving us access to do the following I think is cookie-blocking service ambiguous enough? Though I can't really comment on what the other services require.

Here is an example that is compliant with CookieBot

<iframe
    data-cookieblock-src="https://www.youtube.com/embed/xxxxxxxxxxx"
    data-cookieconsent="marketing"
    frameborder="0"
    allowfullscreen
></iframe>

Where if marketing cookies are accepted, the data-cookieblock-src updates to a src attribute.

So maybe it would be best to give devs the opportunity to disable the src attribute so they can do this.

RE how to handle other services

If a script element is responsible for create an iframe element like a tweet used to (not sure if that's what happens anymore), we can perform a similar change:

<script type="text/plain" data-cookieconsent="marketing"></script>

where the type attribute changes on accepting.

Though of course this requires extending the twig variables a bit more if that's something which could be considered?

@iparr
Copy link

iparr commented Jan 17, 2023

I first raised a request concerning this, perhaps without giving full consideration to GDPR requirements: #23

What I think I'd like to see is:

  1. Interface / documentation language changed so that people don't think they're automatically compliant (I will try and find time for a pull request). I still see some value to this plugin setting as it is now.
  2. A solution like yours @joepagan - to enhance this and help people towards full GDPR compliance. I wonder what other approaches there are?

@reganlawton
Copy link
Member

reganlawton commented Nov 3, 2023

Hmm interesting, so @joepagan and @iparr we'd need something like:

$iframe = $dom->getElementsByTagName('iframe')->item(0);
$src = $iframe->getAttribute('src');

$src = $this->manageGDPR($src);

if (Oembed::getInstance()->getSettings()->enableGdpr) {
    $iframe->setAttribute('data-cookieblock-src', $src);
    $iframe->setAttribute('data-cookieconsent', 'marketing');
}

I do a ton of backend the past year or two, ML stuff, so don't follow GDPR much.

@reganlawton reganlawton self-assigned this Nov 3, 2023
@reganlawton
Copy link
Member

Updated v3.0.3 with new changes with a new setting to support.

@paulwaddington
Copy link

paulwaddington commented Jul 11, 2024

It looks like this update will set 'data-cookieblock-src' in addition to the 'src' attribute, though the Cookiebot implementation removes the 'src' attribute.

It would be great if we could also display a placeholder before or after the iframe-tag

<div class="cookieconsent-optout-marketing">
    Please
    <a href="javascript:Cookiebot.renew()">accept marketing-cookies</a>
    to watch this video.
</div> 

This is the original Cookiebot page:

https://support.cookiebot.com/hc/en-us/articles/360003790854-Iframe-cookie-consent-with-YouTube-example

@MangoMarcus
Copy link

@paulwaddington is correct RE cookiebot, it would needed to remove the src attribute otherwise the iframe will load regardless of cookie consent. Once the user accepts the relevant cookies, Cookiebot updates the iframe's src to its data-cookieblock-src.

I wrote a solution which removes the src and also handles other embeds like TikTok, which provides a <script> rather than an <iframe>

public function addConsentChecksToEmbed(string $code): string
{
    try {
        $dom = new DOMDocument();

        // Disable errors - TikTok puts a <section> in a <blockquote> for some reason which raises a PHP warning
        libxml_use_internal_errors(true);
        $dom->loadHTML($code);
        libxml_use_internal_errors(false);

        // Ensure there is a root level element
        $body = $dom->getElementsByTagName('body')->item(0);
        $childNodes = iterator_to_array($body->childNodes);
        // Get the nodes under body which are elements
        /** @var DOMElement[] $childElements */
        $childElements = array_filter(
            $childNodes,
            fn (DomNode $node): bool => $node instanceof DOMElement,
        );

        if (count($childElements) === 1) {
            $root = $childElements[0];
        } else {
            // Wrap the elements in a div
            $root = $dom->createElement('div');
            if (!$root) {
                Craft::error('Could not create root element', __METHOD__);
                return '';
            }

            foreach ($childNodes as $child) {
                $root->appendChild($child);
            }
            $body->appendChild($root);
        }

        /** @var DOMElement $script */
        foreach($dom->getElementsByTagName('script') as $script) {
            $script->setAttribute('data-cookieconsent', 'marketing');
            $script->setAttribute('type', 'text/plain');
        }

        /** @var DOMElement $iframe */
        foreach($dom->getElementsByTagName('iframe') as $iframe) {
            $iframe->setAttribute('data-cookieconsent', 'marketing');
            $iframe->setAttribute('data-cookieblock-src', $iframe->getAttribute('src'));
            $iframe->removeAttribute('src');
        }

        return $dom->saveHTML($root);
    } catch (DOMException $e) {
        Craft::error($e->getMessage(), __METHOD__);
        return '';
    }
}

I'm currently using that in a Craft module with

{{ craft.videoEmbed.addConsentChecksToEmbed(entry.myField.embed(oEmbedOptions).code)|raw }}

@reganlawton
Copy link
Member

@MangoMarcus If you have a working local solution please send a PR I'd be happen to give it a look and test. If all good I'll merge it through 🍻

@D3VM4TT
Copy link

D3VM4TT commented Jan 22, 2025

Hey @reganlawton

Just checking if any progress has been made here? We have several customers complaining about compliance issues

@reganlawton
Copy link
Member

@D3VM4TT I throw together a quick branch of @MangoMarcus code you can try testing using dev-feature/consent-checks branch in composer.

@reganlawton reganlawton reopened this Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants