outl1ne / nova-settings

A Laravel Nova tool for editing custom settings using native Nova fields.
MIT License
273 stars 97 forks source link

Getting the setting manually ignores casting #55

Closed rickgoemans closed 2 years ago

rickgoemans commented 3 years ago

Wouldn't it be nice if the nova_get_setting('...') method also used the cast if it is used?

In my case we use it to ensure the customer can populate Nova Select fields with only given values. As casting we use array but when we use nova_get_setting('...') we get a json encoded string as return.

Now we have to manually do the json_decode(nova_get_setting('...'), true) part on every setting. Of course we made a helper function getArraySetting(string $key) which does this but it think the nova_get_setting method should get a 2nd parameter bool $useCasting = true which enables the casting part.

I wonder if other people think the same about this and how hard it is to ensure this works but seeing it already stores the casts as a property in NovaSettings, this seems easily achievable.

rickgoemans commented 3 years ago

A little note on this issue, it does cast when you're within a Nova page, but when you're not (for example in Laravel tinker), it just retrieves the value from the database.

EDIT: typos

Tarpsvo commented 3 years ago

That's really weird, it should always cast it. It doesn't matter whether you're in console or not. I also ran a simple test:

Field:

NovaSettings::addSettingsFields(function () {
    return [
        Multiselect::make('Array field', 'array_field')
            ->options([1 => 'Option one', 2 => 'Option two', 3 => 'Option three', 4 => 'Option four']),
    ];
}, [
    'array_field' => 'array',
], 'test');

Results in php artisan tinker.

a) without 'array_field' => 'array':

>>> nova_get_setting('array_field')
=> "["1","3","4"]"

b) with 'array_field' => 'array':

>>> nova_get_setting('array_field')
=> [
     "1",
     "3",
     "4",
   ]

So, unfortunately I was unable to reproduce your issue. Can you give me any more details or try to debug the issue a bit yourself? All the casting should happen in the getValueAttribute of the Settings model.

alexrififi commented 3 years ago

I think @rickgoemans got this situation because he took the value of the settings earlier than he determined the cast

rickgoemans commented 3 years ago

I have the following in my app\Providers\NovaServiceProvider.php:

public function boot()
{
    parent::boot();
    //...
    $this->createSettingsFields();
}

protected function createSettingsFields(): void
{
    NovaSettings::addSettingsFields([
        KeyValue::make(__('Original manufacturer'), 'elevator_original_manufacturer'),
    ], [
        'elevator_original_manufacturer' => 'array',
    ], __('Elevator'));
}

But when I do this in tinker:

$settingKey = 'elevator_original_manufacturer';
$setting = nova_get_setting($settingKey, []);
dump(gettype($setting));

I get "string" as output, while the cast should make it output "array". I've also tried moving the NovaServiceProvider boot's content to the AppServiceProvider's boot method but that didnt't solve it either.

Tarpsvo commented 3 years ago

That's really weird. I tried your exact example and can't replicate it still. Are you sure you're using the latest version?

image

chrillep commented 1 year ago

having the same issue casts are not being applied

chrillep commented 1 year ago

could be middleware ?

Tarpsvo commented 1 year ago

It might be that you're reading the setting before the casts are applied (ie before any ServiceProviders?).