Skip to content

Commit 17e669f

Browse files
authored
Add support for Symfony 5.1 Compound constraint in form type guess (#36)
1 parent cdfbce5 commit 17e669f

File tree

2 files changed

+62
-13
lines changed

2 files changed

+62
-13
lines changed

src/Form/Extension/EnumTypeGuesser.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Symfony\Component\Form\Guess\TypeGuess;
1010
use Symfony\Component\Form\Guess\ValueGuess;
1111
use Symfony\Component\Validator\Constraint;
12+
use Symfony\Component\Validator\Constraints\Compound;
1213
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
1314
use Yokai\EnumBundle\EnumRegistry;
1415
use Yokai\EnumBundle\Form\Type\EnumType;
@@ -40,15 +41,16 @@ public function __construct(MetadataFactoryInterface $metadataFactory, EnumRegis
4041
*/
4142
public function guessTypeForConstraint(Constraint $constraint): ?TypeGuess
4243
{
43-
if (!$constraint instanceof Enum) {
44+
$enum = $this->getEnum($constraint);
45+
if ($enum === null) {
4446
return null;
4547
}
4648

4749
return new TypeGuess(
4850
EnumType::class,
4951
[
50-
'enum' => $constraint->enum,
51-
'multiple' => $constraint->multiple,
52+
'enum' => $enum->enum,
53+
'multiple' => $enum->multiple,
5254
],
5355
Guess::HIGH_CONFIDENCE
5456
);
@@ -77,4 +79,22 @@ public function guessPattern($class, $property): ?ValueGuess
7779
{
7880
return null; //override parent : not able to guess
7981
}
82+
83+
private function getEnum(Constraint $constraint): ?Enum
84+
{
85+
if ($constraint instanceof Enum) {
86+
return $constraint;
87+
}
88+
89+
if ($constraint instanceof Compound) {
90+
foreach ($constraint->constraints as $compositeConstraint) {
91+
$enum = $this->getEnum($compositeConstraint);
92+
if ($enum !== null) {
93+
return $enum;
94+
}
95+
}
96+
}
97+
98+
return null;
99+
}
80100
}

tests/Form/Extension/EnumTypeGuesserTest.php

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Symfony\Component\Form\Guess\Guess;
99
use Symfony\Component\Form\Guess\TypeGuess;
1010
use Symfony\Component\Form\Test\TypeTestCase;
11+
use Symfony\Component\Validator\Constraints\Compound;
1112
use Symfony\Component\Validator\Mapping\ClassMetadata;
1213
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
1314
use Yokai\EnumBundle\EnumRegistry;
@@ -26,7 +27,8 @@ class EnumTypeGuesserTest extends TypeTestCase
2627

2728
const TEST_CLASS = EnumTypeGuesserTest_TestClass::class;
2829

29-
const TEST_PROPERTY = 'property';
30+
const TEST_PROPERTY_DIRECT = 'direct';
31+
const TEST_PROPERTY_COMPOUND = 'compound';
3032

3133
/**
3234
* @var EnumTypeGuesser
@@ -56,7 +58,15 @@ protected function setUp(): void
5658
$this->enumRegistry->get(GenderEnum::class)->willReturn(new GenderEnum);
5759

5860
$this->metadata = new ClassMetadata(self::TEST_CLASS);
59-
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY, new Enum(['enum' => GenderEnum::class]));
61+
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY_DIRECT, new Enum(['enum' => GenderEnum::class]));
62+
if (class_exists(Compound::class)) {
63+
$this->metadata->addPropertyConstraint(self::TEST_PROPERTY_COMPOUND, new class extends Compound {
64+
protected function getConstraints(array $options): array
65+
{
66+
return [new Enum(['enum' => GenderEnum::class])];
67+
}
68+
});
69+
}
6070
$this->metadataFactory = $this->prophesize(MetadataFactoryInterface::class);
6171
$this->metadataFactory->getMetadataFor(self::TEST_CLASS)
6272
->willReturn($this->metadata);
@@ -66,7 +76,7 @@ protected function setUp(): void
6676
parent::setUp();
6777
}
6878

69-
public function testGuessType(): void
79+
public function testGuessTypeDirect(): void
7080
{
7181
$guess = new TypeGuess(
7282
EnumType::class,
@@ -77,33 +87,51 @@ public function testGuessType(): void
7787
Guess::HIGH_CONFIDENCE
7888
);
7989

80-
$this->assertEquals($guess, $this->guesser->guessType(self::TEST_CLASS, self::TEST_PROPERTY));
90+
$this->assertEquals($guess, $this->guesser->guessType(self::TEST_CLASS, self::TEST_PROPERTY_DIRECT));
91+
}
92+
93+
public function testGuessTypeCompound(): void
94+
{
95+
if (!class_exists(Compound::class)) {
96+
$this->markTestSkipped();
97+
}
98+
99+
$guess = new TypeGuess(
100+
EnumType::class,
101+
[
102+
'enum' => GenderEnum::class,
103+
'multiple' => false,
104+
],
105+
Guess::HIGH_CONFIDENCE
106+
);
107+
108+
$this->assertEquals($guess, $this->guesser->guessType(self::TEST_CLASS, self::TEST_PROPERTY_COMPOUND));
81109
}
82110

83111
public function testGuessRequired(): void
84112
{
85-
$this->assertNull($this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY));
113+
$this->assertNull($this->guesser->guessRequired(self::TEST_CLASS, self::TEST_PROPERTY_DIRECT));
86114
}
87115

88116
public function testGuessMaxLength(): void
89117
{
90-
$this->assertNull($this->guesser->guessMaxLength(self::TEST_CLASS, self::TEST_PROPERTY));
118+
$this->assertNull($this->guesser->guessMaxLength(self::TEST_CLASS, self::TEST_PROPERTY_DIRECT));
91119
}
92120

93121
public function testGuessPattern(): void
94122
{
95-
$this->assertNull($this->guesser->guessPattern(self::TEST_CLASS, self::TEST_PROPERTY));
123+
$this->assertNull($this->guesser->guessPattern(self::TEST_CLASS, self::TEST_PROPERTY_DIRECT));
96124
}
97125

98126
public function testCreateForm(): void
99127
{
100128
$class = self::TEST_CLASS;
101129
$form = $this->factory->create(FormType::class, new $class, ['data_class' => $class])
102-
->add(self::TEST_PROPERTY);
130+
->add(self::TEST_PROPERTY_DIRECT);
103131

104132
$this->assertEquals(
105133
['Male' => 'male', 'Female' => 'female'],
106-
$form->get(self::TEST_PROPERTY)->getConfig()->getOption('choices')
134+
$form->get(self::TEST_PROPERTY_DIRECT)->getConfig()->getOption('choices')
107135
);
108136
}
109137

@@ -117,5 +145,6 @@ protected function getExtensions(): array
117145

118146
class EnumTypeGuesserTest_TestClass
119147
{
120-
public $property;
148+
public $direct;
149+
public $compound;
121150
}

0 commit comments

Comments
 (0)