PHPackages                             foothing/laravel-gdpr-consent - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. foothing/laravel-gdpr-consent

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

foothing/laravel-gdpr-consent
=============================

Light-weight package for gdpr consent records.

0.4.0(5y ago)6881MITPHPCI failing

Since May 31Pushed 5y ago2 watchersCompare

[ Source](https://github.com/foothing/laravel-gdpr-consent)[ Packagist](https://packagist.org/packages/foothing/laravel-gdpr-consent)[ RSS](/packages/foothing-laravel-gdpr-consent/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (2)Dependencies (8)Versions (6)Used By (0)

Laravel GDPR Consent
====================

[](#laravel-gdpr-consent)

Light-weight Laravel 5 package for user's consents and data processing records.

Install
-------

[](#install)

Via composer

`composer require foothing/laravel-gdpr-consent`

Add service provider in `config/app.php`

```
'providers' => [
	// omitted

	Foothing\Laravel\Consent\ConsentServiceProvider::class
]
```

Add alias in `config/app.php` if you want to use the facade

```
'aliases' => [
	// omitted

	'Consent' => Foothing\Laravel\Consent\Facades\Consent::class
]
```

Publish config and migrations

`php artisan vendor:publish --tag=config`

`php artisan vendor:publish --tag=migrations`

Configure as needed, then run the migration `php artisan migrate`

Setup the treatments table `php artisan consent`

Quick start
-----------

[](#quick-start)

First you need to configure which `treatments` are required by your site. You can do so in `config/consent.php`, like the following example:

```
'treatments' => [
	[
		// A logical name for your treatment.
		'name' => 'gdpr.privacy',

		// You can specify which document
		// describes the treatment type
		// with a document version and url.
		// This part is optional.
		'documentVersion' => '1.0',
		'documentUrl' => env('PRIVACY_POLICY'),

		// Whether this treatment is active or not.
		// The reason why this flag is here is to
		// allow for progressive modifications, so you
		// can keep track of what the end user gave
		// consent to. So if you are upgrading or
		// changing the treatment the recommended
		// process is to deactivate the current one
		// then add a new record.
		'active' => true,

		// Set if this treatment is mandatory or optional.
		'required' => true,

		// A description text to be shown near a checkbox
		// or anywhere in your UI.
		'description' => 'gdpr.privacy.text',

		// UI weight, use this to choose what should be
		// listed first.
		'weight' => 0,
	],
	[
		'name' => 'gdpr.marketing',
		'documentVersion' => '1.0',
		'documentUrl' => env('PRIVACY_POLICY'),
		'active' => true,
		'required' => false,
		'description' => 'gdpr.marketing.text',
		'weight' => 1,
	],
]
```

Once you are done with the configuration you can run `php artisan consent:setup` to update your treatments database.

Then make your `User` model implement the `ConsentSubject` Contract and use the `HasConsents` trait.

```
class User extends Model implements ConsentSubject
{
	// This trait will implement the relation to the consent table.
	use HasConsents;

	/**
     * Returns the subject id.
     *
     * @return mixed
     */
	public function getSubjectId()
	{
        return $this->id;
    }

}
```

Now you will be able to use the package API to register user's consent and data processing events like in the following example.

### Display consent checkboxes in register page

[](#display-consent-checkboxes-in-register-page)

```
@foreach(Consent::treatments() as $treatment)

			{{ trans($treatment->description) }}

@endforeach
```

> Note that your `checkbox` name must match `consent_TREATMENTID`

### Validate checkboxes in your controller

[](#validate-checkboxes-in-your-controller)

```
public function postRegister(Request $request)
{
	if (! $treatments = Consent::validate($request->all()) {
		// User didn't accept all the mandatory checkboxes.
		throw new \Exception("Consent is mandatory in order to proceed.");
	}
}
```

### Register the consent

[](#register-the-consent)

```
public function postRegister(Request $request)
{
	// omitted

	// This will register a record with the
	// user's consent along with an event log.
	Facade::grant($treatments, Auth::user());
}
```

### Show consent in a user's settings page

[](#show-consent-in-a-users-settings-page)

```

@foreach(Consent::treatments() as $treatment)

			{{ trans($treatment->description) }}

@endforeach
```

> Note that for the update handler the checkbox name should be the treatment id.

### Save user's consent changes

[](#save-users-consent-changes)

```
public function postUpdateConsent(Request $request)
{
	// You should pass only the checkboxes as the first argument.
	Consent::update($request->except('_token'), Auth::user());

	// redirect as you like.
}
```

> Note that those are just examples to show the Consent API, though i wouldn't recommend using the facade inside the views and you can replicate the same feature manipulating data in a controller, before the view is being rendered.

### Log the "right to erasure"

[](#log-the-right-to-erasure)

In your `delete user` controller or service:

```
public function deleteIndex(Request $request)
{

	\DB::transaction(function() use($user)
	{
		// Delete the user first.
    	// i.e. $user->delete();

    	// This will remove consents and log the erasure request.
    	Consent::erase($user);
	});
}
```

### Events

[](#events)

It's not completely clear yet how anyone will approach logs or data processing records, which should anyway be stored and maintained. In order to provide a better flexibility an API for events has been added aswell.

The events API is implicitly used within the only hardcoded actions (*grant*, *revoke*, *erasure*) but you can use it how you like to track meaningful data processing records.

```
$event = new Event([
	// The subject id.
	'subject_id' => $user->id,

	// A string describing what has been done with subject's data.
	'action' => $action,

	// Optional, consent record id.
	'consent_id' => $consentId,
]);
Consent::log($event);

// Retrieving subject's logs
Consent::events($subject);
```

"Pseudonymization" in event records
-----------------------------------

[](#pseudonymization-in-event-records)

Since each event record stores subject's ip and the request payload, those fields are encrypted with a 2-way algorithm.

Keep in mind that Laravel uses the `config/app.php` key to encrypt and decrypt, so if you change that your data won't be decryptable anymore.

Project status
--------------

[](#project-status)

This package is under active development and needs work, but it got to the point where i had the features i need at the moment.

What is needed yet

- api refactor
- test coverage to 100%
- test with every 5.x minor release
- travis integration
- style fixes

so feel free to drop a line if you'd like to contribute.

License
-------

[](#license)

MIT

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~352 days

Total

4

Last Release

1847d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9ebf3a4938226620036760ed05bf0d6801b7bc2c383a1fd7dd1a4c48ba84145d?d=identicon)[brazorf](/maintainers/brazorf)

---

Top Contributors

[![brazorf](https://avatars.githubusercontent.com/u/3330031?v=4)](https://github.com/brazorf "brazorf (13 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/foothing-laravel-gdpr-consent/health.svg)

```
[![Health](https://phpackages.com/badges/foothing-laravel-gdpr-consent/health.svg)](https://phpackages.com/packages/foothing-laravel-gdpr-consent)
```

###  Alternatives

[wendelladriel/laravel-validated-dto

Data Transfer Objects with validation for Laravel applications

759569.4k13](/packages/wendelladriel-laravel-validated-dto)[spatie/laravel-honeypot

Preventing spam submitted through forms

1.6k6.0M60](/packages/spatie-laravel-honeypot)[axlon/laravel-postal-code-validation

Worldwide postal code validation for Laravel and Lumen

3853.3M1](/packages/axlon-laravel-postal-code-validation)[fumeapp/modeltyper

Generate TypeScript interfaces from Laravel Models

196277.9k](/packages/fumeapp-modeltyper)[illuminatech/validation-composite

Allows uniting several validation rules into a single one for easy re-usage

184485.5k](/packages/illuminatech-validation-composite)[laravel-validation-rules/phone

Validate that a phone number is in the correct format

69355.5k](/packages/laravel-validation-rules-phone)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
