Skip to content

Commit 8d45011

Browse files
authored
Merge branch 'main' into patch-55
2 parents 30649f5 + 9895552 commit 8d45011

20 files changed

+153
-54
lines changed

.github/workflows/run-tests.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
php: [8.4, 8.3, 8.2, 8.1, 8.0]
13-
laravel: ["^11.0", "^10.0", "^9.0", "^8.12"]
13+
laravel: ["^12.0", "^11.0", "^10.0", "^9.0", "^8.12"]
1414
dependency-version: [prefer-lowest, prefer-stable]
1515
include:
16+
- laravel: "^12.0"
17+
testbench: 10.*
1618
- laravel: "^11.0"
1719
testbench: 9.*
1820
- laravel: "^10.0"
@@ -22,6 +24,10 @@ jobs:
2224
- laravel: "^8.12"
2325
testbench: "^6.23"
2426
exclude:
27+
- laravel: "^12.0"
28+
php: 8.1
29+
- laravel: "^12.0"
30+
php: 8.0
2531
- laravel: "^11.0"
2632
php: 8.1
2733
- laravel: "^11.0"
@@ -52,7 +58,7 @@ jobs:
5258

5359
- name: Install dependencies
5460
run: |
55-
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "symfony/console:>=4.3.4" "mockery/mockery:^1.3.2" "nesbot/carbon:>=2.62.1" --no-interaction --no-update
61+
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "symfony/console:>=4.3.4" "mockery/mockery:^1.3.2" "nesbot/carbon:>=2.72.6" --no-interaction --no-update
5662
composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction
5763
5864
- name: Execute tests

CHANGELOG.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,46 @@
22

33
All notable changes to `laravel-permission` will be documented in this file
44

5+
## 6.12.0 - 2025-01-31
6+
7+
### What's Changed
8+
9+
* Support Laravel 12
10+
11+
**Full Changelog**: https://github.com/spatie/laravel-permission/compare/6.11.0...6.12.0
12+
13+
## 6.11.0 - 2025-01-30
14+
15+
### What's Changed
16+
17+
* Add configurable team resolver for permission team id (helpful for Jetstream, etc) by @adrenallen in https://github.com/spatie/laravel-permission/pull/2790
18+
19+
### Internals
20+
21+
* Replace php-cs-fixer with Laravel Pint by @bobbrodie in https://github.com/spatie/laravel-permission/pull/2780
22+
23+
### Documentation Updates
24+
25+
* [Docs] Include namespace in example in uuid.md by @ken-tam in https://github.com/spatie/laravel-permission/pull/2764
26+
* [Docs] Include Laravel 11 example in exceptions.md by @frankliniwobi in https://github.com/spatie/laravel-permission/pull/2768
27+
* [Docs] Fix typo in code example in passport.md by @m3skalina in https://github.com/spatie/laravel-permission/pull/2782
28+
* [Docs] Correct username in new-app.md by @trippodi in https://github.com/spatie/laravel-permission/pull/2785
29+
* [Docs] Add composer specificity by @imanghafoori1 in https://github.com/spatie/laravel-permission/pull/2772
30+
* [Docs] Update installation-laravel.md to fix providers.php location. by @curiousteam in https://github.com/spatie/laravel-permission/pull/2796
31+
32+
### New Contributors
33+
34+
* @ken-tam made their first contribution in https://github.com/spatie/laravel-permission/pull/2764
35+
* @frankliniwobi made their first contribution in https://github.com/spatie/laravel-permission/pull/2768
36+
* @bobbrodie made their first contribution in https://github.com/spatie/laravel-permission/pull/2780
37+
* @m3skalina made their first contribution in https://github.com/spatie/laravel-permission/pull/2782
38+
* @trippodi made their first contribution in https://github.com/spatie/laravel-permission/pull/2785
39+
* @imanghafoori1 made their first contribution in https://github.com/spatie/laravel-permission/pull/2772
40+
* @curiousteam made their first contribution in https://github.com/spatie/laravel-permission/pull/2796
41+
* @adrenallen made their first contribution in https://github.com/spatie/laravel-permission/pull/2790
42+
43+
**Full Changelog**: https://github.com/spatie/laravel-permission/compare/6.10.1...6.11.0
44+
545
## 6.10.1 - 2024-11-08
646

