|
4 | 4 |
|
5 | 5 | namespace Doctrine\ORM\Mapping; |
6 | 6 |
|
| 7 | +use BackedEnum; |
7 | 8 | use BadMethodCallException; |
8 | 9 | use DateInterval; |
9 | 10 | use DateTime; |
|
22 | 23 | use InvalidArgumentException; |
23 | 24 | use LogicException; |
24 | 25 | use ReflectionClass; |
| 26 | +use ReflectionEnum; |
25 | 27 | use ReflectionNamedType; |
26 | 28 | use ReflectionProperty; |
27 | 29 | use RuntimeException; |
|
37 | 39 | use function assert; |
38 | 40 | use function class_exists; |
39 | 41 | use function count; |
| 42 | +use function enum_exists; |
40 | 43 | use function explode; |
41 | 44 | use function gettype; |
42 | 45 | use function in_array; |
|
77 | 80 | * length?: int, |
78 | 81 | * id?: bool, |
79 | 82 | * nullable?: bool, |
| 83 | + * enumType?: class-string<BackedEnum>, |
80 | 84 | * columnDefinition?: string, |
81 | 85 | * precision?: int, |
82 | 86 | * scale?: int, |
@@ -1025,6 +1029,13 @@ public function wakeupReflection($reflService) |
1025 | 1029 | $this->reflFields[$field] = isset($mapping['declared']) |
1026 | 1030 | ? $reflService->getAccessibleProperty($mapping['declared'], $field) |
1027 | 1031 | : $reflService->getAccessibleProperty($this->name, $field); |
| 1032 | + |
| 1033 | + if (isset($mapping['enumType']) && $this->reflFields[$field] !== null) { |
| 1034 | + $this->reflFields[$field] = new ReflectionEnumProperty( |
| 1035 | + $this->reflFields[$field], |
| 1036 | + $mapping['enumType'] |
| 1037 | + ); |
| 1038 | + } |
1028 | 1039 | } |
1029 | 1040 |
|
1030 | 1041 | foreach ($this->associationMappings as $field => $mapping) { |
@@ -1468,6 +1479,15 @@ private function validateAndCompleteTypedFieldMapping(array $mapping): array |
1468 | 1479 | ! isset($mapping['type']) |
1469 | 1480 | && ($type instanceof ReflectionNamedType) |
1470 | 1481 | ) { |
| 1482 | + if (PHP_VERSION_ID >= 80100 && ! $type->isBuiltin() && enum_exists($type->getName(), false)) { |
| 1483 | + $mapping['enumType'] = $type->getName(); |
| 1484 | + |
| 1485 | + $reflection = new ReflectionEnum($type->getName()); |
| 1486 | + $type = $reflection->getBackingType(); |
| 1487 | + |
| 1488 | + assert($type instanceof ReflectionNamedType); |
| 1489 | + } |
| 1490 | + |
1471 | 1491 | switch ($type->getName()) { |
1472 | 1492 | case DateInterval::class: |
1473 | 1493 | $mapping['type'] = Types::DATEINTERVAL; |
@@ -1589,6 +1609,16 @@ protected function validateAndCompleteFieldMapping(array $mapping): array |
1589 | 1609 | $mapping['requireSQLConversion'] = true; |
1590 | 1610 | } |
1591 | 1611 |
|
| 1612 | + if (isset($mapping['enumType'])) { |
| 1613 | + if (PHP_VERSION_ID < 80100) { |
| 1614 | + throw MappingException::enumsRequirePhp81($this->name, $mapping['fieldName']); |
| 1615 | + } |
| 1616 | + |
| 1617 | + if (! enum_exists($mapping['enumType'])) { |
| 1618 | + throw MappingException::nonEnumTypeMapped($this->name, $mapping['fieldName'], $mapping['enumType']); |
| 1619 | + } |
| 1620 | + } |
| 1621 | + |
1592 | 1622 | return $mapping; |
1593 | 1623 | } |
1594 | 1624 |
|
|
0 commit comments