From 1f02a2ec4fa052d120869b717a7ec3b96f0925ce Mon Sep 17 00:00:00 2001 From: Thibault Buathier Date: Fri, 25 Nov 2022 15:56:51 +0100 Subject: [PATCH] fix: do not cast BackedEnum identifiers --- src/Proxy/ProxyGenerator.php | 8 +- ...LazyLoadableObjectWithPHP81EnumIntType.php | 24 +++ ...bjectWithPHP81EnumIntTypeClassMetadata.php | 157 ++++++++++++++++++ .../Proxy/ProxyLogicIdentifierGetterTest.php | 1 + 4 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntType.php create mode 100644 tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata.php diff --git a/src/Proxy/ProxyGenerator.php b/src/Proxy/ProxyGenerator.php index 8019d418f..f73e8682e 100644 --- a/src/Proxy/ProxyGenerator.php +++ b/src/Proxy/ProxyGenerator.php @@ -940,12 +940,16 @@ 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) ' : ''; + $castToInt = in_array($fieldType, ['integer', 'smallint'], true); $methods .= ' if ($this->__isInitialized__ === false) {' . "\n"; $methods .= ' '; $methods .= $this->shouldProxiedMethodReturn($method) ? 'return ' : ''; - $methods .= $cast . ' parent::' . $method->getName() . "();\n"; + if ($castToInt) { + $methods .= '! parent::' . $method->getName() . '() instanceof \BackedEnum '; + $methods .= '? (int) parent::' . $method->getName() . '() : '; + } + $methods .= 'parent::' . $method->getName() . "();\n"; $methods .= ' }' . "\n\n"; } diff --git a/tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntType.php b/tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntType.php new file mode 100644 index 000000000..99c1bbdd6 --- /dev/null +++ b/tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntType.php @@ -0,0 +1,24 @@ +identifierFieldEnumIntType; + } + + public static function getFooIdentifier(): LazyLoadableObjectWithPHP81EnumIntTypeIdentfier + { + return LazyLoadableObjectWithPHP81EnumIntTypeIdentfier::FOO; + } +} + +enum LazyLoadableObjectWithPHP81EnumIntTypeIdentfier: int +{ + case FOO = 1; + case BAR = 2; +} diff --git a/tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata.php b/tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata.php new file mode 100644 index 000000000..87d5688e7 --- /dev/null +++ b/tests/Common/Proxy/LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata.php @@ -0,0 +1,157 @@ + */ + protected $identifier = [ + 'identifierFieldEnumIntType' => true, + ]; + + /** @var array */ + protected $fields = [ + 'identifierFieldEnumIntType' => true, + ]; + + /** + * {@inheritDoc} + */ + public function getName() + { + return $this->getReflectionClass()->getName(); + } + + /** + * {@inheritDoc} + */ + public function getIdentifier() + { + return array_keys($this->identifier); + } + + /** + * {@inheritDoc} + */ + public function getReflectionClass() + { + if ($this->reflectionClass === null) { + $this->reflectionClass = new ReflectionClass(__NAMESPACE__ . '\LazyLoadableObjectWithPHP81EnumIntType'); + } + + return $this->reflectionClass; + } + + /** + * {@inheritDoc} + */ + public function isIdentifier($fieldName) + { + return isset($this->identifier[$fieldName]); + } + + /** + * {@inheritDoc} + */ + public function hasField($fieldName) + { + return isset($this->fields[$fieldName]); + } + + /** + * {@inheritDoc} + */ + public function hasAssociation($fieldName) + { + return false; + } + + /** + * {@inheritDoc} + */ + public function isSingleValuedAssociation($fieldName) + { + throw new BadMethodCallException('not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isCollectionValuedAssociation($fieldName) + { + throw new BadMethodCallException('not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getFieldNames() + { + return array_keys($this->fields); + } + + /** + * {@inheritDoc} + */ + public function getIdentifierFieldNames() + { + return $this->getIdentifier(); + } + + /** + * {@inheritDoc} + */ + public function getAssociationNames() + { + return []; + } + + /** + * {@inheritDoc} + */ + public function getTypeOfField($fieldName) + { + return 'integer'; + } + + /** + * {@inheritDoc} + */ + public function getAssociationTargetClass($assocName) + { + throw new BadMethodCallException('not implemented'); + } + + /** + * {@inheritDoc} + */ + public function isAssociationInverseSide($assocName) + { + throw new BadMethodCallException('not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getAssociationMappedByTargetField($assocName) + { + throw new BadMethodCallException('not implemented'); + } + + /** + * {@inheritDoc} + */ + public function getIdentifierValues($object) + { + throw new BadMethodCallException('not implemented'); + } +} diff --git a/tests/Common/Proxy/ProxyLogicIdentifierGetterTest.php b/tests/Common/Proxy/ProxyLogicIdentifierGetterTest.php index 40ac68711..80c3b757f 100644 --- a/tests/Common/Proxy/ProxyLogicIdentifierGetterTest.php +++ b/tests/Common/Proxy/ProxyLogicIdentifierGetterTest.php @@ -80,6 +80,7 @@ public function methodsForWhichLazyLoadingShouldBeDisabled() } if (PHP_VERSION_ID >= 80100) { + $data[] = [new LazyLoadableObjectWithPHP81EnumIntTypeClassMetadata(), 'identifierFieldEnumIntType', LazyLoadableObjectWithPHP81EnumIntType::getFooIdentifier()]; $data[] = [new LazyLoadableObjectWithPHP81IntersectionTypeClassMetadata(), 'identifierFieldIntersectionType', new class extends \stdClass implements \Stringable { public function __toString(): string {