Skip to content

Commit

Permalink
Fixed enum mapping validation
Browse files Browse the repository at this point in the history
  • Loading branch information
yceruto committed Dec 14, 2023
1 parent 2b91edc commit 05ef1f4
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 6 deletions.
41 changes: 37 additions & 4 deletions lib/Doctrine/ORM/Tools/SchemaValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket\GH11037;

interface EntityStatus
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ public function testMetadataFieldTypeNotCoherentWithEntityPropertyType(): void

self::assertEquals(
[
"The field 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\InvalidEntityWithTypedEnum#status1' has the property type 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\StringEntityStatus' that differs from the metadata field type 'int' returned by the 'integer' DBAL type.",
"The field 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\InvalidEntityWithTypedEnum#status1' has the property type 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\StringEntityStatus' with a backing type of 'string' that differs from the metadata field type 'int'.",
"The field 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\InvalidEntityWithTypedEnum#status2' has the property type 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\IntEntityStatus' that differs from the metadata enumType 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\StringEntityStatus'.",
"The field 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\InvalidEntityWithTypedEnum#status3' has the metadata enumType 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\StringEntityStatus' with a backing type of 'string' that differs from the metadata field type 'int'.",
],
$ce
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ class InvalidEntityWithTypedEnum
* @Column(type="integer", enumType=StringEntityStatus::class)
*/
protected IntEntityStatus $status2;

/**
* @Column(type="integer", enumType=StringEntityStatus::class)
*/
protected EntityStatus $status3;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Doctrine\Tests\ORM\Functional\Ticket\GH11037;

enum StringEntityStatus: string
enum StringEntityStatus: string implements EntityStatus
{
case ACTIVE = 'active';
case INACTIVE = 'inactive';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ class ValidEntityWithTypedEnum
* @Column(type="smallint", enumType=IntEntityStatus::class)
*/
protected IntEntityStatus $status2;

/**
* @Column(type="string", enumType=StringEntityStatus::class)
*/
protected EntityStatus $status3;
}

0 comments on commit 05ef1f4

Please sign in to comment.