{"id":32443973,"url":"https://github.com/gecche/laravel-policy-builder","last_synced_at":"2026-03-06T19:06:29.757Z","repository":{"id":62509469,"uuid":"212046326","full_name":"gecche/laravel-policy-builder","owner":"gecche","description":"A simple way to build allowed list of eloquent models (acl)","archived":false,"fork":false,"pushed_at":"2025-02-26T08:24:08.000Z","size":78,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-28T07:52:30.390Z","etag":null,"topics":["acl","eloquent","filtering-lists","laravel","permissions","php","policies","policy"],"latest_commit_sha":null,"homepage":null,"language":"PHP","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/gecche.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-01T08:24:32.000Z","updated_at":"2025-02-26T08:24:11.000Z","dependencies_parsed_at":"2022-11-02T10:30:45.180Z","dependency_job_id":null,"html_url":"https://github.com/gecche/laravel-policy-builder","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/gecche/laravel-policy-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gecche%2Flaravel-policy-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gecche%2Flaravel-policy-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gecche%2Flaravel-policy-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gecche%2Flaravel-policy-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gecche","download_url":"https://codeload.github.com/gecche/laravel-policy-builder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gecche%2Flaravel-policy-builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30192430,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T18:54:55.862Z","status":"ssl_error","status_checked_at":"2026-03-06T18:53:04.013Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["acl","eloquent","filtering-lists","laravel","permissions","php","policies","policy"],"created_at":"2025-10-26T03:03:50.370Z","updated_at":"2026-03-06T19:06:29.749Z","avatar_url":"https://github.com/gecche.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://tldrlegal.com/license/mit-license)\n[![Laravel](https://img.shields.io/badge/Laravel-12.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-11.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-10.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-9.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-8.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-7.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-6.x-orange.svg?style=flat-square)](http://laravel.com)\n[![Laravel](https://img.shields.io/badge/Laravel-5.x-orange.svg?style=flat-square)](http://laravel.com)\n\n# laravel-policy-builder\nA simple and convenient way to build allowed list of Eloquent models according to policies.\n\n## Description\n  In many apps you use Laravel's Policies for checking if an user is allowed to handle a resource. \n  Usually, in those apps, you also have to get lists of allowed resources accordingly to policies.\n  \n  By using this package you store the business logic of filtering lists of resources directly in the \n  policies and you get such lists by simply calling the method `acl` when using an Eloquent Builder.\n\n## Documentation\n\n### Version Compatibility\n\n Laravel  | PolicyBuilder\n:---------|:----------\n 12.x     | 12.x\n 11.x     | 11.x\n 10.x     | 10.x\n 9.x      | 5.x\n 8.x      | 4.x\n 7.x      | 3.x\n 6.x      | 2.x\n 5.8.x    | 1.4.x\n 5.7.x    | 1.3.x\n 5.6.x    | 1.2.x\n 5.5.x    | 1.1.x\n\n### Installation\n\nAdd gecche/laravel-policy-builder as a requirement to composer.json:\n\n```javascript\n{\n    \"require\": {\n        \"gecche/laravel-policy-builder\": \"12.*\"\n    }\n}\n```\n\nThis package makes use of the discovery feature.\n\n### Basic usage\n\n#### Define the business logic of building allowed lists of models in the policies\nLet us suppose to have an `Author` Model class and a standard `AuthorPolicy` class for defining ability methods as \nusual.\n\nSimply add directly in the `AuthorPolicy` class the business logic for filtering lists of Author. E.g.:\n\n```php\nclass AuthorPolicy\n{\n    use HandlesAuthorization;\n\n    /**\n     *\n     * - All authors are allowed to users 1 and 2\n     * - Only italian authors are allowed to users 3 and 4\n     * - Only non-italian authors are allowed to other users\n     *\n     * @param   \\Illuminate\\Contracts\\Auth\\Authenticatable|null $user\n     * @param  Builder $builder\n     * @return mixed\n     */\n    public function acl($user, $builder)\n    {\n    \n        switch ($user-\u003egetKey()) {\n            case 1:\n            case 2:\n                return $builder;\n            case 3:\n            case 4:\n                return $builder-\u003ewhere('nation','IT');\n            default:\n                return $builder-\u003ewhere('nation','\u003c\u003e','IT');\n\n        }\n\n\n    }\n```\n\n\n#### Get the allowed list of models for an user\n\nNow, to get the allowed list of authors for the currently authenticated user, simply do:\n\n```php\n    Author::acl()-\u003eget();\n```\n\nIf you want the list for the user 3, simply do:\n\n```php\n    $userForAcl = User::find(3);\n    Code::acl($userForAcl)-\u003eget();\n```\n\nNow the lists returns only italian authors.\n\n#### Default list\n\nLet us consider another `Book` model for which either the `acl` method has not been defined in \nits `BookPolicy` or there is no `BookPolicy` at all.\n\nIf we do:\n\n```php\n    Book::acl()-\u003eget();\n```\n\nwe get the empty list of models for any user.\n\n\n### Beyond the basics\n\nOnce installed, other than the `acl` Eloquent Builder macro, \nthe package provides the `PolicyBuilderServiceProvider` (together with the \n`PolicyBuilder` facade) which performs the underlying machinery for linking \nthe Eloquent Builder with the policies \n(by wrapping the Laravel's `Gate` provider) and it offers some useful methods.\n\n#### Basic default builder methods: `all` and `none` \n\nThe PolicyBuilder has two public methods, namely `all` and `none` which basically, \ngiven an Eloquent Builder adn (optionally) the model class name, return respectively \nthe list of all available models (no filters at all) and the empty list.\n\nThe return of above methods can be customized by using the `setAllBuilder` and `setNoneBuilder` methods.\n\nIn the following example we change the previous `AuthorPolicy` class with the  \nPolicyBuilder's `all` method, but we leave the same semantics as before.\n\n```php\nuse Gecche\\PolicyBuilder\\Facades\\PolicyBuilder;\nuse App\\Models\\Author;\n\nclass AuthorPolicy\n{\n    use HandlesAuthorization;\n\n    /**\n     *\n     * - All authors are allowed to users 1 and 2\n     * - Only italian authors are allowed to users 3 and 4\n     * - Only non-italian authors are allowed to other users\n     *\n     * @param   \\Illuminate\\Contracts\\Auth\\Authenticatable|null $user\n     * @param  Builder $builder\n     * @return mixed\n     */\n    public function acl($user, $builder)\n    {\n    \n        switch ($user-\u003egetKey()) {\n            case 1:\n            case 2:\n                return PolicyBuilder::all($builder,Author::class);\n            case 3:\n            case 4:\n                return $builder-\u003ewhere('nation','IT');\n            default:\n                return $builder-\u003ewhere('nation','\u003c\u003e','IT');\n\n        }\n    }\n```\n    \nAs before for both user 1 and 2 the full list of authors is returned if we do:\n\n```php\n    Author::acl()-\u003eget();\n```\n\nHowever we can set globally a different semantics for the PolicyBuilder's `all` method, e.g.: \n\n```php\nPolicyBuilder::setAllBuilder(function ($builder,$modelClassName = null) {\n    if ($modelClassName == Author::class) {\n        return $builder-\u003ewhere('id','\u003c\u003e',1);\n    }\n    return $builder;\n});\n```\n\nIn the above example when the `all` method is called the list of authors lacks \nthe author with id 1.\n\nThe same can be done with the PolicyBuilder's `none` method.\n\n\n#### Changing the \"context\" \n\nUsually, an user either can access or not a certain model. \nBut there are some cases in which, under certain \"context\", we need to built \na list of allowed models which is different than the standard one.\n\nFor example, an user can view the whole list of `Author` models in the library, \nbut it cannot edit all of them. \nSo we want to build also the list of books which the user can edit \nand we are changing to the `editing` \"context\" with a different business \nlogic for building the list.\n   \nIn that case, simply pass the \"context\" to the builder:\n   \n```php\n    //returning the 'editing' list for the authenticated user \n    Author::acl(null,'editing')-\u003eget();\n    //or returning the 'editing' list for user 2 \n    $userForAcl = User::find(2);\n    Author::acl($userForAcl,'editing')-\u003eget();\n```\n\nIn the AuthorPolicy you have to define accordingly the  `aclEditing` method as done before for the `acl` one.\n\n\n#### `beforeAcl` PolicyBuilder and Policy methods\n \nLike the Laravel's Gate `before` method, PolicyBuilder has a `beforeAcl` method for registering\n  \"beforeAcl\" callbacks. If a registered callback returns an Eloquent Builder, further elaboration \n  is not needed and thus no policy is needed at all. E.g.:\n  \n```php\n/*\n * - For user 1 (superuser) it returns the full list of models for any model and context\n * - For all the other registerd users, it returns the full list of models for Book\n */\nPolicyBuilder::beforeAcl(function ($user, $modelClassName, $context, $builder) {\n\n    if (!$user) {\n        return;\n    }\n\n    if ($user-\u003egetKey() == 1 || $modelClassName == Book::class) {\n        return PolicyBuilder::all($builder,$modelClassName);\n    }\n\n    return;\n});  \n```\n\nA very similar `beforeAcl` method can also be placed into a single policy and \nit will be handled by the `PolicyBuilderServiceProvider` before elaborating \nany other method in the policy. \n\n```php\nuse Gecche\\PolicyBuilder\\Facades\\PolicyBuilder;\nuse App\\Models\\Author;\n\nclass AuthorPolicy\n{\n    use HandlesAuthorization;\n\n\n    public function beforeAcl($user, $context, $builder) {\n\n        if (is_null($user)) {\n            return PolicyBuilder::none($builder,Author::class);\n        }\n\n        return null;\n\n    }\n\n    ...\n    \n```\n\nIn the above example, the guest user has no access at all to the authors.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgecche%2Flaravel-policy-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgecche%2Flaravel-policy-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgecche%2Flaravel-policy-builder/lists"}