Skip to content

Commit a5966a3

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

File tree

6 files changed

+77
-0
lines changed

6 files changed

+77
-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: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\MakerBundle\Tests\Maker;
1313

14+
use App\Entity\Enum\Role;
1415
use Symfony\Bundle\MakerBundle\Maker\MakeEntity;
1516
use Symfony\Bundle\MakerBundle\Test\MakerTestCase;
1617
use Symfony\Bundle\MakerBundle\Test\MakerTestDetails;
@@ -81,6 +82,8 @@ public function getTestDetails(): \Generator
8182
'',
8283
// default length
8384
'',
85+
// enum type
86+
'',
8487
// nullable
8588
'',
8689
// no more properties
@@ -188,6 +191,8 @@ public function getTestDetails(): \Generator
188191
'name',
189192
'string',
190193
'255', // length
194+
// enum type
195+
'',
191196
// nullable
192197
'y',
193198
'createdAt',
@@ -214,6 +219,8 @@ public function getTestDetails(): \Generator
214219
'lastName',
215220
'string',
216221
'', // length (default 255)
222+
// enum type
223+
'',
217224
// nullable
218225
'y',
219226
// finish adding fields
@@ -620,6 +627,7 @@ public function getTestDetails(): \Generator
620627
// field name
621628
'firstName',
622629
'string',
630+
'',
623631
'', // length (default 255)
624632
// nullable
625633
'',
@@ -710,6 +718,30 @@ public function getTestDetails(): \Generator
710718
$this->assertFileExists($runner->getPath('src/Entity/User.php'));
711719
}),
712720
];
721+
722+
yield 'it_creates_a_new_class_with_enum_field' => [$this->createMakeEntityTest()
723+
->run(function (MakerTestRunner $runner) {
724+
$this->copyEntity($runner, 'Enum/Role-basic.php');
725+
726+
$runner->runMaker([
727+
// entity class name
728+
'User',
729+
// add not additional fields
730+
'role',
731+
'string',
732+
'255', // length
733+
// enum type
734+
'y',
735+
'App\\Entity\\Enum\\Role',
736+
// nullable
737+
'y',
738+
// finish adding fields
739+
'',
740+
]);
741+
742+
$this->runEntityTest($runner);
743+
}),
744+
];
713745
}
714746

715747
/** @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)