diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php index d4f86c52c2be..c7f0bde33920 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php @@ -2071,8 +2071,7 @@ public function originalIsEquivalent($key) return $this->fromDateTime($attribute) === $this->fromDateTime($original); } elseif ($this->hasCast($key, ['object', 'collection'])) { - return $this->fromJson($attribute) === - $this->fromJson($original); + return $this->jsonIsEquivalent($attribute, $original); } elseif ($this->hasCast($key, ['real', 'float', 'double'])) { if ($original === null) { return false; @@ -2083,11 +2082,13 @@ public function originalIsEquivalent($key) return $this->castAttribute($key, $attribute) === $this->castAttribute($key, $original); } elseif ($this->isClassCastable($key) && Str::startsWith($this->getCasts()[$key], [AsArrayObject::class, AsCollection::class])) { - return $this->fromJson($attribute) === $this->fromJson($original); + return $this->jsonIsEquivalent($attribute, $original); } elseif ($this->isClassCastable($key) && Str::startsWith($this->getCasts()[$key], [AsEnumArrayObject::class, AsEnumCollection::class])) { - return $this->fromJson($attribute) === $this->fromJson($original); + return $this->jsonIsEquivalent($attribute, $original); } elseif ($this->isClassCastable($key) && $original !== null && Str::startsWith($this->getCasts()[$key], [AsEncryptedArrayObject::class, AsEncryptedCollection::class])) { return $this->fromEncryptedString($attribute) === $this->fromEncryptedString($original); + } elseif ($this->isClassCastable($key) && $this->resolveCasterClass($key) instanceof Json) { + return $this->jsonIsEquivalent($attribute, $original); } return is_numeric($attribute) && is_numeric($original) @@ -2254,4 +2255,19 @@ protected static function getAttributeMarkedMutatorMethods($class) return false; })->map->name->values()->all(); } + + /** + * Checks whether two Json strings are the same and, if not, + * whether the data decoded into an associative array is the same + * without taking the order or types of the elements into account. + * + * @param mixed $attribute + * @param mixed $original + * @return bool + */ + public function jsonIsEquivalent($attribute, $original) + { + return $original == $attribute + ?: json_decode($attribute, true) == json_decode($original, true); + } }