outl1ne / nova-settings

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

datetime value stored as string by nova_set_setting_value() #172

Closed nathan-io closed 9 months ago

nathan-io commented 9 months ago

We have a setting which is cast as a datetime.

When we set the value through Nova, the value is stored in the table as:

2023-10-01T21:14:12.000Z

However, when setting it via nova_set_setting_value(), the result is stored as a string:

nova_set_setting_value('retail_sale_products_last_updated', now())
// "2023-10-01T21:16:26.665577Z"

This causes Nova to throw an exception when viewing the nova-settings page:

Failed to parse time string (\"2023-10-01T21:16:26.665577Z\") at position 0 (\"): Unexpected character at /path/to/project/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php:87)

However, everything works properly if I chain on ->toISOString():

nova_set_setting_value('retail_sale_products_last_updated', now()->toISOString())
// 2023-10-01T21:16:26.665577Z

Here's our NovaServiceProvider:

        NovaSettings::addSettingsFields([
            Panel::make('Products', [
                DateTime::make('Products Last Updated', 'retail_sale_products_last_updated'),
            ]),
        ], [
            'retail_sale_products_last_updated' => 'datetime',
        ], 'Retail Sales');

I also found it strange that this format appears to be ISO string (rather than ISO-8601), because Laravel docs say:

By default, the date and datetime casts will serialize dates to a UTC ISO-8601 date string (YYYY-MM-DDTHH:MM:SS.uuuuuuZ), regardless of the timezone specified in your application's timezone configuration option.

Yet that example given looks like ISO, not ISO-8601:

> now()->toISOString()
= "2023-10-01T21:36:32.573048Z"

> now()->toISO8601String()
= "2023-10-01T21:36:38+00:00"
marttinnotta commented 9 months ago

Hi and thank you for bringing this issue out!

We are now using casts defined when calling addSettingsFields and instead of json serializing it we will let Nova do the logic. Now when you call nova_set_setting_value('retail_sale_products_last_updated', now()) it should work as expected.

Fix is in new 5.2.2 release.

Good luck!