From 2b244d743cbf833df9456fe9079437982dfabbe5 Mon Sep 17 00:00:00 2001 From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:40:22 +0200 Subject: [PATCH 1/4] Gave $action variable to the button view to allow more customization on the button itself --- README.md | 2 +- src/CookiesManager.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4dc2730..faf7883 100644 --- a/README.md +++ b/README.md @@ -391,7 +391,7 @@ In this example: With this setup, you can freely customize your button styles using pseudo-classes like `:hover`, `:focus`, while keeping a clean and maintainable structure. -For other changes, don't forget [you can publish the package views](#the-views). +For other changes, don't forget [you can publish the package views](#the-views). The `$action` variable lets you customize your button for specific use cases. ### Javascript diff --git a/src/CookiesManager.php b/src/CookiesManager.php index 58b387c..36da68d 100644 --- a/src/CookiesManager.php +++ b/src/CookiesManager.php @@ -264,6 +264,7 @@ public function renderButton(string $action, ?string $label = null, array $attri 'label' => $label ?? $action, // TODO: use lang file 'attributes' => $attributes, 'basename' => $basename, + 'action' => $action, ])->render(); } From 4bd6f2d30cc935aa3cf4ce5602ab227370758847 Mon Sep 17 00:00:00 2001 From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com> Date: Wed, 8 Oct 2025 17:09:07 +0200 Subject: [PATCH 2/4] Added an exemple in readme --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index faf7883..780c7cc 100644 --- a/README.md +++ b/README.md @@ -346,6 +346,24 @@ Cookie notices are boring and this package's default design is no different. It However, this world shouldn't be a boring place and even if cookie notices are part of a project's legal requirements, why not use it as an opportunity to bring a smile to your audience's face? Cookie modals are now integrated in every digital platform's user experience and therefore they should blend in accordingly: that's why we've built this package with full flexibility in our mind. +For example, after publishing the views, you can fully customize the different buttons, as in this example: + +```bladehtml +
+ @csrf + @if($action === 'reset') + + @else + + @endif +
+``` + ### The views A good starting point is to take a look at this package's default markup. If not already published, you can access the views using `php artisan vendor:publish --tag=laravel-cookie-consent-views`, this will copy our blade files to your app's `resources/views/vendor/cookie-consent` directory. @@ -373,7 +391,7 @@ Our CSS is compiled from a SASS file included in this package's `resources/scss` Buttons in this package are designed to be easily customizable. You can pass an array of attributes directly to the `@cookieconsentbutton` component: -```blade +```bladehtml @cookieconsentbutton( action: 'reset', label: 'Manage cookies', From f49b7fba2f019d3f432cb535e283830a468db985 Mon Sep 17 00:00:00 2001 From: Debatty-Tom <145542891+Debatty-Tom@users.noreply.github.com> Date: Mon, 20 Oct 2025 14:03:35 +0200 Subject: [PATCH 3/4] Added CookieConsentState Enum to the button view --- src/CookiesManager.php | 8 ++++++++ src/Enums/CookieConsentState.php | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/Enums/CookieConsentState.php diff --git a/src/CookiesManager.php b/src/CookiesManager.php index 36da68d..6bd6e8f 100644 --- a/src/CookiesManager.php +++ b/src/CookiesManager.php @@ -5,6 +5,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Cookie as CookieFacade; use Symfony\Component\HttpFoundation\Cookie as CookieComponent; +use Whitecube\LaravelCookieConsent\Enums\CookieConsentState; class CookiesManager { @@ -240,6 +241,12 @@ public function renderButton(string $action, ?string $label = null, array $attri default => null, }; + $state = match (true) { + request()->routeIs('cookieconsent.reset') => CookieConsentState::Reset, + // request()->routeIs('cookieconsent.update') => CookieConsentState::Updating, + default => CookieConsentState::Pending, + }; + if(! $url) { throw new \InvalidArgumentException('Cookie consent action "' . $action . '" does not exist. Try one of these: "accept.all", "accept.essentials", "accept.configuration", "reset".'); } @@ -265,6 +272,7 @@ public function renderButton(string $action, ?string $label = null, array $attri 'attributes' => $attributes, 'basename' => $basename, 'action' => $action, + 'state' => $state, ])->render(); } diff --git a/src/Enums/CookieConsentState.php b/src/Enums/CookieConsentState.php new file mode 100644 index 0000000..a43302b --- /dev/null +++ b/src/Enums/CookieConsentState.php @@ -0,0 +1,18 @@ + Date: Wed, 22 Oct 2025 09:38:36 +0200 Subject: [PATCH 4/4] Added a state property on cookie manager and use it to define when to display the notice --- src/CookiesManager.php | 67 +++++++++++--------- src/Enums/CookieConsentState.php | 9 +++ src/Http/Controllers/AcceptAllController.php | 3 +- src/Http/Controllers/ResetController.php | 3 + 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/CookiesManager.php b/src/CookiesManager.php index 6bd6e8f..9dd86cf 100644 --- a/src/CookiesManager.php +++ b/src/CookiesManager.php @@ -18,6 +18,7 @@ class CookiesManager * The user's current consent preferences. */ protected ?array $preferences = null; + protected CookieConsentState $state; /** * Create a new Service Manager instance. @@ -26,6 +27,7 @@ public function __construct(CookiesRegistrar $registrar, Request $request) { $this->registrar = $registrar; $this->preferences = $this->getCurrentConsentSettings($request); + $this->state = $this->preferences ? CookieConsentState::Configured : CookieConsentState::Pending; } /** @@ -37,12 +39,12 @@ protected function getCurrentConsentSettings(Request $request): ?array ? json_decode($raw, true) : null; - if(! $preferences || ! is_int($preferences['consent_at'] ?? null)) { + if (!$preferences || !is_int($preferences['consent_at'] ?? null)) { return null; } // Check duration in case application settings have changed since the cookie was set. - if($preferences['consent_at'] + (config('cookieconsent.cookie.duration') * 60) < time()) { + if ($preferences['consent_at'] + (config('cookieconsent.cookie.duration') * 60) < time()) { return null; } @@ -54,9 +56,9 @@ protected function getCurrentConsentSettings(Request $request): ?array */ protected function makeConsentSettings(array $categories): array { - return array_reduce($this->registrar->getCategories(), function($values, $category) use ($categories) { + return array_reduce($this->registrar->getCategories(), function ($values, $category) use ($categories) { $state = in_array($category->key(), $categories); - return array_reduce($category->getCookies(), function($values, $cookie) use ($state) { + return array_reduce($category->getCookies(), function ($values, $cookie) use ($state) { $values[$cookie->name] = $state; return $values; }, $values); @@ -77,13 +79,24 @@ public function __call(string $method, array $arguments) */ public function shouldDisplayNotice(): bool { - if(! $this->preferences) { - return true; + if ($this->state === CookieConsentState::Configured) { + $this->state = $this->checkCurrentState() ? CookieConsentState::Pending : CookieConsentState::Configured; } - // Check if each defined cookie has been shown to the user yet. - return array_reduce($this->registrar->getCategories(), function($state, $category) { - return $state ? true : array_reduce($category->getCookies(), function(bool $state, Cookie $cookie) { + return $this->state->shouldDisplayNotice(); + } + + public function setCookieConsentState(CookieConsentState $state): self + { + $this->state = $state; + + return $this; + } + + protected function checkCurrentState(): bool + { + return array_reduce($this->registrar->getCategories(), function ($state, $category) { + return $state ? true : array_reduce($category->getCookies(), function (bool $state, Cookie $cookie) { return $state ? true : !array_key_exists($cookie->name, $this->preferences); }, false); }, false); @@ -94,13 +107,13 @@ public function shouldDisplayNotice(): bool */ public function hasConsentFor(string $key): bool { - if(! $this->preferences) { + if ($this->state === CookieConsentState::Configured) { return false; } - $groups = array_reduce($this->registrar->getCategories(), function($results, $category) use ($key) { - return array_reduce($category->getDefined(), function(array $results, Cookie|CookiesGroup $instance) use ($key) { - if(is_a($instance, CookiesGroup::class) && $instance->name === $key) { + $groups = array_reduce($this->registrar->getCategories(), function ($results, $category) use ($key) { + return array_reduce($category->getDefined(), function (array $results, Cookie|CookiesGroup $instance) use ($key) { + if (is_a($instance, CookiesGroup::class) && $instance->name === $key) { $results[] = $instance; } return $results; @@ -111,8 +124,8 @@ public function hasConsentFor(string $key): bool ? array_unique(array_reduce($groups, fn($cookies, $group) => array_merge($cookies, array_map(fn($cookie) => $cookie->name, $group->getCookies())), [])) : [$key]; - foreach($cookies as $cookie) { - if(! boolval($this->preferences[$cookie] ?? false)) return false; + foreach ($cookies as $cookie) { + if (!boolval($this->preferences[$cookie] ?? false)) return false; } return true; @@ -123,7 +136,7 @@ public function hasConsentFor(string $key): bool */ public function accept(string|array $categories = '*'): ConsentResponse { - if(! is_array($categories) || ! $categories) { + if (!is_array($categories) || !$categories) { $categories = array_map(fn($category) => $category->key(), $this->registrar->getCategories()); } @@ -142,8 +155,8 @@ public function accept(string|array $categories = '*'): ConsentResponse */ protected function getConsentResponse(): ConsentResponse { - return array_reduce($this->registrar->getCategories(), function($response, $category) { - return array_reduce($category->getDefined(), function(ConsentResponse $response, Cookie|CookiesGroup $instance) { + return array_reduce($this->registrar->getCategories(), function ($response, $category) { + return array_reduce($category->getDefined(), function (ConsentResponse $response, Cookie|CookiesGroup $instance) { return $this->hasConsentFor($instance->name) ? $response->handleConsent($instance) : $response; @@ -174,7 +187,7 @@ public function renderScripts(bool $withDefault = true): string ? $this->getNoticeScripts($withDefault) : $this->getConsentedScripts($withDefault); - if(strlen($output)) { + if (strlen($output)) { $output = '' . $output; } @@ -218,7 +231,7 @@ public function renderView(): string public function getNoticeMarkup(): string { - if($policy = config('cookieconsent.policy')) { + if ($policy = config('cookieconsent.policy')) { $policy = route($policy); } @@ -241,13 +254,7 @@ public function renderButton(string $action, ?string $label = null, array $attri default => null, }; - $state = match (true) { - request()->routeIs('cookieconsent.reset') => CookieConsentState::Reset, - // request()->routeIs('cookieconsent.update') => CookieConsentState::Updating, - default => CookieConsentState::Pending, - }; - - if(! $url) { + if (!$url) { throw new \InvalidArgumentException('Cookie consent action "' . $action . '" does not exist. Try one of these: "accept.all", "accept.essentials", "accept.configuration", "reset".'); } @@ -256,7 +263,7 @@ public function renderButton(string $action, ?string $label = null, array $attri 'data-cookie-action' => $action, ], $attributes); - if(! ($attributes['class'] ?? null)) { + if (!($attributes['class'] ?? null)) { $attributes['class'] = 'cookiebtn'; } @@ -272,7 +279,7 @@ public function renderButton(string $action, ?string $label = null, array $attri 'attributes' => $attributes, 'basename' => $basename, 'action' => $action, - 'state' => $state, + 'state' => $this->state, ])->render(); } @@ -291,7 +298,7 @@ public function replaceInfoTag(string $wysiwyg): string $cookieConsentInfo = view('cookie-consent::info', [ 'cookies' => $this->registrar, ])->render(); - + $formattedString = preg_replace( [ '/\<(\w)[^\>]+\>\@cookieconsentinfo\<\/\1\>/', diff --git a/src/Enums/CookieConsentState.php b/src/Enums/CookieConsentState.php index a43302b..e53f549 100644 --- a/src/Enums/CookieConsentState.php +++ b/src/Enums/CookieConsentState.php @@ -15,4 +15,13 @@ enum CookieConsentState // User had configured consent but chose to reset the settings (similar to "pending") case Reset; + + public function shouldDisplayNotice(): bool + { + return match($this) { + static::Pending , static::Reset=> true, + static::Configured => false, +// static::Updating => true, + }; + } } \ No newline at end of file diff --git a/src/Http/Controllers/AcceptAllController.php b/src/Http/Controllers/AcceptAllController.php index 2c28bab..7cf9cd0 100644 --- a/src/Http/Controllers/AcceptAllController.php +++ b/src/Http/Controllers/AcceptAllController.php @@ -4,11 +4,12 @@ use Whitecube\LaravelCookieConsent\CookiesManager; use Illuminate\Http\Request; +use Whitecube\LaravelCookieConsent\Enums\CookieConsentState; class AcceptAllController { public function __invoke(Request $request, CookiesManager $cookies) { - return $cookies->accept('*')->toResponse($request); + return $cookies->setCookieConsentState(CookieConsentState::Configured)->accept('*')->toResponse($request); } } diff --git a/src/Http/Controllers/ResetController.php b/src/Http/Controllers/ResetController.php index 47121ca..d4da18f 100644 --- a/src/Http/Controllers/ResetController.php +++ b/src/Http/Controllers/ResetController.php @@ -4,11 +4,14 @@ use Whitecube\LaravelCookieConsent\CookiesManager; use Illuminate\Http\Request; +use Whitecube\LaravelCookieConsent\Enums\CookieConsentState; class ResetController { public function __invoke(Request $request, CookiesManager $cookies) { + $cookies->setCookieConsentState(CookieConsentState::Reset); + $response = ! $request->expectsJson() ? redirect()->back() : response()->json([