diff --git a/src/Metadata/Util/CloneTrait.php b/src/Metadata/Util/CloneTrait.php index 75b903fe9c..b6aa2de42e 100644 --- a/src/Metadata/Util/CloneTrait.php +++ b/src/Metadata/Util/CloneTrait.php @@ -24,14 +24,59 @@ trait CloneTrait { public function clone(mixed $data): mixed { - if (!\is_object($data)) { + if (is_array($data)) { + return $this->cloneArray($data); + } + + if (!is_object($data)) { return $data; } try { - return (new \ReflectionClass($data))->isCloneable() ? clone $data : null; + $reflection = new \ReflectionClass($data); + + if (!$reflection->isCloneable()) { + return null; + } + + $clonedObject = clone $data; + + foreach ($reflection->getProperties() as $property) { + if ($property->isInitialized($data)) { + $value = $property->getValue($data); + + if (is_object($value)) { + $clonedValue = $this->clone($value); + $property->setValue($clonedObject, $clonedValue); + } elseif (is_array($value)) { + $clonedValue = $this->cloneArray($value); + $property->setValue($clonedObject, $clonedValue); + } else { + $property->setValue($clonedObject, $value); + } + } + + // If the property is uninitialized, we skip it to avoid errors + } + + return $clonedObject; } catch (\ReflectionException) { return null; } } + + private function cloneArray(array $array): array + { + $clonedArray = []; + foreach ($array as $key => $value) { + if (is_object($value)) { + $clonedArray[$key] = $this->clone($value); + } elseif (is_array($value)) { + $clonedArray[$key] = $this->cloneArray($value); + } else { + $clonedArray[$key] = $value; + } + } + return $clonedArray; + } }