Skip to content

Commit 76b6197

Browse files
committed
add enum support
1 parent 9f46bbe commit 76b6197

5 files changed

Lines changed: 92 additions & 0 deletions

File tree

data-access-kit/src/Converter/DefaultValueConverter.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
use DateTimeImmutable;
1111
use DateTimeZone;
1212
use ReflectionNamedType;
13+
use ReflectionEnum;
14+
use BackedEnum;
15+
use UnitEnum;
1316
use stdClass;
17+
use function enum_exists;
1418
use function in_array;
1519
use function is_object;
1620
use function json_decode;
@@ -74,6 +78,14 @@ public function objectToDatabase(Table $table, Column $column, mixed $value, boo
7478
} else if (in_array($valueType->getName(), [DateTime::class, DateTimeImmutable::class], true)) {
7579
/** @var DateTime|DateTimeImmutable $value */
7680
$returnValue = (clone $value)->setTimezone($this->dateTimeZone)->format($this->dateTimeFormat);
81+
} else if (enum_exists($valueType->getName())) {
82+
/** @var BackedEnum|UnitEnum $value */
83+
if ($value instanceof BackedEnum) {
84+
$returnValue = $value->value;
85+
} else {
86+
// Unit enum - store the name
87+
$returnValue = $value->name;
88+
}
7789
} else if (null !== ($nestedTable = $this->registry->maybeGet($valueType->getName()))) {
7890
$jsonObject = new stdClass();
7991
foreach ($nestedTable->columns as $nestedColumn) {
@@ -161,6 +173,35 @@ public function databaseToObject(Table $table, Column $column, mixed $value, boo
161173
));
162174
}
163175
}
176+
} else if (enum_exists($valueType->getName())) {
177+
/** @var class-string<BackedEnum|UnitEnum> $className */
178+
$className = $valueType->getName();
179+
$enumReflection = new ReflectionEnum($className);
180+
181+
if ($enumReflection->isBacked()) {
182+
// Backed enum - use from() method
183+
/** @var class-string<BackedEnum> $className */
184+
$returnValue = $className::from($value);
185+
} else {
186+
// Unit enum - find case by name
187+
$cases = $enumReflection->getCases();
188+
$returnValue = null;
189+
foreach ($cases as $case) {
190+
if ($case->getName() === $value) {
191+
$returnValue = $case->getValue();
192+
break;
193+
}
194+
}
195+
if ($returnValue === null) {
196+
throw new ConverterException(sprintf(
197+
"Could not find enum case [%s] for enum [%s] in property [%s::\$%s].",
198+
$value,
199+
$className,
200+
$table->reflection->getName(),
201+
$column->reflection->getName()
202+
));
203+
}
204+
}
164205
} else if (null !== ($nestedTable = $this->registry->maybeGet($valueType->getName()))) {
165206
$jsonObject = $decode ? json_decode($value) : $value;
166207
$nestedObject = $nestedTable->reflection->newInstanceWithoutConstructor();

data-access-kit/test/Converter/DefaultValueConverterTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
use DataAccessKit\Attribute\Table;
77
use DataAccessKit\Converter\Fixture\DeepNestedObject;
88
use DataAccessKit\Converter\Fixture\NestedObject;
9+
use DataAccessKit\Converter\Fixture\StatusEnum;
10+
use DataAccessKit\Converter\Fixture\PriorityEnum;
11+
use DataAccessKit\Converter\Fixture\UnitEnum;
912
use DataAccessKit\Registry;
1013
use DateTime;
1114
use DateTimeImmutable;
@@ -100,6 +103,15 @@ public static function data()
100103
#[Column] public DeepNestedObject $deepNestedObject;
101104
#[Column] public ?DeepNestedObject $nullableDeepNestedObjectNull;
102105
#[Column] public ?DeepNestedObject $nullableDeepNestedObjectNotNull;
106+
#[Column] public StatusEnum $statusEnum;
107+
#[Column] public ?StatusEnum $nullableStatusEnumNull;
108+
#[Column] public ?StatusEnum $nullableStatusEnumNotNull;
109+
#[Column] public PriorityEnum $priorityEnum;
110+
#[Column] public ?PriorityEnum $nullablePriorityEnumNull;
111+
#[Column] public ?PriorityEnum $nullablePriorityEnumNotNull;
112+
#[Column] public UnitEnum $unitEnum;
113+
#[Column] public ?UnitEnum $nullableUnitEnumNull;
114+
#[Column] public ?UnitEnum $nullableUnitEnumNotNull;
103115
});
104116

105117
$data = [
@@ -139,6 +151,15 @@ public static function data()
139151
"deepNestedObject" => [new DeepNestedObject(new DeepNestedObject()), '{"nested":{"nested":null}}'],
140152
"nullableDeepNestedObjectNull" => [null, null],
141153
"nullableDeepNestedObjectNotNull" => [new DeepNestedObject(new DeepNestedObject()), '{"nested":{"nested":null}}'],
154+
"statusEnum" => [StatusEnum::Active, 'active'],
155+
"nullableStatusEnumNull" => [null, null],
156+
"nullableStatusEnumNotNull" => [StatusEnum::Pending, 'pending'],
157+
"priorityEnum" => [PriorityEnum::High, 3],
158+
"nullablePriorityEnumNull" => [null, null],
159+
"nullablePriorityEnumNotNull" => [PriorityEnum::Medium, 2],
160+
"unitEnum" => [UnitEnum::Red, 'Red'],
161+
"nullableUnitEnumNull" => [null, null],
162+
"nullableUnitEnumNotNull" => [UnitEnum::Blue, 'Blue'],
142163
];
143164
foreach ($data as $columnName => [$objectValue, $databaseValue]) {
144165
yield $columnName => [$table, $table->columns[$columnName], $objectValue, $databaseValue];
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace DataAccessKit\Converter\Fixture;
4+
5+
enum PriorityEnum: int
6+
{
7+
case Low = 1;
8+
case Medium = 2;
9+
case High = 3;
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace DataAccessKit\Converter\Fixture;
4+
5+
enum StatusEnum: string
6+
{
7+
case Active = 'active';
8+
case Inactive = 'inactive';
9+
case Pending = 'pending';
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace DataAccessKit\Converter\Fixture;
4+
5+
enum UnitEnum
6+
{
7+
case Red;
8+
case Green;
9+
case Blue;
10+
}

0 commit comments

Comments
 (0)