Skip to content

Commit 783a000

Browse files
[10.x] Allow object caching to be disabled for custom class casters (#47423)
* Allow caching to be disabled for class casters * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 42173c8 commit 783a000

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -803,16 +803,20 @@ protected function castAttribute($key, $value)
803803
*/
804804
protected function getClassCastableAttributeValue($key, $value)
805805
{
806-
if (isset($this->classCastCache[$key])) {
806+
$caster = $this->resolveCasterClass($key);
807+
808+
$objectCachingDisabled = $caster->withoutObjectCaching ?? false;
809+
810+
if (isset($this->classCastCache[$key]) && ! $objectCachingDisabled) {
807811
return $this->classCastCache[$key];
808812
} else {
809-
$caster = $this->resolveCasterClass($key);
810-
811813
$value = $caster instanceof CastsInboundAttributes
812814
? $value
813815
: $caster->get($this, $key, $value, $this->attributes);
814816

815-
if ($caster instanceof CastsInboundAttributes || ! is_object($value)) {
817+
if ($caster instanceof CastsInboundAttributes ||
818+
! is_object($value) ||
819+
$objectCachingDisabled) {
816820
unset($this->classCastCache[$key]);
817821
} else {
818822
$this->classCastCache[$key] = $value;
@@ -1134,7 +1138,9 @@ protected function setClassCastableAttribute($key, $value)
11341138
))
11351139
);
11361140

1137-
if ($caster instanceof CastsInboundAttributes || ! is_object($value)) {
1141+
if ($caster instanceof CastsInboundAttributes ||
1142+
! is_object($value) ||
1143+
($caster->withoutObjectCaching ?? false)) {
11381144
unset($this->classCastCache[$key]);
11391145
} else {
11401146
$this->classCastCache[$key] = $value;

tests/Integration/Database/DatabaseEloquentModelCustomCastingTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ public function testBasicCustomCasting()
103103
$model = new TestEloquentModelWithCustomCast;
104104
$model->birthday_at = now();
105105
$this->assertIsString($model->toArray()['birthday_at']);
106+
107+
$model = new TestEloquentModelWithCustomCast;
108+
$now = now()->toImmutable();
109+
$model->anniversary_on_with_object_caching = $now;
110+
$model->anniversary_on_without_object_caching = $now;
111+
$this->assertSame($now, $model->anniversary_on_with_object_caching);
112+
$this->assertSame('UTC', $model->anniversary_on_with_object_caching->format('e'));
113+
$this->assertNotSame($now, $model->anniversary_on_without_object_caching);
114+
$this->assertNotSame('UTC', $model->anniversary_on_without_object_caching->format('e'));
106115
}
107116

108117
public function testGetOriginalWithCastValueObjects()
@@ -299,6 +308,8 @@ class TestEloquentModelWithCustomCast extends Model
299308
'value_object_caster_with_caster_instance' => ValueObjectWithCasterInstance::class,
300309
'undefined_cast_column' => UndefinedCast::class,
301310
'birthday_at' => DateObjectCaster::class,
311+
'anniversary_on_with_object_caching' => DateTimezoneCasterWithObjectCaching::class.':America/New_York',
312+
'anniversary_on_without_object_caching' => DateTimezoneCasterWithoutObjectCaching::class.':America/New_York',
302313
];
303314
}
304315

@@ -584,3 +595,25 @@ public function set($model, $key, $value, $attributes)
584595
return $value->format('Y-m-d');
585596
}
586597
}
598+
599+
class DateTimezoneCasterWithObjectCaching implements CastsAttributes
600+
{
601+
public function __construct(private string $timezone = 'UTC')
602+
{
603+
}
604+
605+
public function get($model, $key, $value, $attributes)
606+
{
607+
return Carbon::parse($value, $this->timezone);
608+
}
609+
610+
public function set($model, $key, $value, $attributes)
611+
{
612+
return $value->timezone($this->timezone)->format('Y-m-d');
613+
}
614+
}
615+
616+
class DateTimezoneCasterWithoutObjectCaching extends DateTimezoneCasterWithObjectCaching
617+
{
618+
public bool $withoutObjectCaching = true;
619+
}

0 commit comments

Comments
 (0)