Conversation
The module setting will fallback to `site_html_header` as that was the name before. While at it I fixed the labels as they used hardcoded text or displayed faulty output.
The module setting will fallback to `site_html_footer` as that was the name before. While at it I fixed the labels as they used hardcoded text or displayed faulty output.
It seems like this settings was already available but not displayed in the backend :s
Sorry, I copy/pasted it wrong.
I think I wrote it more readable: * If Google Tag Manager is added thru the backend we expect Google Analytics to be loaded from within Google Tag Manager * If the web property is empty we can't build a correct code therefore it should not be added * If the web property is present in any of the site wide HTML than we should not add it.
gtag.js is the current way to add Google Analytics to a site. See https://support.google.com/analytics/answer/7538414
…Manager Container Id
The Analytics module should not be responsible for adding the Google Analytics Tracking Code. As we now have a separate setting we use that one to decide if the code should be added.
It should be as easy as:
$container->get(ForkCMS\Google\TagManager\DataLayer::class)->add('key', $value);
We will add the anonimizeIp variable by default
This consent should enable developers to build GDPR compliant websites. In the backend the developer can define privacy levels to which the user can agree. There is a service ForkCMS\Privacy\ConsentDialog which can be used to retrieve the preferences of the current user. The data is also available in jsData for usage in JavaScript
This feature conflicts with GDPR, although we had a way to not set the cookie. As GDPR states that the user should know he is tracked, we can't generate a way of tracking per default. If you need this feature you should build it yourself, you can look at the past code on how it was done, but you should ask permission first.
|
Some considerations / ideas / ...:
WE USE COOKIES | Set preferences | | Accept all | With set preferences a modal link, which has a backdrop that makes it more of a separate thing instead of 'noise' on your page. If you don't go with this idea, I would still put the whole thing in a 8000 modal because it is too big for an alert over your content, and I would put the button on the left, for an easier flow. Example: https://www.standaard.be/ (but I would go with a shorter infotext).
|
|
@sarahmey I don't agree.
About the backend:
|
|
Also; the "accept all" button is considered a dark pattern as it does not really inform you. |
|
My two cents:
|
|
@fspin |
In your screenshots I see the possibility to add a new checkbox, indeed, but not an extra explanatory text.
Even without a backdrop, you'll still have the problem if your modal/popup is fixed and large (or your screen is small).
I meant that the cookies' preferences. For instance: if I agree with the analytics cookies, but not with the social cookies. Once I close the dialog, and start navigating... would it be enough to set a js variable in order to get the google analytics properly working? |
Those are added thru translations in Fork, as explained in the PR description.
Okay, se in essence @sarahmey and yourself would prefer a modal which forces the user to make a choice before consuming the actual content. And we should provide a way to hide this modal on certain pages. So to wrap it up:
In my personal opinion this will clutter up the interface, so if we do this I will move the whole Consent dialog to a separate item in the settings menu. I also think we are making a lot of decisions that are not up to us, but are decisions that should be made by the project-owner.
With the levels, a visitor choses to which he/she agrees. It could be that the visitor agrees to statistical but not social. It is up to the developer to handle these correctly. In the PR description there is an example on how to load Hotjar only if the user agrees, and hotter will be injected as soon as the user agrees. |
In fact, you could let the user just navigate the site without making a decision. In which case it will means the user didn't accept optional cookies, right? In order to do this, your modal should appear (and stay)
It will clutter the backend interface, you mean, right? Then I agree... it will be better to put it in its own I wonder which decisions are we making? I just think this isn't easy. And it should be present in every site using analytics or social plugins (mandatory in the EU, for the moment, where we are located): So, it seems to me reasonable to put it by default. Afterwards, the project owner can always dismissed all this, but it will be a (quite irresponsible) opt-out. |
The example you give hides the possible options. The proposed implementation allows the user to navigate thur the site without being forced to choose anything (which is my personal way of handling it).
Fork is a "framework" to build sites it does not dictate on how something should look, or how the user interacts with it. So in my opinion you decide to "block" the user to visit the site if you make a "wall" the default. |
|
I decided not to add the title and text per level per language as I think the translations are fine, however I will write a blogpost on https://www.fork-cms.com to explain how it should be used. I fixed the close-button, so the consent-dialog can be closed when it is in the way of the content, in that case nothing is saved and it will appear again until the visitor has saved the chosen preferences. Ofcourse developers can change the behaviour and convert it into a real modal. I also will discuss it in person with Fabian. |
The ePrivacy Directive specifies that persistant cookies can not be stored longer than 12 months, so we splitted it in half. More information on: https://gdpr.eu/cookies/#:~:text=All%20persistent%20cookies%20have%20an,you%20do%20not%20take%20action.
app/config/config.yml
Outdated
| public: true | ||
| arguments: | ||
| - "@fork.settings" | ||
| - "@fork.cookie" No newline at end of file |
There was a problem hiding this comment.
new line at the end of the file is missing
| */ | ||
| public function hasAllowedCookies(): bool | ||
| { | ||
| return $this->get('cookie_bar_agree', 'N') === 'Y'; |
There was a problem hiding this comment.
I would really love to put this in Fork 5 but this is a BC break.
Can you implement it in a way that in Fork 5 you can choose for the cookie bar or the consent dialog? And then just add a deprecation notice on the cookie bar
src/Frontend/Core/Engine/Footer.php
Outdated
|
|
||
| // facebook admins given? | ||
| // @deprecated remove this in Fork 6, Facebook should not be added automaticall | ||
| $facebookAppId = $this->get('fork.settings')->get('Core', 'facebook_app_id', null); |
| } | ||
| // if the consent dialog is disabled we will anonymize by default | ||
| if (!$this->modulesSettings->get('Core', 'show_consent_dialog', false)) { | ||
| return true; |
There was a problem hiding this comment.
I would have it fallback here on the cookiebar and mark it as deprecated
| <ul class="list-unstyled"> | ||
| <li class="checkbox"> | ||
| <label for="showCookieBar" class="control-label">{% form_field show_cookie_bar %} {{ 'msg.ShowCookieBar'|trans|ucfirst }}</label> | ||
| <label for="showConsentDialog" class="control-label">{% form_field show_consent_dialog %} {{ 'msg.ShowConsentDialog'|trans|ucfirst }}</label> |
There was a problem hiding this comment.
I would do this as a radiobutton that people have to choose between nothing, the cookiebar or the consent dialog for in Fork 5 and then remove the cookiebar in Fork 6
| * Handles the cookieBar | ||
| * Handles the privacy consent dialog | ||
| */ | ||
| jsFrontend.cookieBar = { |
Readded a lot of stuff to make the (deprecated) cookiebar work again. I did not make it use a radiobutton as I think it should be decided by the developer.
|
@carakas I did not opted for a radiobutton, I just restored the checkbox for the cookie-bar. |
Type
Pull request description
This PR enables developers to build GDPR compliant websites. GDPR affects all
website owners that target EU citizens.
In essence it will show a visitor a dialog wherein they can select their privacy
preferences. For example:
The preferences are stored in functional cookies so they are remembered.
IMPORTANT: it is still the responsibility of the developer/marketeer to
respect the visitors choices. Fork gives you the ability to do so.
Configuration of the consent dialog
In the backend under "Settings" there is a new block which allows you to define
different privacy levels. You can add as many as needed. A visitor can agree to
each level separately.
For each level you need to add 2 translations, these translations will be used
in the consent dialog.
to make an informed disscision, so in the description you can describe what the
level means an how you will use the visitors agreement.
The reference code/name of the translation uses the level like explained below:
So for instance if you define the level "statistics" you will need to add 2
translations with the names:
PrivacyConsentLevelStatisticsTitlePrivacyConsentLevelStatisticsTextRemark: If you change the levels the consent dialog will be shown again
to all visitors. Previous choices will not be ticked.
There is one level that is always available:
functional, this is alwaysallowed. The user can not change this. It is added as it is a good practice to
explain your visitor what you store in these cookies.
Usage
Retrieving choices in JavaScript
The choices of the visitor are available in
jsDatain theprivacyConsent-object.possibleLevelscontains all the levels that are defined thru the CMS.levelsHash, this is the hash that is used to determine if the levels are changed.visitorChoices, this contains the choice a user has made per level. The default is false.Retrieving choices in PHP
A new service is available as
ForkCMS\Privacy\ConsentDialog. This serviceexposes some methods that you can use:
getLevels(bool $includeFunctional = false), this will return all the defined levels.getVisitorChoices(): returns an array with the users chosen preferenceshasAgreedTo(string $level): returns a boolean if the user has agreed to a given level. Returns false per default, also for non existing levels.So for example if you want to do personalations if the user has agreed to the
personalisation-level, you can use the snippet below:Anonymize IP
Google Analytics has a feature called anonymizeIp. If you use our Google Analytics-
or Google Tag Manager integration we use the anonymizeIp feature by default.
In this case you need to add a privacy level with the name
statistics. If you doso, and the visitor agrees to it we will disable the IP anonymization.
Warning: In Belgium this is not correct. The DPA decided that anonymizeIp
is not enough, therefor you should ask permission before tracking! See below how you
can achieve this.
Google Tag Manager
If you use Google Tag Manager it is completely up to you to adhere the visitors
preferences. Below is explained on how it can be configured.
Create a variables
Do this for all the levels you defined.
Create triggers
Repeat these steps for each level you have defined
Load a tag only when it is allowed
By adding the exception the Tag won't be fired. This is the case when a visitor
has not agreed to anything. In that case the consent dialog is shown.
When the visitor clicks "Save my preferences", we will fire an event per agreed
level:
privacyConsentLevelXXXAgreed. This will fire the tag, as it is configuredas a Firing trigger.
If the visitor visits another page the exception won't be triggered as the variable
is true. So the tag will be fired by the "All Pages" trigger.
Removed features
Adding new features also means cleaning up non relevant features, so some are removed:
Cookie bar
This new Consent Dialog replaces the previous Cookie Bar.
This means you can't use the following methods anymore:
$this->get('fork.cookie')->hasAllowedCookies()$this->get('fork.cookie')->hasHiddenCookieBar()Visitor Id
The visitor Id that was generated and stored in a cookie does not exist anymore.
If you rely on it you should build this feature yourself.