whitecube / nova-flexible-content

Flexible Content & Repeater Fields for Laravel Nova
MIT License
790 stars 234 forks source link

Date field must cast to 'date' in Eloquent model #171

Open dmitriytretyakov opened 4 years ago

dmitriytretyakov commented 4 years ago

Hi, i already write issue https://github.com/whitecube/nova-flexible-content/issues/151 and https://github.com/whitecube/nova-flexible-content/issues/14 doesn't help me.

Bug appears only on view page, edit page is fine.

My layout code is:

namespace App\Nova\Flexible\Layouts;

use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Sloveniangooner\SearchableSelect\SearchableSelect;
use Whitecube\NovaFlexibleContent\Layouts\Layout;

class PersonQuote extends Layout
{
    public $casts = [
        'published_at' => 'date'
    ];

    public $dateFormat = 'U';

    /**
     * The layout's unique identifier
     *
     * @var string
     */
    protected $name = 'person_quote';

    /**
     * The displayed title
     *
     * @var string
     */
    protected $title = 'Цитата персоны';

    /**
     * Get the fields displayed by the layout.
     *
     * @return array
     */
    public function fields()
    {
        return [
            SearchableSelect::make("Персона", "person_id")->resource(\App\Nova\Person::class)->displayUsingLabels()->rules('required'),
            Text::make('Название источника', 'source_name')->rules('nullable'),
            Text::make('Ссылка на источник', 'source_url')->rules(['nullable', 'url']),
            Date::make('Дата публикации', 'published_at'),
            Textarea::make('Текст', 'text')->alwaysShow()->rules('required')
        ];
    }
}

What's wrong?

dmitriytretyakov commented 4 years ago

What about fix? Version: dev-master 232b476

ondroftw commented 4 years ago

I have this issue too. Any progress on this ? Tried casts both on layout and model. No luck. Thanks

codechrisz commented 4 years ago

The issue appears only in view page as you say, but I am getting the error message about cast also in deletion and I am not able to delete the entry.

phlisg commented 4 years ago

Confirming the same issue here. Using latest version too

My custom layout:

namespace App\Nova\Flexible\Layouts;

use App\Src\MyCity\FlexibleConstruct;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Text;
use Whitecube\NovaFlexibleContent\Flexible;
use Whitecube\NovaFlexibleContent\Layouts\Layout;

class Schedules extends Layout
{
    /**
     * The layout's unique identifier
     *
     * @var string
     */
    protected $name = 'schedules';

    /**
     * The displayed title
     *
     * @var string
     */
    protected $title = 'Schedules';

    protected $casts = [
        'starts' => 'date',
        'ends' => 'date',
        'every_year' => 'boolean',
        'always_open' => 'boolean',
    ];

    /**
     * The storage format of the model's date columns.
     *
     * @var string
     */
    protected $dateFormat = 'Y-m-d';

    /**
     * Get the fields displayed by the layout.
     *
     * @return array
     * @throws \Exception
     */
    public function fields()
    {
        return [
            Date::make('Du', 'starts')
                ->sortable(),
            Date::make('Au', 'ends')
                ->sortable(),
            Boolean::make('Chaque année', 'every_year')->sortable()
                ->help("L'objet se déroule chaque année au même moment"),

            Flexible::make('Ouvertures', 'openings')
                ->addLayout(Openings::class)
                ->addLayout('Fermetures', 'closures', [
                    Text::make('Du', 'from')
                        ->withMeta([
                            'type' => 'date',
                        ]),

                    Text::make('Au', 'to')
                        ->withMeta([
                            'type' => 'date',
                        ]),
                ])
                ->button('Ajouter des horaires')->hideFromIndex(),
        ];
    }
}
voidgraphics commented 4 years ago

@Nyratas do you think you can make some time for this soon? If it prevents deleting layouts it's a pretty major bug.

XternalSoft commented 4 years ago

Unable to load a resource with datetime error (with custom layout defined).

Problem appear on View (detail) page and DELETE action. No problem on edit

image

vmihaly2020 commented 4 years ago

how to resolve this issue

you have to handle mannualy the conversion of the date fields if you have a filed struckure like this:

Flexible::make(('Blackout'))->addLayout( ('Blackout'), 'blackout', [ Date::make(('Startdate'), 'startdate') ->hideFromIndex() ->sortable(), Date::make(('Enddate'), 'enddate') ->hideFromIndex() ->sortable(), ]) ->button(__('Add blackout'))

you have to define a mutator for this blackout attribute named "getBlackoutAttribute" in your model

public function getBlackoutAttribute($value)
{
    if(\is_string($value)){
        $value =  json_decode($value, true);
        foreach ($value as $key => $oneBlackOut) {
            $this->toCarbon($oneBlackOut, 'attributes.startdate');
            $this->toCarbon($oneBlackOut, 'attributes.enddate');
            $value[$key] = $oneBlackOut;
        }
    }
    return $value;
}

protected function toCarbon(&$srcArr, $key)
{
    $carbonDate = new Carbon(data_get($srcArr, $key));
    data_set($srcArr, $key,   $carbonDate);
}
dmitriytretyakov commented 4 years ago

Doesn't help for me

marianne-fullstack commented 4 years ago

Any progress on this? I'm having the same issue

FabienFrays commented 4 years ago

Thank's vmihaly2020,

I just had to use Laravel Carbon and I did it inside the foreach but that's perfect.

foreach ($value as $key => $dateInflexible) {
  $value[$key]['attributes']['start_at'] = Carbon::createFromFormat("Y-m-d H:i:s", $dateInflexible['attributes']['start_at']);
  $value[$key]['attributes']['end_at'] = Carbon::createFromFormat("Y-m-d H:i:s", $dateInflexible['attributes']['end_at']);
}
Broutard commented 3 years ago

You can use resolveUsing() to override the default Datetime resolver.

DateTime::make('Date')
                        ->format('DD/MM/YYYY HH:mm')
                        ->resolveUsing(function ($value) {
                            return $value;
                        }),
marianne00 commented 3 years ago

@Broutard thanks! that worked for me

jakecausier commented 3 years ago

@Broutard Lifesafer! Should be in the docs.

bhavinzwt commented 3 years ago

Thank you for your solution. It works for me. @Broutard Do you know how to remove the selection of the date from the calendar popup? This means we want only a selection of the month and year in the date picker popup. Screenshot: http://prntscr.com/1r0xi1y

chrisvasey commented 2 years ago

You can use resolveUsing() to override the default Datetime resolver.

DateTime::make('Date')
                        ->format('DD/MM/YYYY HH:mm')
                        ->resolveUsing(function ($value) {
                            return $value;
                        }),

This is the solution. 🎉

HeadStudios commented 2 years ago

Yeh cool but doesn't it say this though? https://share.getcloudapp.com/4gue5K1A - where did the format come from lol. I'll try with just resolveUsing and if it work syou're a genius!

yaroslawww commented 1 year ago

Without format (in case if db contains different formats and you need standartise)

  Date::make('Date', 'date')
                ->resolveUsing(function ($value) {
                    if($value) {
                        try {
                            return Carbon::parse($value);
                        } catch (\Exception $e) {

                        }
                    }
                    return null;
                }),
HeadStudios commented 1 year ago

Without format (in case if db contains different formats and you need standartise)

  Date::make('Date', 'date')
                ->resolveUsing(function ($value) {
                    if($value) {
                        try {
                            return Carbon::parse($value);
                        } catch (\Exception $e) {

                        }
                    }
                    return null;
                }),

Thank you!