. */ namespace SP\Domain\Common\Models; use ReflectionClass; use SP\Domain\Common\Adapters\Serde; use SP\Domain\Common\Attributes\Hydratable; /** * Trait SerializedModel */ trait SerializedModel { /** * @inheritDoc */ public function hydrate(string $class): ?object { return $this->parseAttribute( function (Hydratable $hydratable) use ($class) { $valid = array_filter( $hydratable->getTargetClass(), static fn(string $targetClass) => is_a($class, $targetClass, true) ); $property = $this->{$hydratable->getSourceProperty()}; if (count($valid) > 0 && $property !== null) { return Serde::deserialize($property, $class) ?: null; } return null; } ); } private function parseAttribute(callable $callback): mixed { $reflectionClass = new ReflectionClass($this); foreach ($reflectionClass->getAttributes(Hydratable::class) as $attribute) { return $callback($attribute->newInstance()); } return null; } /** * @inheritDoc */ public function dehydrate(object $object): static|null { return $this->parseAttribute( function (Hydratable $hydratable) use ($object) { $valid = array_filter( $hydratable->getTargetClass(), static fn(string $targetClass) => is_a($object, $targetClass) ); if (count($valid) > 0) { return $this->mutate([$hydratable->getSourceProperty() => Serde::serialize($object)]); } return $this; } ); } }