Skip to content

Commit 279f13f

Browse files
authored
Merge pull request #4 from whitecube/fix-model-serialize
Fixed models serialization
2 parents e8d6336 + 1a3775b commit 279f13f

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

src/Casts/TimezonedDatetime.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
use Illuminate\Support\Facades\Date;
66
use Whitecube\LaravelTimezones\Facades\Timezone;
77
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
8+
use Carbon\Carbon;
9+
use Illuminate\Support\Facades\Config;
10+
use Illuminate\Database\Eloquent\Model;
811

912
class TimezonedDatetime implements CastsAttributes
1013
{
@@ -40,6 +43,10 @@ public function get($model, $key, $value, $attributes)
4043
if(!$value && $value !== 0) {
4144
return null;
4245
}
46+
47+
if ($this->isTimestamp($model, $key)) {
48+
$value = Carbon::parse($value)->format($this->format ?? $model->getDateFormat());
49+
}
4350

4451
$original = Timezone::store($value, fn($raw, $tz) => $this->asDateTime($raw, $tz, $model));
4552

@@ -61,10 +68,25 @@ public function set($model, $key, $value, $attributes)
6168
return null;
6269
}
6370

71+
if ($this->isTimestamp($model, $key) && is_string($value)) {
72+
$value = Carbon::parse($value, Config::get('app.timezone'));
73+
}
74+
6475
$requested = Timezone::date($value, fn($raw, $tz) => $this->asDateTime($raw, $tz, $model));
6576

6677
return Timezone::store($requested)->format($this->format ?? $model->getDateFormat());
6778
}
79+
80+
/**
81+
* Check if the given key is part of the model's known timestamps
82+
* @param Model $model
83+
* @param string $key
84+
* @return bool
85+
*/
86+
protected function isTimestamp(Model $model, string $key): bool
87+
{
88+
return $model->usesTimestamps() && in_array($key, $model->getDates());
89+
}
6890

6991
/**
7092
* Create a new date value from raw material
@@ -82,4 +104,4 @@ public function asDateTime($value, $timezone, $model)
82104
$timezone,
83105
);
84106
}
85-
}
107+
}

tests/CastTest.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use Carbon\Carbon;
4+
use Illuminate\Support\Facades\Config;
35
use Whitecube\LaravelTimezones\Casts\TimezonedDatetime;
46

57
it('can access UTC database date with application timezone', function() {
@@ -138,4 +140,24 @@
138140

139141
$output = $cast->get(fakeModel(), 'id', $input, []);
140142
expect($output->format('H'))->toEqual(4);
141-
});
143+
});
144+
145+
test('a model with a timezone date cast can be json serialized', function () {
146+
setupFacade();
147+
148+
Config::shouldReceive('get')
149+
->with('app.timezone')
150+
->andReturn('UTC');
151+
152+
$date = new Carbon('2022-12-15 09:00:00', 'UTC');
153+
$model = fakeModelWithCast();
154+
155+
$model->test_at = $date;
156+
$model->updated_at = $date;
157+
158+
expect($model->jsonSerialize())
159+
->toBe([
160+
'test_at' => $date->toJSON(),
161+
'updated_at' => $date->toJSON()
162+
]);
163+
});

tests/Pest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use Whitecube\LaravelTimezones\Timezone;
44
use Whitecube\LaravelTimezones\Facades\Timezone as Facade;
55
use Illuminate\Database\Eloquent\Model;
6+
use Whitecube\LaravelTimezones\Casts\TimezonedDatetime;
67

78
/*
89
|--------------------------------------------------------------------------
@@ -60,3 +61,19 @@ public function getDateFormat()
6061
}
6162
};
6263
}
64+
65+
function fakeModelWithCast()
66+
{
67+
return new class() extends Model {
68+
protected $casts = [
69+
'test_at' => TimezonedDatetime::class,
70+
'created_at' => TimezonedDatetime::class,
71+
'updated_at' => TimezonedDatetime::class,
72+
];
73+
74+
public function getDateFormat()
75+
{
76+
return 'Y-m-d H:i:s';
77+
}
78+
};
79+
}

0 commit comments

Comments
 (0)