{"id":28656069,"url":"https://github.com/offline-gmbh/oc-gdpr-plugin","last_synced_at":"2025-06-13T08:10:15.335Z","repository":{"id":32751120,"uuid":"136131480","full_name":"OFFLINE-GmbH/oc-gdpr-plugin","owner":"OFFLINE-GmbH","description":"October CMS plugin to make websites GDPR and ePrivacy compliant","archived":false,"fork":false,"pushed_at":"2024-09-05T15:16:28.000Z","size":857,"stargazers_count":36,"open_issues_count":8,"forks_count":20,"subscribers_count":7,"default_branch":"develop","last_synced_at":"2025-06-09T01:08:46.181Z","etag":null,"topics":["eprivacy","gdpr","octobercms","octobercms-plugin"],"latest_commit_sha":null,"homepage":"https://octobercms.com/plugin/offline-gdpr","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OFFLINE-GmbH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-05T06:36:31.000Z","updated_at":"2024-09-05T15:16:21.000Z","dependencies_parsed_at":"2024-06-09T17:27:44.009Z","dependency_job_id":"3e3acc85-9f6e-401e-ae9c-8cd8816cd32a","html_url":"https://github.com/OFFLINE-GmbH/oc-gdpr-plugin","commit_stats":{"total_commits":204,"total_committers":15,"mean_commits":13.6,"dds":0.2549019607843137,"last_synced_commit":"1a992fe9ca33b0213a7bc9d80833ab072f118430"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/OFFLINE-GmbH/oc-gdpr-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-gdpr-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-gdpr-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-gdpr-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-gdpr-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OFFLINE-GmbH","download_url":"https://codeload.github.com/OFFLINE-GmbH/oc-gdpr-plugin/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-gdpr-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259606992,"owners_count":22883565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eprivacy","gdpr","octobercms","octobercms-plugin"],"created_at":"2025-06-13T08:10:14.624Z","updated_at":"2025-06-13T08:10:15.312Z","avatar_url":"https://github.com/OFFLINE-GmbH.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oc-gdpr-plugin\nOctober CMS plugin to make websites GDPR compliant.\n\nThis plugin is available on the October Marketplace: https://octobercms.com/plugin/offline-gdpr\n\n## Features\n\n* [Cookie Consent Manager](#cookie-consent-manager)\n* [Data retention](#data-retention)\n\n## Cookie Consent Manager\n\nThis plugin provides two simple components to make your October installation GDPR compliant.\n\n![cookie-manager](https://user-images.githubusercontent.com/8600029/41364223-5c58a548-6f36-11e8-9279-2e04217fe645.gif)\n\n\n### Quick start\n\n1. Define your cookie groups and cookies via the backend settings page.\nYou can also import a example preset by running `php artisan gdpr:import`\n1. Place the `cookieManager` component on a `cookies.htm` page\n1. Place the `cookieBanner` component on all of your layouts. Use the configuration listed below.\n\n```ini\n[cookieBanner]\ninclude_css = 1\nupdate_partial = \"gdpr\"\nupdate_selector = \"#gdpr-reload\"\ncookie_manager_page = \"cookies\"\n==\n{% component 'cookieBanner' %}\n```\n\n1. Create a new `gdpr.htm` partial. Include the partial in your layouts as shown below. Note the `#gdpr-reload` \nwrapper.\n\n```twig\n\u003cdiv id=\"gdpr-reload\"\u003e\n    {% partial 'gdpr' %}\n\u003c/div\u003e\n```\n\n1. Inside your `gdpr.htm` partial you can now conditionally include your dependencies by querying the cookie's `code`.\n\n```twig\n{% if gdprCookieAllowed('google-analytics') %}\n    \u003c!-- Include analytics code here --\u003e\n{% endif %}\n```\n\n### Cookie manager\n\nThe `cookieManager` component gives a visitor more control over the cookies your site is using. \n\nThis component can simply be placed on a page and needs no further configuration.  \n\n```twig\ntitle = \"Cookies\"\nurl = \"/cookies\"\nlayout = \"default\"\nis_hidden = 0\n\n[cookieManager]\n==\n{% component 'cookieManager' %}\n```\n\n#### Cookie presets\n\nIt is possible to define your cookie groups and cookies in a `yaml` file and import them using the `gdpr:import` console command.\nThis allows you to define cookies once and re-use them between installations.\n\n```\nphp artisan gdpr:import --path=plugins/offline/gdpr/assets/presets/example_en.yaml --replace\n```\n\nYou can find example definitions in the [`assets/presets`](./assets/presets) directory of this plugin.\n\nYou can optionally use the `--replace` flag to remove all existing cookie data and replace it with your preset.\n\nIf no path is specified, the plugin will load all presets from the configured `presets_path` and ask you which preset to import.\n\nYou can change the path where presets are loaded from by changing the `offline.gdpr::config.presets_path` config entry.\nTo do this, create the file `config/offline/gdpr/config.php` and return your custom path:\n\n```php\n\u003c?php\nreturn [\n    'presets_path' =\u003e '/path/to/your/presets',\n];\n``` \n\n\n### cookieBanner\n\n![image](https://user-images.githubusercontent.com/8600029/44200030-e913bb80-a145-11e8-83fc-272bb577c4fc.png)\n\n\nThe `cookieBanner` component displays a cookie banner on the first page view. There the user has the possibility to \nenable and disable cookies that your website uses (defined via October's backend settings).\n\nThese settings are stored and made available in your partials using the `gdprCookieAllowed` helper. With this helper \nyou can check for the user's consent and optionally include your resources.\n\n#### Installation\n\n1. Define your cookie groups and cookies via the Backend settings\n1. Add the `cookieBanner` component to all your **layouts**.\n\n```\n[cookieBanner]\ninclude_css = 1\nupdate_partial = \"gdpr\"\nupdate_selector = \"#gdpr-reload\"\ncookie_manager_page = \"cookies\"\n==\n{% component 'cookieBanner' %}\n```\n\n#### Log\n\nYou can enable a log via the backend settings so every cookie banner request gets logged. This is useful to get an idea of the number of users that do not accept a cookie request and therefore never end up in your analytics data.\n\nThe log only contains the user's session id and their decision.\n\n#### Properties\n\nIf you don't want to include the default css use `include_css = 0` when including your component.\n\n##### `cookieManager` page\n\nSet the property `cookie_manager_page` to the page that contains the `cookieManager` component. \n\nA `Advanced Settings` link will be placed on the `cookieBar` that links to this page. This enables the user to \nfurther define what cookies are allowed.\n\n\n#### Twig Helpers\n\n##### `gdprCookieAllowed($code, $minLevel = 0)`\n\nCheck if a certain cookie is allowed to be included. You can optionally pass a cookie level to check if the user has \naccepted a specific level of this cookie.\n\n```twig\n{% if gdprCookieAllowed('google-analytics') %}\n    \u003c!-- Include Analytics Code here --\u003e\n{% endif %}\n\n{% if gdprCookieAllowed('google-analytics', 3) %}\n    \u003c!-- Include advanced Level 3 Analytics Code here --\u003e\n{% endif %}\n```\n\n##### `gdprAllowedCookieLevel($code)`\n\nGet the max allowed level for a certain cookie. A return value of `-1` means the cookie is not allowed at all. A \nvalue of `0` or higher means the cookie is allowed with the returned level value. \n\n```twig\n{% if gdprAllowedCookieLevel('google-analytics') \u003e= 3 %}\n    \u003c!-- Include advanced Level 3 Analytics Code here --\u003e\n{% endif %}\n```\n\n##### `gdprIsUndecided()`\n\nCheck if the user has made a decision about the cookies yet. This will return `true` on the second page view if the \nuser did not interact with the `cookieBanner` (silent opt-in).\n\n\n## Data retention\n\nThe data retention functionality enables you to delete old plugin data after a specified amount of days.\n\nYou can specify the data retention policy for each plugin via October's backend settings.\n\n\u003e **Important**: To automatically delete old data [make sure you have set up the Task Scheduler](http://octobercms.com/docs/setup/installation#crontab-setup) correctly.\n\n### Register your plugin\n\nTo register your plugin you have to listen for the `offline.gdpr::cleanup.register` event in your Plugin's boot method.\n\n```php\n    public function boot()\n    {\n        \\Event::listen('offline.gdpr::cleanup.register', function () {\n            return [\n                'id'     =\u003e 'your-contact-form-plugin',\n                'label'  =\u003e 'Custom Contact Form Plugin',\n                'models' =\u003e [\n                    [\n                        'label'   =\u003e 'Contact form messages',\n                        'comment' =\u003e 'Delete logged contact form messages',\n                        'class'   =\u003e MessageLog::class,\n                    ],\n                    [\n                        'id'      =\u003e 'vendor-plugin-spam-messages',  // The ID is required if you specify a closure. This should be unique to your plugin.\n                        'label'   =\u003e 'SPAM-Messages',\n                        'comment' =\u003e 'Delete blocked SPAM messages',\n                        'closure' =\u003e function (Carbon $deadline, int $keepDays) {\n                            // Delete your old data here\n                        },\n                    ],\n                ],\n            ];\n        });\n    }\n```\n\nYou have to specify the following data:\n\n|  key | information  |   \n|---|---|\n| id  | A unique identifier of your plugin   |\n| label  | A human readable label for your plugin   |\n| models  | An array of all your data collecting models |\n\nAs `models` you have to specify an array with the following data:\n\n|  key | information  |   \n|---|---|\n| 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`) |\n| label  | A human readable label for the backend switch form widget |\n| comment  | A human readable comment for the backend switch form widget   |\n| closure  | A closure that is called when the cleanup job is run. Make sure to also define an `id`.  |\n| class  | A model class that defines a `gdprCleanup` method |\n\n\nYou have to specify either a `closure` or a `class` value. If both are specified the `closure` value will be used.\n\n#### Cleanup method\n\nYou can either specify a `closure` or a model class that defines a `gdprCleanup` method. Both have the same \nsignature:\n\n```php\n    public function gdprCleanup(\\Carbon\\Carbon $deadline, int $keepDays)\n    {\n        self::where('created_at', '\u003c', $deadline)-\u003eeach(function (self $item) {\n            $item-\u003edelete();\n        });\n        // or\n        // self::where('created_at', '\u003c', $deadline)-\u003edelete();\n    }\n```\n\nThis method is called whenever the cleanup job is run. `$deadline` contains a `Carbon` instance.\nAll data older than this date has to be deleted. `$keepDays` contains the number of days\nthat `$deadline` is in the past.\n\nMake sure to use an `each/delete` loop if your model makes use of `deleting/deleted` model events.\n\n#### Cleanup command\n\nYou can trigger the cleanup on demand via \n\n\u003e php artisan gdpr:cleanup\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foffline-gmbh%2Foc-gdpr-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foffline-gmbh%2Foc-gdpr-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foffline-gmbh%2Foc-gdpr-plugin/lists"}