747
### What's Changed
@@ -890,6 +930,8 @@ The following changes are not "breaking", but worth making the updates to your a
890930

891931

892932

933+
934+
893935

894936

895937

@@ -961,6 +1003,8 @@ The following changes are not "breaking", but worth making the updates to your a
9611003

9621004

9631005

1006+
1007+
9641008

9651009

9661010

composer.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@
2323
"homepage": "https://github.com/spatie/laravel-permission",
2424
"require": {
2525
"php": "^8.0",
26-
"illuminate/auth": "^8.12|^9.0|^10.0|^11.0",
27-
"illuminate/container": "^8.12|^9.0|^10.0|^11.0",
28-
"illuminate/contracts": "^8.12|^9.0|^10.0|^11.0",
29-
"illuminate/database": "^8.12|^9.0|^10.0|^11.0"
26+
"illuminate/auth": "^8.12|^9.0|^10.0|^11.0|^12.0",
27+
"illuminate/container": "^8.12|^9.0|^10.0|^11.0|^12.0",
28+
"illuminate/contracts": "^8.12|^9.0|^10.0|^11.0|^12.0",
29+
"illuminate/database": "^8.12|^9.0|^10.0|^11.0|^12.0"
3030
},
3131
"require-dev": {
32-
"larastan/larastan": "^1.0|^2.0",
3332
"laravel/passport": "^11.0|^12.0",
34-
"orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
35-
"phpunit/phpunit": "^9.4|^10.1"
33+
"laravel/pint": "^1.0",
34+
"orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0",
35+
"phpunit/phpunit": "^9.4|^10.1|^11.5"
3636
},
3737
"minimum-stability": "dev",
3838
"prefer-stable": true,
@@ -65,7 +65,7 @@
6565
},
6666
"scripts": {
6767
"test": "phpunit",
68-
"format": "php-cs-fixer fix --allow-risky=yes",
69-
"analyse": "phpstan analyse"
68+
"format": "pint",
69+
"analyse": "echo 'Checking dependencies...' && composer require --dev larastan/larastan && phpstan analyse"
7070
}
7171
}

config/permission.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@
7575
/*
7676
* Change this if you want to name the related pivots other than defaults
7777
*/
78-
'role_pivot_key' => null, //default 'role_id',
79-
'permission_pivot_key' => null, //default 'permission_id',
78+
'role_pivot_key' => null, // default 'role_id',
79+
'permission_pivot_key' => null, // default 'permission_id',
8080

