Skip to content

Commit

Permalink
[make:entity] add enum support
Browse files Browse the repository at this point in the history
  • Loading branch information
loicsapone committed May 3, 2024
1 parent 132d766 commit aab771b
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Maker/MakeEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,10 @@ private function askForNextField(ConsoleStyle $io, array $fields, string $entity
if ('string' === $type) {
// default to 255, avoid the question
$classProperty->length = $io->ask('Field length', '255', Validator::validateLength(...));

if ($io->confirm('Is this field an enum?', false)) {
$classProperty->enumType = $io->ask('Enum class', null, Validator::classIsBackedEnum(...));
}
} elseif ('decimal' === $type) {
// 10 is the default value given in \Doctrine\DBAL\Schema\Column::$_precision
$classProperty->precision = $io->ask('Precision (total number of digits stored: 100.00 would be 5)', '10', Validator::validatePrecision(...));
Expand Down
7 changes: 7 additions & 0 deletions src/Util/ClassSource/Model/ClassProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public function __construct(
public ?int $scale = null,
public bool $needsTypeHint = true,
public bool $unique = false,
public ?string $enumType = null,
) {
}

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

if ($this->enumType) {
$attributes['enumType'] = $this->enumType;
}

foreach (['length', 'id', 'nullable', 'precision', 'scale'] as $property) {
if (null !== $this->$property) {
$attributes[$property] = $this->$property;
Expand All @@ -74,6 +79,7 @@ public static function createFromObject(FieldMapping|array $data): self
precision: $data->precision,
scale: $data->scale,
unique: $data->unique ?? false,
enumType: $data->enumType,
);
}

Expand All @@ -93,6 +99,7 @@ public static function createFromObject(FieldMapping|array $data): self
precision: $data['precision'] ?? null,
scale: $data['scale'] ?? null,
unique: $data['unique'] ?? false,
enumType: $data['enumType'] ?? null,
);
}
}
14 changes: 14 additions & 0 deletions src/Util/ClassSourceManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ public function addEntityField(ClassProperty $mapping): void
}
}

if (null !== $mapping->enumType) {
$typeHint = $this->addUseStatementIfNecessary($mapping->enumType);
}

// 2) USE property type on property below, nullable
// 3) If default value, then NOT nullable

Expand Down Expand Up @@ -894,6 +898,16 @@ public function buildAttributeNode(string $attributeClass, array $options, ?stri
);
}

if ('enumType' === $option) {
return new Node\Arg(
new Node\Expr\ConstFetch(new Node\Name(Str::getShortClassName($value).'::class')),
false,
false,
[],
new Node\Identifier($option)
);
}

return new Node\Arg($context->buildNodeExprByValue($value), false, false, [], new Node\Identifier($option));
}, array_keys($options), array_values($options));

Expand Down
11 changes: 11 additions & 0 deletions src/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,15 @@ public static function classIsUserInterface($userClassName): string

return $userClassName;
}

public static function classIsBackedEnum($backedEnum): string
{
self::classExists($backedEnum);

if (!isset(class_implements($backedEnum)[\BackedEnum::class])) {
throw new RuntimeCommandException(sprintf('The class "%s" is not a valid BackedEnum.', $backedEnum));
}

return $backedEnum;
}
}
31 changes: 31 additions & 0 deletions tests/Maker/MakeEntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public function getTestDetails(): \Generator
'',
// default length
'',
// enum type
'',
// nullable
'',
// no more properties
Expand Down Expand Up @@ -188,6 +190,8 @@ public function getTestDetails(): \Generator
'name',
'string',
'255', // length
// enum type
'',
// nullable
'y',
'createdAt',
Expand All @@ -214,6 +218,8 @@ public function getTestDetails(): \Generator
'lastName',
'string',
'', // length (default 255)
// enum type
'',
// nullable
'y',
// finish adding fields
Expand Down Expand Up @@ -620,6 +626,7 @@ public function getTestDetails(): \Generator
// field name
'firstName',
'string',
'',
'', // length (default 255)
// nullable
'',
Expand Down Expand Up @@ -710,6 +717,30 @@ public function getTestDetails(): \Generator
$this->assertFileExists($runner->getPath('src/Entity/User.php'));
}),
];

yield 'it_creates_a_new_class_with_enum_field' => [$this->createMakeEntityTest()
->run(function (MakerTestRunner $runner) {
$this->copyEntity($runner, 'Enum/Role-basic.php');

$runner->runMaker([
// entity class name
'User',
// add not additional fields
'role',
'string',
'255', // length
// enum type
'y',
'App\\Entity\\Enum\\Role',
// nullable
'y',
// finish adding fields
'',
]);

$this->runEntityTest($runner);
}),
];
}

/** @param array<string, mixed> $data */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Entity\Enum;

enum Role: string
{
case ADMIN = 'admin';
case USER = 'user';
}

0 comments on commit aab771b

Please sign in to comment.