Skip to content

Commit

Permalink
Guess enum types
Browse files Browse the repository at this point in the history
  • Loading branch information
phansys committed Oct 22, 2023
1 parent bd0f494 commit 584432a
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/FieldDescription/FieldDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/FieldDescription/FilterTypeGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
5 changes: 2 additions & 3 deletions src/FieldDescription/TypeGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
12 changes: 12 additions & 0 deletions tests/FieldDescription/FieldDescriptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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
*/
Expand Down
25 changes: 23 additions & 2 deletions tests/FieldDescription/FilterTypeGuesserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -44,18 +47,21 @@ protected function setUp(): void
* @dataProvider provideGuessCases
*
* @phpstan-param class-string $expectedType
* @phpstan-param array<string, mixed> $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);

Expand All @@ -65,7 +71,7 @@ public function testGuess(
}

/**
* @phpstan-return iterable<array-key, array{int|string|null, class-string, array<string, mixed>, int}>
* @phpstan-return iterable<array-key, array{0: int|string|null, 1: class-string, 2: array<string, mixed>, 3: int, 4?: array<string, mixed>}>
*/
public function provideGuessCases(): iterable
{
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions tests/FieldDescription/TypeGuesserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,12 @@ public function provideGuessCases(): iterable
[],
Guess::HIGH_CONFIDENCE,
];

yield [
'enum',
FieldDescriptionInterface::TYPE_ENUM,
[],
Guess::HIGH_CONFIDENCE,
];
}
}
22 changes: 22 additions & 0 deletions tests/Fixtures/Entity/Enum/Suit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* 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';
}

0 comments on commit 584432a

Please sign in to comment.