From 05ef1f4f967b6f6c5fa299853f0f17051c43dfdd Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 14 Dec 2023 15:21:32 -0500 Subject: [PATCH] Fixed enum mapping validation --- lib/Doctrine/ORM/Tools/SchemaValidator.php | 41 +++++++++++++++++-- .../Ticket/GH11037/EntityStatus.php | 9 ++++ .../Functional/Ticket/GH11037/GH11037Test.php | 3 +- .../GH11037/InvalidEntityWithTypedEnum.php | 5 +++ .../Ticket/GH11037/StringEntityStatus.php | 2 +- .../GH11037/ValidEntityWithTypedEnum.php | 5 +++ 6 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index fbaf33bd01d..c82e8da638a 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -39,6 +39,7 @@ use function get_class; use function implode; use function in_array; +use function interface_exists; use function is_a; use function sprintf; @@ -389,10 +390,20 @@ function (array $fieldMapping) use ($class): ?string { return null; } - if ( - is_a($propertyType, BackedEnum::class, true) - && $metadataFieldType === (string) (new ReflectionEnum($propertyType))->getBackingType() - ) { + if (is_a($propertyType, BackedEnum::class, true)) { + $backingType = (string) (new ReflectionEnum($propertyType))->getBackingType(); + + if ($metadataFieldType !== $backingType) { + return sprintf( + "The field '%s#%s' has the property type '%s' with a backing type of '%s' that differs from the metadata field type '%s'.", + $class->name, + $fieldName, + $propertyType, + $backingType, + $metadataFieldType + ); + } + if (! isset($fieldMapping['enumType']) || $propertyType === $fieldMapping['enumType']) { return null; } @@ -406,6 +417,28 @@ function (array $fieldMapping) use ($class): ?string { ); } + if ( + isset($fieldMapping['enumType']) + && $propertyType !== $fieldMapping['enumType'] + && interface_exists($propertyType) + && is_a($fieldMapping['enumType'], $propertyType, true) + ) { + $backingType = (string) (new ReflectionEnum($fieldMapping['enumType']))->getBackingType(); + + if ($metadataFieldType === $backingType) { + return null; + } + + return sprintf( + "The field '%s#%s' has the metadata enumType '%s' with a backing type of '%s' that differs from the metadata field type '%s'.", + $class->name, + $fieldName, + $fieldMapping['enumType'], + $backingType, + $metadataFieldType + ); + } + if ( $fieldMapping['type'] === 'json' && in_array($propertyType, ['string', 'int', 'float', 'bool', 'true', 'false', 'null'], true) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php new file mode 100644 index 00000000000..f94c44affe0 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php @@ -0,0 +1,9 @@ +