soyhuce / laravel-fluent-policy
Write fluent policies in Laravel
Fund package maintenance!
soyhuce
Installs: 9 029
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 3
Forks: 0
Open Issues: 2
Requires
- php: ^8.3
- illuminate/auth: ^11.0
- illuminate/contracts: ^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.7
- larastan/larastan: ^3.0
- nunomaduro/collision: ^8.1
- orchestra/testbench: ^9.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
This package is auto-updated.
Last update: 2024-12-17 12:43:43 UTC
README
Write your policies fluently in Laravel.
<?php class PostPolicy extends FluentPolicy { public function delete(User $user, Post $post): Response { return $this->denyWhen($post->user_id !== $user->id) ->denyWhen($post->published_at !== null) ->allow(); } }
Installation
You can install the package via composer:
composer require soyhuce/laravel-fluent-policy
Usage
The goal of this package is to write your policies more easily in a clean syntax.
For exemple, the following policy:
<?php use Illuminate\Auth\Access\HandlesAuthorization; class PostPolicy { use HandlesAuthorization; public function delete(User $user, Post $post): bool { if ($post->user_id !== $user->id) { return false; } if ($post->published_at !== null) { return false; } return true; } }
can be re-written as:
<?php use Illuminate\Auth\Access\Response; use Soyhuce\FluentPolicy\FluentPolicy; class PostPolicy extends FluentPolicy { public function delete(User $user, Post $post): Response { return $this->denyWhen($post->user_id !== $user->id) ->denyWhen($post->published_at !== null) ->allow(); } }
You can customise the response if needed :
return $this->denyWhen($post->published_at !== null, 'You cannot delete a published post') ->allow();
You can also call another policy or gate this way :
return $this->authorize($user, 'update', $post) ->allowWhen($post->published_at === null) ->deny();
Custom Http status
You can deny the policy returning a custom http status code :
return $this->denyWithStatusWhen($post->user_id !== $user->id, 404) ->allow(); // or $this->>allowWhen(...)->denyWithStatus(404);
In the case of 404
status code, you can use the shortcut
return $this->denyAsNotFoundWhen($post->user_id !== $user->id) ->allow(); // or $this->>allowWhen(...)->denyAsNotFound();
Lazy evaluation
The different branches allowWhen
and denyWhen
are evaluated lazily which mean that the following code is completely
correct :
<?php use Illuminate\Auth\Access\Response; use Soyhuce\FluentPolicy\FluentPolicy; class PostPolicy extends FluentPolicy { public function delete(User $user, Post $post): Response { // Here, $post->published_at is Carbon or null return $this->denyWhen($post->user_id !== $user->id) ->allowWhen($post->published_at === null) // 1 ->allowWhen($post->published_at->isFuture()) // 2 ->deny(); } }
2
will only be called if previous branches are all false. We are sure that here $post->published_at
is not null
thanks to 1
.
PHPStan
When running PHPStan on
public function delete(User $user, Post $post): Response { return $this->denyWhen($post->user_id !== $user->id) ->allowWhen($post->published_at === null) // 1 ->allowWhen($post->published_at->isFuture()) // 2 ->deny(); }
an error is raised on 2
(Cannot call method
isFuture on Carbon|null
).
An extension is available to fix this issue and should be included in your phpstan.neon
file.
includes: - vendor/bin/soyhuce/laravel-fluent-policies/extension.neon
Unfortunately, due to a PHPStan limitation, you still have to rewrite your policy a little bit :
public function delete(User $user, Post $post): Response { $this->denyWhen($post->user_id !== $user->id) ->allowWhen($post->published_at === null); // From here, PHPStan understands that $post->published_at is not null return $this->allowWhen($post->published_at->isFuture()) ->deny(); }
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.