Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False update value from date picker in repeaters #745

Closed
galingong opened this issue Oct 6, 2020 · 4 comments
Closed

False update value from date picker in repeaters #745

galingong opened this issue Oct 6, 2020 · 4 comments
Labels
impact: low a minor issue for some people type: bug Something isn't working

Comments

@galingong
Copy link
Contributor

Date picker would save different values than displayed when used in repeaters outside the block editor (i.e. one-to-many).

For the bug the be present, all of these 3 things has to be true: Timezone is not UTC, child model has $dates attribute set, date field is in a repeater.

Steps to reproduce:

  1. Set up two modules, a parent and a child. The child should have a foreignId column (parent_id) and a datetime column (test_date)
  2. Set a one-to-many relationship on the models. Set "automated repeaters" on the parent repository (public $repeaters = ['children']), create a repeater blade for the children (it should have a date_picker field for test_date), and add a repeater formField type children to the parent.
  3. On the child model protected $dates = ['test_date']; should be set. Timezone in config app.timezone has to be something different than UTC (e.g. Europe/Paris).
  4. Create a parent record and add a child record to the repeater. Set any date with the date picker. Save the record.
  5. Refresh the browser. Save the parent record again, without touching the date picker.
  6. Refresh the browser again. Date will be updated to an unwanted value.

Here's a screencast displaying the issue: https://drive.google.com/file/d/1YwfAL2ZcXq8Q2Taf7lcTg-8YX2cKCZL7/view?usp=sharing

@ptrckvzn ptrckvzn added the type: bug Something isn't working label Apr 28, 2021
@IllyaMoskvin
Copy link
Contributor

IllyaMoskvin commented Nov 19, 2021

Confirming that we are also running into this issue. We are storing test_date in a timestamp column. Each time we refresh the browser and save, we see test_date increment by the UTC offset of the current timezone.

We are working around it using mutators, e.g. like this:

<?php

namespace App\Helpers;

use Carbon\Carbon;

class DateHelpers
{
    public static function stripTime($value)
    {
        if (!$value) {
            return;
        }

        if (!is_string($value)) {
            return;
        }

        return (new Carbon($value))
            ->setTime(0, 0, 0)
            ->toDateTimeString();
    }
}
<?php

namespace App\Models;

use App\Helpers\DateHelpers;

class DateRule
{
    protected $dates = ['test_date'];

    public function setTestDateAttribute($value)
    {
        $this->attributes['test_date'] = DateHelpers::stripTime($value);
    }

    public function getTestDateAttribute()
    {
        return DateHelpers::stripTime($this->attributes['test_date']);
    }
}

@pboivin
Copy link
Contributor

pboivin commented Nov 22, 2021

Hi @galingong and @IllyaMoskvin, thanks for reporting this issue. I started investigating this today and was able to reproduce it following the steps described.

If I understand correctly, using protected $dates = ['test_date'] stores the date without timezone information in the DB, and seems to convert the value to UTC when the model is instantiated.

Interestingly, using protected $cast = ['test_date' => 'date'] instead doesn't cause this issue. The value is not converted to UTC.

I'm not really sure but I think the bug is caused by DatePicker.vue, which uses Flatpikr under the hood. As far as I can tell, Flatpikr doesn't accept a timezone parameter, it follows the Browser's configuration. This issue may be caused by the multiple conversions happening (DB -> UTC -> Browser, then back).

Let me know if this makes any sense. I'll keep testing :)

@pboivin
Copy link
Contributor

pboivin commented Nov 23, 2021

Small update on casting.

The following two are equivalent (they cause the issue described with a datetime column) :

protected $dates = ['test_date'];

protected $casts = ['test_date' => 'datetime'];

And this saves the selected time to the DB column but will reset it to 00:00:00 automatically on the Carbon instance :

protected $casts = ['test_date' => 'date'];

@ifox ifox added the impact: low a minor issue for some people label Feb 6, 2022
@haringsrob
Copy link
Contributor

This should be resolved in 3.x with: #1724

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
impact: low a minor issue for some people type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants