Skip to content

Commit aab771b

Browse files
committed
[make:entity] add enum support
1 parent 132d766 commit aab771b

File tree

6 files changed

+76
-0
lines changed

6 files changed

+76
-0
lines changed

src/Maker/MakeEntity.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,10 @@ private function askForNextField(ConsoleStyle $io, array $fields, string $entity
424424
if ('string' === $type) {
425425
// default to 255, avoid the question
426426
$classProperty->length = $io->ask('Field length', '255', Validator::validateLength(...));
427+
428+
if ($io->confirm('Is this field an enum?', false)) {
429+
$classProperty->enumType = $io->ask('Enum class', null, Validator::classIsBackedEnum(...));
430+
}
427431
} elseif ('decimal' === $type) {
428432
// 10 is the default value given in \Doctrine\DBAL\Schema\Column::$_precision
429433
$classProperty->precision = $io->ask('Precision (total number of digits stored: 100.00 would be 5)', '10', Validator::validatePrecision(...));

src/Util/ClassSource/Model/ClassProperty.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function __construct(
3333
public ?int $scale = null,
3434
public bool $needsTypeHint = true,
3535
public bool $unique = false,
36+
public ?string $enumType = null,
3637
) {
3738
}
3839

@@ -52,6 +53,10 @@ public function getAttributes(): array
5253
$attributes['unique'] = true;
5354
}
5455

56+
if ($this->enumType) {
57+
$attributes['enumType'] = $this->enumType;
58+
}
59+
5560
foreach (['length', 'id', 'nullable', 'precision', 'scale'] as $property) {
5661
if (null !== $this->$property) {
5762
$attributes[$property] = $this->$property;
@@ -74,6 +79,7 @@ public static function createFromObject(FieldMapping|array $data): self
7479
precision: $data->precision,
7580
scale: $data->scale,
7681
unique: $data->unique ?? false,
82+
enumType: $data->enumType,
7783
);
7884
}
7985

@@ -93,6 +99,7 @@ public static function createFromObject(FieldMapping|array $data): self
9399
precision: $data['precision'] ?? null,
94100
scale: $data['scale'] ?? null,
95101
unique: $data['unique'] ?? false,
102+
enumType: $data['enumType'] ?? null,
96103
);
97104
}
98105
}

src/Util/ClassSourceManipulator.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ public function addEntityField(ClassProperty $mapping): void
112112
}
113113
}
114114

115+
if (null !== $mapping->enumType) {
116+
$typeHint = $this->addUseStatementIfNecessary($mapping->enumType);
117+
}
118+
115119
// 2) USE property type on property below, nullable
116120
// 3) If default value, then NOT nullable
117121

@@ -894,6 +898,16 @@ public function buildAttributeNode(string $attributeClass, array $options, ?stri
894898
);
895899
}
896900

901+
if ('enumType' === $option) {
902+
return new Node\Arg(
903+
new Node\Expr\ConstFetch(new Node\Name(Str::getShortClassName($value).'::class')),
904+
false,
905+
false,
906+
[],
907+
new Node\Identifier($option)
908+
);
909+
}
910+
897911
return new Node\Arg($context->buildNodeExprByValue($value), false, false, [], new Node\Identifier($option));
898912
}, array_keys($options), array_values($options));
899913

src/Validator.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,15 @@ public static function classIsUserInterface($userClassName): string
244244

245245
return $userClassName;
246246
}
247+
248+
public static function classIsBackedEnum($backedEnum): string
249+
{
250+
self::classExists($backedEnum);
251+
252+
if (!isset(class_implements($backedEnum)[\BackedEnum::class])) {
253+
throw new RuntimeCommandException(sprintf('The class "%s" is not a valid BackedEnum.', $backedEnum));
254+
}
255+
256+
return $backedEnum;
257+
}
247258
}

tests/Maker/MakeEntityTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ public function getTestDetails(): \Generator
8181
'',
8282
// default length
8383
'',
84+
// enum type
85+
'',
8486
// nullable
8587
'',
8688
// no more properties
@@ -188,6 +190,8 @@ public function getTestDetails(): \Generator
188190
'name',
189191
'string',
190192
'255', // length
193+
// enum type
194+
'',
191195
// nullable
192196
'y',
193197
'createdAt',
@@ -214,6 +218,8 @@ public function getTestDetails(): \Generator
214218
'lastName',
215219
'string',
216220
'', // length (default 255)
221+
// enum type
222+
'',
217223
// nullable
218224
'y',
219225
// finish adding fields
@@ -620,6 +626,7 @@ public function getTestDetails(): \Generator
620626
// field name
621627
'firstName',
622628
'string',
629+
'',
623630
'', // length (default 255)
624631
// nullable
625632
'',
@@ -710,6 +717,30 @@ public function getTestDetails(): \Generator
710717
$this->assertFileExists($runner->getPath('src/Entity/User.php'));
711718
}),
712719
];
720+
721+
yield 'it_creates_a_new_class_with_enum_field' => [$this->createMakeEntityTest()
722+
->run(function (MakerTestRunner $runner) {
723+
$this->copyEntity($runner, 'Enum/Role-basic.php');
724+
725+
$runner->runMaker([
726+
// entity class name
727+
'User',
728+
// add not additional fields
729+
'role',
730+
'string',
731+
'255', // length
732+
// enum type
733+
'y',
734+
'App\\Entity\\Enum\\Role',
735+
// nullable
736+
'y',
737+
// finish adding fields
738+
'',
739+
]);
740+
741+
$this->runEntityTest($runner);
742+
}),
743+
];
713744
}
714745

715746
/** @param array<string, mixed> $data */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace App\Entity\Enum;
4+
5+
enum Role: string
6+
{
7+
case ADMIN = 'admin';
8+
case USER = 'user';
9+
}

0 commit comments

Comments
 (0)