8181
/*
8282
* Change this if you want to name the related model primary key other than
@@ -122,6 +122,11 @@
122122

123123
'teams' => false,
124124

125+
/*
126+
* The class to use to resolve the permissions team id
127+
*/
128+
'team_resolver' => \Spatie\Permission\DefaultTeamResolver::class,
129+
125130
/*
126131
* Passport Client Credentials Grant
127132
* When set to true the package will use Passports Client to check permissions

docs/basic-usage/new-app.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ If you are creating a demo app for reporting a bug or getting help with troubles
160160

161161
If this is your first app with this package, you may want some quick permission examples to see it in action. If you've set up your app using the instructions above, the following examples will work in conjunction with the users and permissions created in the seeder.
162162

163-
Three users were created: test@example.com, [email protected], [email protected] and the password for each is "password".
163+
Three users were created: tester@example.com, [email protected], [email protected] and the password for each is "password".
164164

165165
`/resources/views/dashboard.php`
166166
```diff

docs/basic-usage/passport.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Client extends BaseClient implements AuthorizableContract
2929

3030
public function guardName()
3131
{
32-
return 'api'
32+
return 'api';
3333
}
3434
}
3535
```

docs/best-practices/roles-vs-permissions.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ Summary:
3232
Sometimes certain groups of `route` rules may make best sense to group them around a `role`, but still, whenever possible, there is less overhead used if you can check against a specific `permission` instead.
3333

3434

35+
### FURTHER READING:
36+
37+
[@joelclermont](https://github.com/joelclermont) at [masteringlaravel.io](https://masteringlaravel.io/daily) offers similar guidance in his post about [Treating Feature Access As Data, Not Code](https://masteringlaravel.io/daily/2025-01-09-treat-feature-access-as-data-not-code)

docs/installation-laravel.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Choose the version of this package that suits your Laravel version.
99

1010
Package Version | Laravel Version
1111
----------------|-----------
12-
^6.0 | 8,9,10,11 (PHP 8.0+)
12+
^6.0 | 8,9,10,11,12 (PHP 8.0+)
1313
^5.8 | 7,8,9,10
1414
^5.7 | 7,8,9
1515
^5.4-^5.6 | 7,8
@@ -28,14 +28,7 @@ Package Version | Laravel Version
2828

2929
composer require spatie/laravel-permission
3030

31-
4. Optional: The service provider will automatically get registered. Or you may manually add the service provider in your `config/app.php` file:
32-
33-
```
34-
'providers' => [
35-
// ...
36-
Spatie\Permission\PermissionServiceProvider::class,
37-
];
38-
```
31+
4. Optional: The **`Spatie\Permission\PermissionServiceProvider::class`** service provider will automatically get registered. Or you may manually add the service provider to the array in your `bootstrap/providers.php` (or `config/app.php` in Laravel 10 or older) file.
3932

4033
5. **You should publish** [the migration](https://github.com/spatie/laravel-permission/blob/main/database/migrations/create_permission_tables.php.stub) and the [`config/permission.php` config file](https://github.com/spatie/laravel-permission/blob/main/config/permission.php) with:
4134

docs/upgrading.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ weight: 6
77

88
ALL upgrades of this package should follow these steps:
99

10-
1. Composer. Upgrading between major versions of this package always require the usual Composer steps:
10+
1. Composer. Upgrading between major versions of this package always requires the usual Composer steps:
1111
- Update your `composer.json` to specify the new major version, for example: `^6.0`
12-
- Then run `composer update`.
12+
- Then run `composer update spatie/laravel-permission`.
1313

1414
2. Migrations. Compare the `migration` file stubs in the NEW version of this package against the migrations you've already run inside your app. If necessary, create a new migration (by hand) to apply any new database changes.
1515

@@ -32,16 +32,16 @@ There are a few breaking-changes when upgrading to v6, but most of them won't af
3232

3333
For guidance with upgrading your extended models, your migrations, your routes, etc, see the **Upgrade Essentials** section at the top of this file.
3434

35-
1. Due to the improved ULID/UUID/GUID support, any package methods which accept a Permission or Role `id` must pass that `id` as an `integer`. If you pass it as a numeric string, the functions will attempt to lookup the role/permission as a string. In such cases you may see errors such as `There is no permission named '123' for guard 'web'.` (where `'123'` is being treated as a string because it was passed as a string instead of as an integer). This also applies to arrays of id's: if it's an array of strings we will do a lookup on the name instead of on the id. **This will mostly only affect UI pages** because an HTML Request is received as string data. **The solution is simple:** if you're passing integers to a form field, then convert them back to integers when using that field's data for calling functions to grant/assign/sync/remove/revoke permissions and roles. One way to convert an array of permissions `id`'s from strings to integers is: `collect($validated['permission'])->map(fn($val)=>(int)$val)`
35+
1. Due to the improved ULID/UUID/GUID support, any package methods which accept a Permission or Role `id` must pass that `id` as an `integer`. If you pass it as a numeric string, the functions will attempt to look up the role/permission as a string. In such cases, you may see errors such as `There is no permission named '123' for guard 'web'.` (where `'123'` is being treated as a string because it was passed as a string instead of as an integer). This also applies to arrays of id's: if it's an array of strings we will do a lookup on the name instead of on the id. **This will mostly only affect UI pages** because an HTML Request is received as string data. **The solution is simple:** if you're passing integers to a form field, then convert them back to integers when using that field's data for calling functions to grant/assign/sync/remove/revoke permissions and roles. One way to convert an array of permissions `id`'s from strings to integers is: `collect($validated['permission'])->map(fn($val)=>(int)$val)`
3636

3737
2. If you have overridden the `getPermissionClass()` or `getRoleClass()` methods or have custom Models, you will need to revisit those customizations. See PR #2368 for details.
3838
eg: if you have a custom model you will need to make changes, including accessing the model using `$this->permissionClass::` syntax (eg: using `::` instead of `->`) in all the overridden methods that make use of the models.
3939

40-
Be sure to compare your custom models with originals to see what else may have changed.
40+
Be sure to compare your custom models with the originals to see what else may have changed.
4141

4242
3. Model and Contract/Interface updates. The Role and Permission Models and Contracts/Interfaces have been updated with syntax changes to method signatures. Update any models you have extended, or contracts implemented, accordingly. See PR [#2380](https://github.com/spatie/laravel-permission/pull/2380) and [#2480](https://github.com/spatie/laravel-permission/pull/2480) for some of the specifics.
4343

44-
4. Migrations WILL need to be upgraded. (They have been updated to anonymous-class syntax that was introduced in Laravel 8, AND some structural coding changes in the registrar class changed the way we extracted configuration settings in the migration files.) There are no changes to the package's structure since v5, so if you had not customized it from the original then replacing the contents of the file should be enough. (Usually the only customization is if you've switched to UUIDs or customized MySQL index name lengths.)
44+
4. Migrations WILL need to be upgraded. (They have been updated to anonymous-class syntax that was introduced in Laravel 8, AND some structural coding changes in the registrar class changed the way we extracted configuration settings in the migration files.) There are no changes to the package's structure since v5, so if you had not customized it from the original then replacing the contents of the file should be enough. (Usually, the only customization is if you've switched to UUIDs or customized MySQL index name lengths.)
4545
**If you get the following error, it means your migration file needs upgrading: `Error: Access to undeclared static property Spatie\Permission\PermissionRegistrar::$pivotPermission`**
4646

4747
5. MIDDLEWARE:
@@ -52,7 +52,7 @@ eg: if you have a custom model you will need to make changes, including accessin
5252

5353
3. In the unlikely event that you have customized the Wildcard Permissions feature by extending the `WildcardPermission` model, please note that the public interface has changed significantly and you will need to update your extended model with the new method signatures.
5454

55-
6. Test suites. If you have tests which manually clear the permission cache and re-register permissions, you no longer need to call `\Spatie\Permission\PermissionRegistrar::class)->registerPermissions();`. In fact, **calls to `->registerPermissions()` MUST be deleted from your tests**.
55+
6. Test suites. If you have tests that manually clear the permission cache and re-register permissions, you no longer need to call `\Spatie\Permission\PermissionRegistrar::class)->registerPermissions();`. In fact, **calls to `->registerPermissions()` MUST be deleted from your tests**.
5656

5757
(Calling `app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();` after creating roles and permissions in migrations and factories and seeders is still okay and encouraged.)
5858

pint.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"preset": "laravel",
3+
"rules": {
4+
"php_unit_method_casing": false
5+
}
6+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Spatie\Permission\Contracts;
4+
5+
interface PermissionsTeamResolver
6+
{
7+
public function getPermissionsTeamId(): int|string|null;
8+
9+
/**
10+
* Set the team id for teams/groups support, this id is used when querying permissions/roles
11+
*
12+
* @param int|string|\Illuminate\Database\Eloquent\Model|null $id
13+
*/
14+
public function setPermissionsTeamId($id): void;
15+
}

