October CMS plugin to make websites GDPR compliant.
This plugin is available on the October Marketplace: https://octobercms.com/plugin/offline-gdpr
This plugin provides two simple components to make your October installation GDPR compliant.
- Define your cookie groups and cookies via the backend settings page.
- Place the
cookieManager
component on acookies.htm
page - Place the
cookieBanner
component on all of your layouts. Use the configuration listed below.
[cookieBanner]
include_css = 1
update_partial = "gdpr"
update_selector = "#gdpr-reload"
cookie_manager_page = "cookies"
==
{% component 'cookieBanner' %}
- Create a new
gdpr.htm
partial. Include the partial in your layouts as shown below. Note the#gdpr-reload
wrapper.
<div id="gdpr-reload">
{% partial 'gdpr' %}
</div>
- Inside your
gdpr.htm
partial you can now conditionally include your dependencies by querying the cookie'scode
.
{% if gdprCookieAllowed('google-analytics') %}
<!-- Include analytics code here -->
{% endif %}
The cookieManager
component gives a visitor more control over the cookies your site is using.
This component can simply be placed on a page and needs no further configuration.
title = "Cookies"
url = "/cookies"
layout = "default"
is_hidden = 0
[cookieManager]
==
{% component 'cookieManager' %}
The cookieBanner
component displays a cookie banner on the first page view. There the user has the possibility to
enable and disable cookies that your website uses (defined via October's backend settings).
These settings are stored and made available in your partials using the gdprCookieAllowed
helper. With this helper
you can check for the user's consent and optionally include your resources.
- Define your cookie groups and cookies via the Backend settings
- Add the
cookieBanner
component to all your layouts.
[cookieBanner]
include_css = 1
update_partial = "gdpr"
update_selector = "#gdpr-reload"
cookie_manager_page = "cookies"
==
{% component 'cookieBanner' %}
If you don't want to include the default css use include_css = 0
when including your component.
Set the property cookie_manager_page
to the page that contains the cookieManager
component.
A Advanced Settings
link will be placed on the cookieBar
that links to this page. This enables the user to
further define what cookies are allowed.
Check if a certain cookie is allowed to be included. You can optionally pass a cookie level to check if the user has accepted a specific level of this cookie.
{% if gdprCookieAllowed('google-analytics') %}
<!-- Include Analytics Code here -->
{% endif %}
{% if gdprCookieAllowed('google-analytics', 3) %}
<!-- Include advanced Level 3 Analytics Code here -->
{% endif %}
Get the max allowed level for a certain cookie. A return value of -1
means the cookie is not allowed at all. A
value of 0
or higher means the cookie is allowed with the returned level value.
{% if gdprAllowedCookieLevel('google-analytics') >= 3 %}
<!-- Include advanced Level 3 Analytics Code here -->
{% endif %}
Check if the user has made a decision about the cookies yet. This will return true
on the second page view if the
user did not interact with the cookieBanner
(silent opt-in).
The data retention functionality enables you to delete old plugin data after a specified amount of days.
You can specify the data retention policy for each plugin via October's backend settings.
Important: To automatically delete old data make sure you have set up the Task Scheduler correctly.
To register your plugin you have to listen for the offline.gdpr::cleanup.register
event in your Plugin's boot method.
public function boot()
{
\Event::listen('offline.gdpr::cleanup.register', function () {
return [
'id' => 'your-contact-form-plugin',
'label' => 'Custom Contact Form Plugin',
'models' => [
[
'label' => 'Contact form messages',
'comment' => 'Delete logged contact form messages',
'class' => MessageLog::class,
],
[
'id' => 'vendor-plugin-spam-messages', // The ID is required if you specify a closure. This should be unique to your plugin.
'label' => 'SPAM-Messages',
'comment' => 'Delete blocked SPAM messages',
'closure' => function (Carbon $deadline, int $keepDays) {
// Delete your old data here
},
],
],
];
});
}
You have to specify the following data:
key | information |
---|---|
id | A unique identifier of your plugin |
label | A human readable label for your plugin |
models | An array of all your data collecting models |
As models
you have to specify an array with the following data:
key | information |
---|---|
id | A unique string to identify this model. Use only _-a-z0-9 . Only required if you specify a closure. (ex. offline-gdpr-spam-messages ) |
label | A human readable label for the backend switch form widget |
comment | A human readable comment for the backend switch form widget |
closure | A closure that is called when the cleanup job is run. Make sure to also define an id . |
class | A model class that defines a gdprCleanup method |
You have to specify either a closure
or a class
value. If both are specified the closure
value will be used.
You can either specify a closure
or a model class that defines a gdprCleanup
method. Both have the same
signature:
public function gdprCleanup(Carbon $deadline, int $keepDays)
{
self::where('created_at', '<', $deadline)->each(function (self $item) {
$item->delete();
});
// or
// self::where('created_at', '<', $deadline)->delete();
}
This method is called whenever the cleanup job is run. $deadline
contains a Carbon
instance.
All data older than this date has to be deleted. $keepDays
contains the number of days
that $deadline
is in the past.
Make sure to use an each/delete
loop if your model makes use of deleting/deleted
model events.
You can trigger the cleanup on demand via
php artisan gdpr:cleanup
Use the
cookieBanner Component
instead!
This plugin provides an easy integration of Klaro! A Simple Consent Manager.
The Klaro! Consent Manager displays a GDPR compliant cookie message and allows the customization of the usage of third-party applications by a website visitor.
All Klaro! settings can be managed via October's backend.
Information on how to use Klaro! can be found on the official website https://klaro.kiprotect.com/.
You can configure all Klaro! settings via the October CMS backend settings.
If you are more of a code person you can overwrite the config.js
partial
via your theme and use your own configuration file instead.
If you only want to define your applications manually you can overwrite the apps.js
partial via your theme.
A configuration example is availabe at https://klaro.kiprotect.com/config.js.
You can add custom translation strings via the backend settings page. Create a new translation, give it a 2-char
language code (ex. de
, en
) and paste and modify the following json code into the code editor:
{
consentModal: {
description: 'Hier können Sie einsehen und anpassen, welche Information wir über Sie sammeln. Einträge die als "Beispiel" gekennzeichnet sind dienen lediglich zu Demonstrationszwecken und werden nicht wirklich verwendet.',
},
inlineTracker: {
description: 'Beispiel für ein Inline-Tracking Skript',
},
externalTracker: {
description: 'Beispiel für ein externes Tracking Skript',
},
adsense: {
description: 'Anzeigen von Werbeanzeigen (Beispiel)',
},
matomo: {
description: 'Sammeln von Besucherstatistiken',
},
camera: {
description: 'Eine Ãœberwachungskamera (nur ein Beispiel zu IMG-Tags)',
},
cloudflare: {
description: 'Schutz gegen DDoS-Angriffe',
},
intercom: {
description: 'Chat Widget & Sammeln von Besucherstatistiken (nur ein Beispiel)',
},
mouseflow: {
description: 'Echtzeit-Benutzeranalyse (nur ein Beispiel)',
},
purposes: {
analytics: 'Besucher-Statistiken',
security: 'Sicherheit',
livechat: 'Live Chat',
advertising: 'Anzeigen von Werbung',
}
}
You can find all possible translation keys in Klaro's example config file.
Place this component on your layout, page or partial to display the Klaro! Consent Manager.
{% component 'consentManager' %}
Enable this option to automatically include the klaro.js file. You can disable this option if you want to take full control over how the script is included.
Define a custom css class to be used in the Klaro! HTML markup. If this option is set all default styles will be removed completely.