diff --git a/src/Cast/CastManager.php b/src/Cast/CastManager.php index d54ef6a..044a862 100644 --- a/src/Cast/CastManager.php +++ b/src/Cast/CastManager.php @@ -170,7 +170,7 @@ public function castToCallback(mixed $cast, int $options, string $direction = 'h if (class_exists($cast)) { // Cast interface if (is_subclass_of($cast, CastInterface::class)) { - return static function (mixed $value, ORM $orm) use ($options, $direction, $cast) { + return static function (mixed $value, ORM $orm) use ($cast, $options, $direction) { return $orm->getAttributesResolver() ->createObject($cast) ->$direction($value); @@ -178,7 +178,7 @@ public function castToCallback(mixed $cast, int $options, string $direction = 'h } // Pure class - return static function (mixed $value, ORM $orm) use ($options, $cast) { + return static function (mixed $value, ORM $orm) use ($cast, $options) { if (is_subclass_of($cast, \BackedEnum::class)) { return $cast::wrap($value); } diff --git a/src/Hydrator/EntityHydrator.php b/src/Hydrator/EntityHydrator.php index 2610dee..342d409 100644 --- a/src/Hydrator/EntityHydrator.php +++ b/src/Hydrator/EntityHydrator.php @@ -219,6 +219,10 @@ public static function castFieldForHydrate( try { $value = $hydrator($value, $metadata->getORM(), $entity); } catch (Throwable $e) { + if ($hydrator instanceof \Closure) { + $hydrator = static::extractCastNameFromClosure($hydrator); + } + $castName = is_object($hydrator) ? $hydrator::class : json_encode($hydrator); throw new CastingException( @@ -260,4 +264,26 @@ public static function castArray(EntityMetadata $metadata, array $data, ?object return $data; } + + /** + * @param \Closure $hydrator + * + * @return mixed + * + * @throws \ReflectionException + */ + protected static function extractCastNameFromClosure(\Closure $hydrator): mixed + { + $ref = new \ReflectionFunction($hydrator); + + if ($caster = $ref->getClosureUsedVariables()['caster'] ?? null) { + $ref = new \ReflectionFunction($caster); + + if ($cast = $ref->getClosureUsedVariables()['cast'] ?? null) { + $hydrator = $cast; + } + } + + return $hydrator; + } }