src/DefaultTeamResolver.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Spatie\Permission;
4+
5+
use Spatie\Permission\Contracts\PermissionsTeamResolver;
6+
7+
class DefaultTeamResolver implements PermissionsTeamResolver
8+
{
9+
protected int|string|null $teamId = null;
10+
11+
/**
12+
* Set the team id for teams/groups support, this id is used when querying permissions/roles
13+
*
14+
* @param int|string|\Illuminate\Database\Eloquent\Model|null $id
15+
*/
16+
public function setPermissionsTeamId($id): void
17+
{
18+
if ($id instanceof \Illuminate\Database\Eloquent\Model) {
19+
$id = $id->getKey();
20+
}
21+
$this->teamId = $id;
22+
}
23+
24+
public function getPermissionsTeamId(): int|string|null
25+
{
26+
return $this->teamId;
27+
}
28+
}

src/PermissionRegistrar.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Database\Eloquent\Collection;
1111
use Illuminate\Database\Eloquent\Model;
1212
use Spatie\Permission\Contracts\Permission;
13+
use Spatie\Permission\Contracts\PermissionsTeamResolver;
1314
use Spatie\Permission\Contracts\Role;
1415

1516
class PermissionRegistrar
@@ -34,9 +35,9 @@ class PermissionRegistrar
3435

