bezhanSalleh / filament-shield

The easiest and most intuitive way to add access management to your Filament Panel; Resources, Pages & Widgets through `spatie/laravel-permission`
MIT License
1.75k stars 195 forks source link

extra columns in Role model creates it as an extra permission when using Spatie Laravel Translatable #325

Closed eelco2k closed 6 months ago

eelco2k commented 9 months ago

After adding a column "description" to the Role model with the ability of translatable via the spatie/translatable package. this column is not correctly saved. the content of the "description" will be saved as a new "Custom Permission" and added in the permissions table...

It looks to me that there should be an exclude model columns option or something.. or is there another option to this?

eelco2k commented 9 months ago

guest i have to use:

protected function mutateFormDataBeforeSave(array $data): array
    {
        $this->permissions = collect($data)
            ->filter(function ($permission, $key) {
                return !in_array($key, ['name', 'guard_name', 'select_all', 'description']);
            })
            ->values()
            ->flatten();
       return Arr::only($data, ['name', 'guard_name', 'description', config('permission.column_names.team_foreign_key')]);
    }
bezhanSalleh commented 9 months ago

please update the following parts, or republish the resource and apply your changes to avoid any future complications.

//EditRole.php
$this->permissions = collect($data)
            ->filter(function ($permission, $key) {
                return !in_array($key, ['name', 'guard_name', 'select_all', 'description']);
            })
            ->values()
            ->flatten()
            ->unique(); // to include unique()

same for CreateRole.php

$this->permissions = collect($data)
            ->filter(function ($permission, $key) {
                return !in_array($key, ['name', 'guard_name', 'select_all', 'description']);
            })
            ->values()
            ->flatten()
            ->unique(); // to include unique();
eelco2k commented 9 months ago

it is still a problem when i use the extra column "description" with the package: https://github.com/filamentphp/spatie-laravel-translatable-plugin

When you have multiple languages the second (and maybe other extra languages) input gets added as a custom_permissions[]:

Scherm­afbeelding 2024-01-25 om 18 34 24

As you can see there is a custom_permissions array with the title of the dutch value of "description" TextField.

eelco2k commented 9 months ago

okay, i found the issue:

because the Trait Translatable of the Spatie package uses the handleRecordUpdate() method. it calls "$localeData = $this->mutateFormDataBeforeSave($localeData);" again for every translatable field.

this makes $this->permissions go empty in the function mutateFormDataBeforeSave() EditRole.php when called for second/third time/language. so for now i modified it like this:

protected ?bool $firstMutation;

protected function mutateFormDataBeforeSave(array $data, $firstMutation = true): array
    {
        if($firstMutation) {
        $this->permissions = collect($data)
            ->filter(function ($permission, $key) {
                return !in_array($key, ['name', 'guard_name', 'select_all', 'description']);
            })
            ->values()
            ->flatten();
        }
         return Arr::only($data, ['name', 'guard_name', 'description', config('permission.column_names.team_foreign_key')]);
    }

then i copied the handleRecordUpdate() from the Trait,

and changed this line:

$localeData = $this->mutateFormDataBeforeSave($localeData);

to

$localeData = $this->mutateFormDataBeforeSave($localeData, false);

I also had to do this for the CreateRole.php

with the handleRecordCreate() function