diff --git a/src/FieldDescription/FieldDescription.php b/src/FieldDescription/FieldDescription.php index 2869af486..b1dac98cf 100644 --- a/src/FieldDescription/FieldDescription.php +++ b/src/FieldDescription/FieldDescription.php @@ -52,7 +52,7 @@ protected function setFieldMapping(array $fieldMapping): void $this->fieldMapping = $fieldMapping; $this->type ??= (string) $fieldMapping['type']; - $this->mappingType ??= $fieldMapping['type']; + $this->mappingType ??= isset($fieldMapping['enumType']) ? 'enum' : $fieldMapping['type']; } protected function setAssociationMapping(array $associationMapping): void diff --git a/src/FieldDescription/FilterTypeGuesser.php b/src/FieldDescription/FilterTypeGuesser.php index f5131493a..642a4c276 100644 --- a/src/FieldDescription/FilterTypeGuesser.php +++ b/src/FieldDescription/FilterTypeGuesser.php @@ -18,6 +18,7 @@ use Sonata\AdminBundle\FieldDescription\TypeGuesserInterface; use Sonata\AdminBundle\Form\Type\Operator\EqualOperatorType; use Sonata\DoctrineORMAdminBundle\Filter\BooleanFilter; +use Sonata\DoctrineORMAdminBundle\Filter\ChoiceFilter; use Sonata\DoctrineORMAdminBundle\Filter\DateFilter; use Sonata\DoctrineORMAdminBundle\Filter\DateTimeFilter; use Sonata\DoctrineORMAdminBundle\Filter\ModelFilter; @@ -26,6 +27,7 @@ use Sonata\DoctrineORMAdminBundle\Filter\TimeFilter; use Sonata\DoctrineORMAdminBundle\Filter\UidFilter; use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\EnumType; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Guess\Guess; use Symfony\Component\Form\Guess\TypeGuess; @@ -66,6 +68,11 @@ public function guess(FieldDescriptionInterface $fieldDescription): TypeGuess case 'time': case 'time_immutable': return new TypeGuess(TimeFilter::class, $options, Guess::HIGH_CONFIDENCE); + case 'enum': + $options['field_type'] = EnumType::class; + $options['field_options']['class'] = $fieldDescription->getFieldMapping()['enumType']; + + return new TypeGuess(ChoiceFilter::class, $options, Guess::HIGH_CONFIDENCE); case ClassMetadata::ONE_TO_ONE: case ClassMetadata::ONE_TO_MANY: case ClassMetadata::MANY_TO_ONE: diff --git a/src/FieldDescription/TypeGuesser.php b/src/FieldDescription/TypeGuesser.php index ffd91ab08..a78d11e44 100644 --- a/src/FieldDescription/TypeGuesser.php +++ b/src/FieldDescription/TypeGuesser.php @@ -54,15 +54,14 @@ public function guess(FieldDescriptionInterface $fieldDescription): TypeGuess case 'time': case 'time_immutable': return new TypeGuess(FieldDescriptionInterface::TYPE_TIME, [], Guess::HIGH_CONFIDENCE); + case 'enum': + return new TypeGuess(FieldDescriptionInterface::TYPE_ENUM, [], Guess::HIGH_CONFIDENCE); case ClassMetadata::ONE_TO_MANY: return new TypeGuess(FieldDescriptionInterface::TYPE_ONE_TO_MANY, [], Guess::HIGH_CONFIDENCE); - case ClassMetadata::MANY_TO_MANY: return new TypeGuess(FieldDescriptionInterface::TYPE_MANY_TO_MANY, [], Guess::HIGH_CONFIDENCE); - case ClassMetadata::MANY_TO_ONE: return new TypeGuess(FieldDescriptionInterface::TYPE_MANY_TO_ONE, [], Guess::HIGH_CONFIDENCE); - case ClassMetadata::ONE_TO_ONE: return new TypeGuess(FieldDescriptionInterface::TYPE_ONE_TO_ONE, [], Guess::HIGH_CONFIDENCE); default: diff --git a/tests/FieldDescription/FieldDescriptionTest.php b/tests/FieldDescription/FieldDescriptionTest.php index e71ae7e22..1bcc42f5d 100644 --- a/tests/FieldDescription/FieldDescriptionTest.php +++ b/tests/FieldDescription/FieldDescriptionTest.php @@ -19,6 +19,7 @@ use Sonata\AdminBundle\Exception\NoValueException; use Sonata\AdminBundle\FieldDescription\FieldDescriptionInterface; use Sonata\DoctrineORMAdminBundle\FieldDescription\FieldDescription; +use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Enum\Suit; final class FieldDescriptionTest extends TestCase { @@ -251,6 +252,17 @@ public function testGetValueForMultiLevelEmbeddedObject(): void static::assertSame('myMethodValue', $field->getValue($mockedObject)); } + public function testEnum(): void + { + $fieldMapping = ['type' => 'string', 'enumType' => Suit::class]; + + $field = new FieldDescription('bar', [], $fieldMapping); + + static::assertSame('string', $field->getType()); + static::assertSame('enum', $field->getMappingType()); + static::assertSame($fieldMapping, $field->getFieldMapping()); + } + /** * @dataProvider provideDescribesSingleValuedAssociationCases */ diff --git a/tests/FieldDescription/FilterTypeGuesserTest.php b/tests/FieldDescription/FilterTypeGuesserTest.php index afab364ce..0e2ff8838 100644 --- a/tests/FieldDescription/FilterTypeGuesserTest.php +++ b/tests/FieldDescription/FilterTypeGuesserTest.php @@ -19,13 +19,16 @@ use Sonata\AdminBundle\Form\Type\Operator\EqualOperatorType; use Sonata\DoctrineORMAdminBundle\FieldDescription\FilterTypeGuesser; use Sonata\DoctrineORMAdminBundle\Filter\BooleanFilter; +use Sonata\DoctrineORMAdminBundle\Filter\ChoiceFilter; use Sonata\DoctrineORMAdminBundle\Filter\DateFilter; use Sonata\DoctrineORMAdminBundle\Filter\DateTimeFilter; use Sonata\DoctrineORMAdminBundle\Filter\ModelFilter; use Sonata\DoctrineORMAdminBundle\Filter\NumberFilter; use Sonata\DoctrineORMAdminBundle\Filter\StringFilter; use Sonata\DoctrineORMAdminBundle\Filter\TimeFilter; +use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Enum\Suit; use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\EnumType; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Guess\Guess; @@ -44,18 +47,21 @@ protected function setUp(): void * @dataProvider provideGuessCases * * @phpstan-param class-string $expectedType + * @phpstan-param array $fieldMapping */ public function testGuess( int|string|null $mappingType, string $expectedType, array $expectedOptions, - int $expectedConfidence + int $expectedConfidence, + array $fieldMapping = [] ): void { $fieldDescription = $this->createStub(FieldDescriptionInterface::class); $fieldDescription->method('getFieldName')->willReturn('foo'); $fieldDescription->method('getMappingType')->willReturn($mappingType); $fieldDescription->method('getParentAssociationMappings')->willReturn([]); $fieldDescription->method('getTargetModel')->willReturn('Foo'); + $fieldDescription->method('getFieldMapping')->willReturn($fieldMapping); $guess = $this->guesser->guess($fieldDescription); @@ -65,7 +71,7 @@ public function testGuess( } /** - * @phpstan-return iterable, int}> + * @phpstan-return iterable, 3: int, 4?: array}> */ public function provideGuessCases(): iterable { @@ -125,6 +131,21 @@ public function provideGuessCases(): iterable Guess::MEDIUM_CONFIDENCE, ]; + yield [ + 'enum', + ChoiceFilter::class, + [ + 'field_name' => 'foo', + 'parent_association_mappings' => [], + 'field_type' => EnumType::class, + 'field_options' => [ + 'class' => Suit::class, + ], + ], + Guess::HIGH_CONFIDENCE, + ['enumType' => Suit::class], + ]; + yield [ ClassMetadata::ONE_TO_ONE, ModelFilter::class, diff --git a/tests/FieldDescription/TypeGuesserTest.php b/tests/FieldDescription/TypeGuesserTest.php index f0c894408..f965e507a 100644 --- a/tests/FieldDescription/TypeGuesserTest.php +++ b/tests/FieldDescription/TypeGuesserTest.php @@ -141,5 +141,12 @@ public function provideGuessCases(): iterable [], Guess::HIGH_CONFIDENCE, ]; + + yield [ + 'enum', + FieldDescriptionInterface::TYPE_ENUM, + [], + Guess::HIGH_CONFIDENCE, + ]; } } diff --git a/tests/Fixtures/Entity/Enum/Suit.php b/tests/Fixtures/Entity/Enum/Suit.php new file mode 100644 index 000000000..c3042cbc9 --- /dev/null +++ b/tests/Fixtures/Entity/Enum/Suit.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Entity\Enum; + +enum Suit: string +{ + case Clubs = 'C'; + case Diamonds = 'D'; + case Hearts = 'H'; + case Spades = 'S'; +}