From 5b54ff399cd5e2018c5936585663d8f7fe8984c5 Mon Sep 17 00:00:00 2001 From: Thibault Buathier Date: Fri, 14 Oct 2022 11:02:13 +0200 Subject: [PATCH] fix: proxy with BackedEnum integer on identifier --- src/Proxy/ProxyGenerator.php | 8 +++++++- src/Util/ClassUtils.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Proxy/ProxyGenerator.php b/src/Proxy/ProxyGenerator.php index 8019d418f..1348cc0fe 100644 --- a/src/Proxy/ProxyGenerator.php +++ b/src/Proxy/ProxyGenerator.php @@ -27,6 +27,7 @@ use function chmod; use function class_exists; use function dirname; +use function enum_exists; use function explode; use function file; use function file_put_contents; @@ -940,7 +941,12 @@ private function generateMethods(ClassMetadata $class) if ($this->isShortIdentifierGetter($method, $class)) { $identifier = lcfirst(substr($name, 3)); $fieldType = $class->getTypeOfField($identifier); - $cast = in_array($fieldType, ['integer', 'smallint'], true) ? '(int) ' : ''; + + if (ClassUtils::containsEnumType($method->getReturnType())) { + $cast = ''; + } else { + $cast = in_array($fieldType, ['integer', 'smallint'], true) ? '(int) ' : ''; + } $methods .= ' if ($this->__isInitialized__ === false) {' . "\n"; $methods .= ' '; diff --git a/src/Util/ClassUtils.php b/src/Util/ClassUtils.php index cc8c6013a..5e07bff84 100644 --- a/src/Util/ClassUtils.php +++ b/src/Util/ClassUtils.php @@ -4,7 +4,12 @@ use Doctrine\Persistence\Proxy; use ReflectionClass; +use ReflectionIntersectionType; +use ReflectionNamedType; +use ReflectionUnionType; +use function assert; +use function enum_exists; use function get_class; use function get_parent_class; use function ltrim; @@ -12,6 +17,8 @@ use function strrpos; use function substr; +use const PHP_VERSION_ID; + /** * Class and reflection related functionality for objects that * might or not be proxy objects at the moment. @@ -110,4 +117,31 @@ public static function generateProxyClassName($className, $proxyNamespace) { return rtrim($proxyNamespace, '\\') . '\\' . Proxy::MARKER . '\\' . ltrim($className, '\\'); } + + /** + * Check if the type is an enum type or type containing an enum type + * + * @param ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $type + * + */ + public static function containsEnumType($type): bool + { + if (PHP_VERSION_ID <= 80100 || $type === null) { + return false; + } + + if ($type instanceof ReflectionUnionType || $type instanceof ReflectionIntersectionType) { + foreach ($type->getTypes() as $unionedType) { + if (self::containsEnumType($unionedType)) { + return true; + } + } + + return false; + } + + assert($type instanceof ReflectionNamedType); + + return enum_exists($type->getName()); + } }