3536
public bool $teams;
3637

37-
public string $teamsKey;
38+
protected PermissionsTeamResolver $teamResolver;
3839

39-
protected string|int|null $teamId = null;
40+
public string $teamsKey;
4041

4142
public string $cacheKey;
4243

@@ -55,6 +56,7 @@ public function __construct(CacheManager $cacheManager)
5556
{
5657
$this->permissionClass = config('permission.models.permission');
5758
$this->roleClass = config('permission.models.role');
59+
$this->teamResolver = new (config('permission.team_resolver', DefaultTeamResolver::class));
5860

5961
$this->cacheManager = $cacheManager;
6062
$this->initializeCache();
@@ -101,18 +103,15 @@ protected function getCacheStoreFromConfig(): Repository
101103
*/
102104
public function setPermissionsTeamId($id): void
103105
{
104-
if ($id instanceof \Illuminate\Database\Eloquent\Model) {
105-
$id = $id->getKey();
106-
}
107-
$this->teamId = $id;
106+
$this->teamResolver->setPermissionsTeamId($id);
108107
}
109108

110109
/**
111110
* @return int|string|null
112111
*/
113112
public function getPermissionsTeamId()
114113
{
115-
return $this->teamId;
114+
return $this->teamResolver->getPermissionsTeamId();
116115
}
117116

118117
/**

src/Traits/HasPermissions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ public function getAllPermissions(): Collection
349349
/** @var Collection $permissions */
350350
$permissions = $this->permissions;
351351

352-
if (!is_a($this, Permission::class)) {
352+
if (! is_a($this, Permission::class)) {
353353
$permissions = $permissions->merge($this->getPermissionsViaRoles());
354354
}
355355

tests/CommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public function it_can_setup_teams_upgrade()
149149

150150
$AddTeamsFields = require $matchingFiles[count($matchingFiles) - 1];
151151
$AddTeamsFields->up();
152-
$AddTeamsFields->up(); //test upgrade teams migration fresh
152+
$AddTeamsFields->up(); // test upgrade teams migration fresh
153153

154154
Role::create(['name' => 'new-role', 'team_test_id' => 1]);
155155
$role = Role::where('name', 'new-role')->first();

tests/HasPermissionsTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ public function it_does_not_run_unnecessary_sqls_when_assigning_new_permissions(
654654
$this->testUser->syncPermissions($this->testUserPermission, $permission2);
655655
DB::disableQueryLog();
656656

657-
$this->assertSame(2, count(DB::getQueryLog())); //avoid unnecessary sqls
657+
$this->assertSame(2, count(DB::getQueryLog())); // avoid unnecessary sqls
658658
}
659659

660660
/** @test */
@@ -676,7 +676,7 @@ public function calling_givePermissionTo_before_saving_object_doesnt_interfere_w
676676

677677
$this->assertTrue($user2->fresh()->hasPermissionTo('edit-articles'));
678678
$this->assertFalse($user2->fresh()->hasPermissionTo('edit-news'));
679-
$this->assertSame(2, count(DB::getQueryLog())); //avoid unnecessary sync
679+
$this->assertSame(2, count(DB::getQueryLog())); // avoid unnecessary sync
680680
}
681681

682682
/** @test */
@@ -698,7 +698,7 @@ public function calling_syncPermissions_before_saving_object_doesnt_interfere_wi
698698

699699
$this->assertTrue($user2->fresh()->hasPermissionTo('edit-articles'));
700700
$this->assertFalse($user2->fresh()->hasPermissionTo('edit-news'));
701-
$this->assertSame(2, count(DB::getQueryLog())); //avoid unnecessary sync
701+
$this->assertSame(2, count(DB::getQueryLog())); // avoid unnecessary sync
702702
}
703703

704704
/** @test */

0 commit comments

Comments
 (0)