orchidsoftware / orchidsoftware/platform

DateTimer with custom format throws an exception

Open
#2,544 1 comment 0 reactions 1 assignee View on GitHub

@tabuna is already working on this.

Since Feb 23, 2023.

Errors
Dominant language
PHP
Stars
4.8k
Forks
662
Avg merge
1d 9h
Merged PRs (30d)
7

Description

Describe the bug
DateTimer with custom format throws exception if any other field is filled incorrect.

To Reproduce

  1. Create form layout with DateTimer (lets say for date of birth - DOB) and at least one more other type field, for example simple Input for email.
  2. Set format and serverFormat on the DateTimer, for example "d/m/Y"
  3. Create validation rules - for DateTimer: "date_format:d/m/Y", for the other Input field - for example "unique:users,email"
  4. Fill the form with any date in the DateTimer and email, which is already taken by another user.
  5. After submit it throws an InvalidFormatException:
    Could not parse '22/03/2023': Failed to parse time string (22/03/2023) at position 0 (2): Unexpected character
  6. If the email validation is OK - there is no InvalidFormatException and everything is working fine.

Layout:

class UserEditLayout extends Rows
{
    public function fields(): array
    {
        return [
            Input::make('user.email')
                ->type('email')
                ->title(__('Email Address')),

            DateTimer::make('user.dob')
                ->title('Date of Birth')
                ->allowInput()
                ->serverFormat(config('app.date_format')) // Set to d/m/Y
                ->format(config('app.date_format')) // Set to d/m/Y
                ->help(__('Format DD/MM/YYYY')),
        ];
    }
}

Screen save method:

public function save(User $user, UserRequest $request)
{
    $request->validate($request->rules());
    $user->when($request->filled('user.password'), function (Builder $builder) use ($request) {
        $builder->getModel()->password = Hash::make($request->input('user.password'));
    });
    
    $user
        ->fill(collect($request->validated('user'))->except('password')->all())
        ->save();

    Toast::info(__('User saved'));
}

UserRequest class:

class UserRequest extends FormRequest
{
    public function rules()
    {
        $ignoreId = $this->route('user') ? ',' . $this->route('user')->id : '';

        return [
            'user.email' => 'email|nullable|unique:users,email' . $ignoreId,
            'user.dob' => 'date_format:' . config('app.date_format') . '|nullable', // Set to d/m/Y
        ];
    }

    public function validated($key = null, $default = null)
    {
        $validated = data_get($this->validator->validated(), $key, $default);
        $merged = collect($validated);

        if ($merged->get('dob')) {
            $merged->put('dob', Carbon::createFromFormat(config('app.date_format'), $merged->get('dob'))->format('Y-m-d'));
        }

        return $merged->all();
    }
}

Expected behavior
Correct parsing the date

Server (please complete the following information):

  • Platfrom Version: 13.8.0
  • Laravel Version: 9.42.
  • PHP Version: 8.1.9
  • Database: MySql
  • Database Version: 8.0.30

Additional context
The date_of_birth fields in the database has type date
I tried to play with prepareForValidation() and failedValidation() methods in the UserRequest class, but it still throws an exception.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.