Skip to content

Commit

Permalink
Merge branch 'main' into patch-55
Browse files Browse the repository at this point in the history
  • Loading branch information
drbyte authored Jan 31, 2025
2 parents 30649f5 + 9895552 commit 8d45011
Show file tree
Hide file tree
Showing 20 changed files with 153 additions and 54 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ jobs:
fail-fast: false
matrix:
php: [8.4, 8.3, 8.2, 8.1, 8.0]
laravel: ["^11.0", "^10.0", "^9.0", "^8.12"]
laravel: ["^12.0", "^11.0", "^10.0", "^9.0", "^8.12"]
dependency-version: [prefer-lowest, prefer-stable]
include:
- laravel: "^12.0"
testbench: 10.*
- laravel: "^11.0"
testbench: 9.*
- laravel: "^10.0"
Expand All @@ -22,6 +24,10 @@ jobs:
- laravel: "^8.12"
testbench: "^6.23"
exclude:
- laravel: "^12.0"
php: 8.1
- laravel: "^12.0"
php: 8.0
- laravel: "^11.0"
php: 8.1
- laravel: "^11.0"
Expand Down Expand Up @@ -52,7 +58,7 @@ jobs:

- name: Install dependencies
run: |
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
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
composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction
- name: Execute tests
Expand Down
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@

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

## 6.12.0 - 2025-01-31

### What's Changed

* Support Laravel 12

**Full Changelog**: https://github.com/spatie/laravel-permission/compare/6.11.0...6.12.0

## 6.11.0 - 2025-01-30

### What's Changed

* Add configurable team resolver for permission team id (helpful for Jetstream, etc) by @adrenallen in https://github.com/spatie/laravel-permission/pull/2790

### Internals

* Replace php-cs-fixer with Laravel Pint by @bobbrodie in https://github.com/spatie/laravel-permission/pull/2780

### Documentation Updates

* [Docs] Include namespace in example in uuid.md by @ken-tam in https://github.com/spatie/laravel-permission/pull/2764
* [Docs] Include Laravel 11 example in exceptions.md by @frankliniwobi in https://github.com/spatie/laravel-permission/pull/2768
* [Docs] Fix typo in code example in passport.md by @m3skalina in https://github.com/spatie/laravel-permission/pull/2782
* [Docs] Correct username in new-app.md by @trippodi in https://github.com/spatie/laravel-permission/pull/2785
* [Docs] Add composer specificity by @imanghafoori1 in https://github.com/spatie/laravel-permission/pull/2772
* [Docs] Update installation-laravel.md to fix providers.php location. by @curiousteam in https://github.com/spatie/laravel-permission/pull/2796

### New Contributors

* @ken-tam made their first contribution in https://github.com/spatie/laravel-permission/pull/2764
* @frankliniwobi made their first contribution in https://github.com/spatie/laravel-permission/pull/2768
* @bobbrodie made their first contribution in https://github.com/spatie/laravel-permission/pull/2780
* @m3skalina made their first contribution in https://github.com/spatie/laravel-permission/pull/2782
* @trippodi made their first contribution in https://github.com/spatie/laravel-permission/pull/2785
* @imanghafoori1 made their first contribution in https://github.com/spatie/laravel-permission/pull/2772
* @curiousteam made their first contribution in https://github.com/spatie/laravel-permission/pull/2796
* @adrenallen made their first contribution in https://github.com/spatie/laravel-permission/pull/2790

**Full Changelog**: https://github.com/spatie/laravel-permission/compare/6.10.1...6.11.0

## 6.10.1 - 2024-11-08

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








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








Expand Down
18 changes: 9 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
"homepage": "https://github.com/spatie/laravel-permission",
"require": {
"php": "^8.0",
"illuminate/auth": "^8.12|^9.0|^10.0|^11.0",
"illuminate/container": "^8.12|^9.0|^10.0|^11.0",
"illuminate/contracts": "^8.12|^9.0|^10.0|^11.0",
"illuminate/database": "^8.12|^9.0|^10.0|^11.0"
"illuminate/auth": "^8.12|^9.0|^10.0|^11.0|^12.0",
"illuminate/container": "^8.12|^9.0|^10.0|^11.0|^12.0",
"illuminate/contracts": "^8.12|^9.0|^10.0|^11.0|^12.0",
"illuminate/database": "^8.12|^9.0|^10.0|^11.0|^12.0"
},
"require-dev": {
"larastan/larastan": "^1.0|^2.0",
"laravel/passport": "^11.0|^12.0",
"orchestra/testbench": "^6.23|^7.0|^8.0|^9.0",
"phpunit/phpunit": "^9.4|^10.1"
"laravel/pint": "^1.0",
"orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0",
"phpunit/phpunit": "^9.4|^10.1|^11.5"
},
"minimum-stability": "dev",
"prefer-stable": true,
Expand Down Expand Up @@ -65,7 +65,7 @@
},
"scripts": {
"test": "phpunit",
"format": "php-cs-fixer fix --allow-risky=yes",
"analyse": "phpstan analyse"
"format": "pint",
"analyse": "echo 'Checking dependencies...' && composer require --dev larastan/larastan && phpstan analyse"
}
}
9 changes: 7 additions & 2 deletions config/permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@
/*
* Change this if you want to name the related pivots other than defaults
*/
'role_pivot_key' => null, //default 'role_id',
'permission_pivot_key' => null, //default 'permission_id',
'role_pivot_key' => null, // default 'role_id',
'permission_pivot_key' => null, // default 'permission_id',

