diff --git a/src/Mpociot/Versionable/Version.php b/src/Mpociot/Versionable/Version.php index d145eb1..5509547 100644 --- a/src/Mpociot/Versionable/Version.php +++ b/src/Mpociot/Versionable/Version.php @@ -89,7 +89,7 @@ public function diff(Version $againstVersion = null) $model = $this->getModel(); $diff = $againstVersion ? $againstVersion->getModel() : $this->versionable()->withTrashed()->first()->currentVersion()->getModel(); - $diffArray = array_diff_assoc($diff->getAttributes(), $model->getAttributes()); + $diffArray = $this->arrayDiffAssocRecursive($diff->getAttributes(), $model->getAttributes()); if (isset( $diffArray[ $model->getCreatedAtColumn() ] )) { unset( $diffArray[ $model->getCreatedAtColumn() ] ); @@ -104,4 +104,33 @@ public function diff(Version $againstVersion = null) return $diffArray; } + /** + * Recursive version of array_diff_assoc. + * + * @param $array1 + * @param $array2 + * + * @return array + */ + public function arrayDiffAssocRecursive($array1, $array2) + { + $difference = []; + + foreach ($array1 as $key => $value) { + if (is_array($value)) { + if (isset($array2[$key])) { + $new_diff = $this->arrayDiffAssocRecursive($value, $array2[$key]); + if (! empty($new_diff)) { + $difference[$key] = $new_diff; + } + } else { + $difference[$key] = $value; + } + } elseif (! in_array($value, $array2, true)) { + $difference[$key] = $value; + } + } + + return $difference; + } } diff --git a/src/Mpociot/Versionable/VersionableTrait.php b/src/Mpociot/Versionable/VersionableTrait.php index 9be633a..9235ed3 100644 --- a/src/Mpociot/Versionable/VersionableTrait.php +++ b/src/Mpociot/Versionable/VersionableTrait.php @@ -176,7 +176,7 @@ protected function versionablePostSave() $versionedHiddenFields = $this->versionedHiddenFields ?? []; $this->makeVisible($versionedHiddenFields); - $version->model_data = serialize($this->attributesToArray()); + $version->model_data = serialize($this->attributesToVersion()); $this->makeHidden($versionedHiddenFields); if (!empty( $this->reason )) { @@ -189,6 +189,19 @@ protected function versionablePostSave() } } + /** + * Wrapper for getting attributes to version, respecting $dontVersionFields. + * + * @return array + */ + protected function attributesToVersion() + { + $attributes = $this->attributesToArray(); + $ignore = $this->dontVersionFields ?? []; + + return collect($attributes)->except($ignore)->all(); + } + /** * Delete old versions of this model when the reach a specific count. *