diff --git a/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php b/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php index db9a21b461ba..b039fb29cfd6 100644 --- a/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php +++ b/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php @@ -19,7 +19,7 @@ public static function castUsing(array $arguments) { public function get($model, $key, $value, $attributes) { - return isset($attributes[$key]) ? new ArrayObject(json_decode($attributes[$key], true)) : null; + return $value ? new ArrayObject(json_decode($value, true)) : null; } public function set($model, $key, $value, $attributes) diff --git a/src/Illuminate/Database/Eloquent/Casts/AsCollection.php b/src/Illuminate/Database/Eloquent/Casts/AsCollection.php index 585b6cfc7012..7c989c1eb9a2 100644 --- a/src/Illuminate/Database/Eloquent/Casts/AsCollection.php +++ b/src/Illuminate/Database/Eloquent/Casts/AsCollection.php @@ -20,7 +20,7 @@ public static function castUsing(array $arguments) { public function get($model, $key, $value, $attributes) { - return isset($attributes[$key]) ? new Collection(json_decode($attributes[$key], true)) : null; + return $value ? new Collection(json_decode($value, true)) : null; } public function set($model, $key, $value, $attributes) diff --git a/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php index 5918bc1b2203..c54b678d6f3f 100644 --- a/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php +++ b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php @@ -20,7 +20,7 @@ public static function castUsing(array $arguments) { public function get($model, $key, $value, $attributes) { - return new ArrayObject(json_decode(Crypt::decryptString($attributes[$key]), true)); + return new ArrayObject(json_decode(Crypt::decryptString($value), true)); } public function set($model, $key, $value, $attributes) diff --git a/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php index ad11b1787b38..bd61d7557a2b 100644 --- a/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php +++ b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php @@ -21,7 +21,7 @@ public static function castUsing(array $arguments) { public function get($model, $key, $value, $attributes) { - return new Collection(json_decode(Crypt::decryptString($attributes[$key]), true)); + return new Collection(json_decode(Crypt::decryptString($value), true)); } public function set($model, $key, $value, $attributes) diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php index 1e57c91004d8..b125baed4e46 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php @@ -1658,6 +1658,17 @@ public function originalIsEquivalent($key) } elseif ($this->hasCast($key, static::$primitiveCastTypes)) { return $this->castAttribute($key, $attribute) === $this->castAttribute($key, $original); + } elseif ($this->isClassCastable($key)) { + $caster = $this->resolveCasterClass($key); + + $original = $this->normalizeCastClassResponse($key, $caster->set( + $this, + $key, + $caster instanceof CastsInboundAttributes ? $original : $caster->get($this, $key, $original, $this->attributes), + $this->attributes + )); + + return $attribute === $original[$key]; } return is_numeric($attribute) && is_numeric($original) diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index a36bba4fe3eb..f5acc6a0673c 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -2,6 +2,7 @@ namespace Illuminate\Tests\Database; +use ArrayObject; use DateTime; use DateTimeImmutable; use DateTimeInterface; @@ -13,6 +14,7 @@ use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\ConnectionResolverInterface as Resolver; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Casts\AsArrayObject; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\JsonEncodingException; use Illuminate\Database\Eloquent\MassAssignmentException; @@ -155,6 +157,24 @@ public function testDirtyOnCastedObjects() $this->assertFalse($model->isDirty('collectionAttribute')); } + public function testDirtyOnCastedArrayObject() + { + $model = new EloquentModelCastingStub; + $model->setRawAttributes([ + 'arrayobjectAttribute' => '{"foo": "bar"}', + ]); + $model->syncOriginal(); + + $this->assertInstanceOf(ArrayObject::class, $model->arrayobjectAttribute); + $this->assertFalse($model->isDirty('arrayobjectAttribute')); + + $model->arrayobjectAttribute = ['foo' => 'bar']; + $this->assertFalse($model->isDirty('arrayobjectAttribute')); + + $model->arrayobjectAttribute = ['foo' => 'baz']; + $this->assertTrue($model->isDirty('arrayobjectAttribute')); + } + public function testCleanAttributes() { $model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]); @@ -2570,6 +2590,7 @@ class EloquentModelCastingStub extends Model 'dateAttribute' => 'date', 'datetimeAttribute' => 'datetime', 'timestampAttribute' => 'timestamp', + 'arrayobjectAttribute' => AsArrayObject::class, ]; public function jsonAttributeValue()