/*
* Change this if you want to name the related model primary key other than
Expand Down Expand Up @@ -122,6 +122,11 @@

'teams' => false,

/*
* The class to use to resolve the permissions team id
*/
'team_resolver' => \Spatie\Permission\DefaultTeamResolver::class,

/*
* Passport Client Credentials Grant
* When set to true the package will use Passports Client to check permissions
Expand Down
2 changes: 1 addition & 1 deletion docs/basic-usage/new-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ If you are creating a demo app for reporting a bug or getting help with troubles

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.

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

`/resources/views/dashboard.php`
```diff
Expand Down
2 changes: 1 addition & 1 deletion docs/basic-usage/passport.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Client extends BaseClient implements AuthorizableContract

public function guardName()
{
return 'api'
return 'api';
}
}
```
Expand Down
3 changes: 3 additions & 0 deletions docs/best-practices/roles-vs-permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ Summary:
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.


### FURTHER READING:

[@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)
11 changes: 2 additions & 9 deletions docs/installation-laravel.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Choose the version of this package that suits your Laravel version.

Package Version | Laravel Version
----------------|-----------
^6.0 | 8,9,10,11 (PHP 8.0+)
^6.0 | 8,9,10,11,12 (PHP 8.0+)
^5.8 | 7,8,9,10
^5.7 | 7,8,9
^5.4-^5.6 | 7,8
Expand All @@ -28,14 +28,7 @@ Package Version | Laravel Version

composer require spatie/laravel-permission

4. Optional: The service provider will automatically get registered. Or you may manually add the service provider in your `config/app.php` file:

```
'providers' => [
// ...
Spatie\Permission\PermissionServiceProvider::class,
];
```
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.

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:

Expand Down
12 changes: 6 additions & 6 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ weight: 6

ALL upgrades of this package should follow these steps:

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

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.

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

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

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)`
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)`

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.
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.

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

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.

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.)
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.)
**If you get the following error, it means your migration file needs upgrading: `Error: Access to undeclared static property Spatie\Permission\PermissionRegistrar::$pivotPermission`**

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

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.

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**.
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**.

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

Expand Down
6 changes: 6 additions & 0 deletions pint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"preset": "laravel",
"rules": {
"php_unit_method_casing": false
}
}
15 changes: 15 additions & 0 deletions src/Contracts/PermissionsTeamResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Spatie\Permission\Contracts;

interface PermissionsTeamResolver
{
public function getPermissionsTeamId(): int|string|null;

/**
* Set the team id for teams/groups support, this id is used when querying permissions/roles
*
* @param int|string|\Illuminate\Database\Eloquent\Model|null $id
*/
public function setPermissionsTeamId($id): void;
}
28 changes: 28 additions & 0 deletions src/DefaultTeamResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Spatie\Permission;

use Spatie\Permission\Contracts\PermissionsTeamResolver;

class DefaultTeamResolver implements PermissionsTeamResolver
{
protected int|string|null $teamId = null;

/**
* Set the team id for teams/groups support, this id is used when querying permissions/roles
*
* @param int|string|\Illuminate\Database\Eloquent\Model|null $id
*/
public function setPermissionsTeamId($id): void
{
if ($id instanceof \Illuminate\Database\Eloquent\Model) {
$id = $id->getKey();
}
$this->teamId = $id;
}

public function getPermissionsTeamId(): int|string|null
{
return $this->teamId;
}
}
13 changes: 6 additions & 7 deletions src/PermissionRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Contracts\Permission;
use Spatie\Permission\Contracts\PermissionsTeamResolver;
use Spatie\Permission\Contracts\Role;

class PermissionRegistrar
Expand All @@ -34,9 +35,9 @@ class PermissionRegistrar

public bool $teams;

public string $teamsKey;
protected PermissionsTeamResolver $teamResolver;

protected string|int|null $teamId = null;
public string $teamsKey;

public string $cacheKey;

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

$this->cacheManager = $cacheManager;
$this->initializeCache();
Expand Down Expand Up @@ -101,18 +103,15 @@ protected function getCacheStoreFromConfig(): Repository
*/
public function setPermissionsTeamId($id): void
{
if ($id instanceof \Illuminate\Database\Eloquent\Model) {
$id = $id->getKey();
}
$this->teamId = $id;
$this->teamResolver->setPermissionsTeamId($id);
}

/**
* @return int|string|null
*/
public function getPermissionsTeamId()
{
return $this->teamId;
return $this->teamResolver->getPermissionsTeamId();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Traits/HasPermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ public function getAllPermissions(): Collection
/** @var Collection $permissions */
$permissions = $this->permissions;

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

Expand Down
2 changes: 1 addition & 1 deletion tests/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public function it_can_setup_teams_upgrade()

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

Role::create(['name' => 'new-role', 'team_test_id' => 1]);
$role = Role::where('name', 'new-role')->first();
Expand Down
6 changes: 3 additions & 3 deletions tests/HasPermissionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ public function it_does_not_run_unnecessary_sqls_when_assigning_new_permissions(
$this->testUser->syncPermissions($this->testUserPermission, $permission2);
DB::disableQueryLog();

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

/** @test */
Expand All @@ -676,7 +676,7 @@ public function calling_givePermissionTo_before_saving_object_doesnt_interfere_w

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

/** @test */
Expand All @@ -698,7 +698,7 @@ public function calling_syncPermissions_before_saving_object_doesnt_interfere_wi

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

/** @test */
Expand Down
Loading

0 comments on commit 8d45011

Please sign in to comment.