Skip to content

Commit

Permalink
[Form] Add the EnumType
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander M. Turek <me@derrabus.de>
  • Loading branch information
derrabus committed Sep 21, 2021
1 parent 44042f6 commit c6edc34
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .github/patch-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php'):
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/'):
case false !== strpos($file, '/src/Symfony/Component/ErrorHandler/Tests/Fixtures/'):
case false !== strpos($file, '/src/Symfony/Component/Form/Tests/Fixtures/Answer.php'):
case false !== strpos($file, '/src/Symfony/Component/Form/Tests/Fixtures/Number.php'):
case false !== strpos($file, '/src/Symfony/Component/Form/Tests/Fixtures/Suit.php'):
case false !== strpos($file, '/src/Symfony/Component/PropertyInfo/Tests/Fixtures/'):
case false !== strpos($file, '/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php81Dummy.php'):
case false !== strpos($file, '/src/Symfony/Component/Runtime/Internal/ComposerPlugin.php'):
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.11",
"symfony/polyfill-php80": "^1.16",
"symfony/polyfill-php81": "^1.22",
"symfony/polyfill-php81": "^1.23",
"symfony/polyfill-uuid": "^1.15"
},
"replace": {
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CHANGELOG

* Deprecate calling `FormErrorIterator::children()` if the current element is not iterable.
* Allow to pass `TranslatableMessage` objects to the `help` option
* Add the `EnumType`

5.3
---
Expand Down
57 changes: 57 additions & 0 deletions src/Symfony/Component/Form/Extension/Core/Type/EnumType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Form\Extension\Core\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* A choice type for native PHP enums.
*
* @author Alexander M. Turek <me@derrabus.de>
*/
final class EnumType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver
->setRequired(['class'])
->setAllowedTypes('class', 'string')
->setAllowedValues('class', \Closure::fromCallable('enum_exists'))
->setDefault('choices', static function (Options $options): array {
return $options['class']::cases();
})
->setDefault('choice_label', static function (\UnitEnum $choice): string {
return $choice->name;
})
->setDefault('choice_value', static function (Options $options): ?\Closure {
if (!is_a($options['class'], \BackedEnum::class, true)) {
return null;
}

return static function (?\BackedEnum $choice): ?string {
if (null === $choice) {
return null;
}

return (string) $choice->value;
};
})
;
}

public function getParent(): string
{
return ChoiceType::class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ abstract class BaseTypeTest extends TypeTestCase

public function testPassDisabledAsOption()
{
$form = $this->factory->create($this->getTestedType(), null, ['disabled' => true]);
$form = $this->factory->create($this->getTestedType(), null, array_merge($this->getTestOptions(), ['disabled' => true]));

$this->assertTrue($form->isDisabled());
}

public function testPassIdAndNameToView()
{
$view = $this->factory->createNamed('name', $this->getTestedType())
$view = $this->factory->createNamed('name', $this->getTestedType(), null, $this->getTestOptions())
->createView();

$this->assertEquals('name', $view->vars['id']);
Expand All @@ -42,7 +42,7 @@ public function testPassIdAndNameToView()

public function testStripLeadingUnderscoresAndDigitsFromId()
{
$view = $this->factory->createNamed('_09name', $this->getTestedType())
$view = $this->factory->createNamed('_09name', $this->getTestedType(), null, $this->getTestOptions())
->createView();

$this->assertEquals('name', $view->vars['id']);
Expand All @@ -53,7 +53,7 @@ public function testStripLeadingUnderscoresAndDigitsFromId()
public function testPassIdAndNameToViewWithParent()
{
$view = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE)
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -66,7 +66,7 @@ public function testPassIdAndNameToViewWithGrandParent()
{
$builder = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE)
->add('child', FormTypeTest::TESTED_TYPE);
$builder->get('child')->add('grand_child', $this->getTestedType());
$builder->get('child')->add('grand_child', $this->getTestedType(), $this->getTestOptions());
$view = $builder->getForm()->createView();

$this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->vars['id']);
Expand All @@ -76,9 +76,9 @@ public function testPassIdAndNameToViewWithGrandParent()

public function testPassTranslationDomainToView()
{
$view = $this->factory->create($this->getTestedType(), null, [
$view = $this->factory->create($this->getTestedType(), null, array_merge($this->getTestOptions(), [
'translation_domain' => 'domain',
])
]))
->createView();

$this->assertSame('domain', $view->vars['translation_domain']);
Expand All @@ -90,7 +90,7 @@ public function testInheritTranslationDomainFromParent()
->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, [
'translation_domain' => 'domain',
])
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -103,9 +103,9 @@ public function testPreferOwnTranslationDomain()
->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, [
'translation_domain' => 'parent_domain',
])
->add('child', $this->getTestedType(), [
->add('child', $this->getTestedType(), array_merge($this->getTestOptions(), [
'translation_domain' => 'domain',
])
]))
->getForm()
->createView();

Expand All @@ -115,7 +115,7 @@ public function testPreferOwnTranslationDomain()
public function testDefaultTranslationDomain()
{
$view = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE)
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -126,9 +126,9 @@ public function testPassLabelTranslationParametersToView()
{
$this->requiresFeatureSet(403);

$view = $this->factory->create($this->getTestedType(), null, [
$view = $this->factory->create($this->getTestedType(), null, array_merge($this->getTestOptions(), [
'label_translation_parameters' => ['%param%' => 'value'],
])
]))
->createView();

$this->assertSame(['%param%' => 'value'], $view->vars['label_translation_parameters']);
Expand All @@ -138,9 +138,9 @@ public function testPassAttrTranslationParametersToView()
{
$this->requiresFeatureSet(403);

$view = $this->factory->create($this->getTestedType(), null, [
$view = $this->factory->create($this->getTestedType(), null, array_merge($this->getTestOptions(), [
'attr_translation_parameters' => ['%param%' => 'value'],
])
]))
->createView();

$this->assertSame(['%param%' => 'value'], $view->vars['attr_translation_parameters']);
Expand All @@ -154,7 +154,7 @@ public function testInheritLabelTranslationParametersFromParent()
->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, [
'label_translation_parameters' => ['%param%' => 'value'],
])
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -169,7 +169,7 @@ public function testInheritAttrTranslationParametersFromParent()
->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, [
'attr_translation_parameters' => ['%param%' => 'value'],
])
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -184,9 +184,9 @@ public function testPreferOwnLabelTranslationParameters()
->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, [
'label_translation_parameters' => ['%parent_param%' => 'parent_value', '%override_param%' => 'parent_override_value'],
])
->add('child', $this->getTestedType(), [
->add('child', $this->getTestedType(), array_merge($this->getTestOptions(), [
'label_translation_parameters' => ['%override_param%' => 'child_value'],
])
]))
->getForm()
->createView();

Expand All @@ -201,9 +201,9 @@ public function testPreferOwnAttrTranslationParameters()
->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE, null, [
'attr_translation_parameters' => ['%parent_param%' => 'parent_value', '%override_param%' => 'parent_override_value'],
])
->add('child', $this->getTestedType(), [
->add('child', $this->getTestedType(), array_merge($this->getTestOptions(), [
'attr_translation_parameters' => ['%override_param%' => 'child_value'],
])
]))
->getForm()
->createView();

Expand All @@ -215,7 +215,7 @@ public function testDefaultLabelTranslationParameters()
$this->requiresFeatureSet(403);

$view = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE)
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -227,7 +227,7 @@ public function testDefaultAttrTranslationParameters()
$this->requiresFeatureSet(403);

$view = $this->factory->createNamedBuilder('parent', FormTypeTest::TESTED_TYPE)
->add('child', $this->getTestedType())
->add('child', $this->getTestedType(), $this->getTestOptions())
->getForm()
->createView();

Expand All @@ -236,23 +236,26 @@ public function testDefaultAttrTranslationParameters()

public function testPassLabelToView()
{
$view = $this->factory->createNamed('__test___field', $this->getTestedType(), null, ['label' => 'My label'])
$view = $this->factory->createNamed('__test___field', $this->getTestedType(), null, array_merge(
$this->getTestOptions(),
['label' => 'My label']
))
->createView();

$this->assertSame('My label', $view->vars['label']);
}

public function testPassMultipartFalseToView()
{
$view = $this->factory->create($this->getTestedType())
$view = $this->factory->create($this->getTestedType(), null, $this->getTestOptions())
->createView();

$this->assertFalse($view->vars['multipart']);
}

public function testSubmitNull($expected = null, $norm = null, $view = null)
{
$form = $this->factory->create($this->getTestedType());
$form = $this->factory->create($this->getTestedType(), null, $this->getTestOptions());
$form->submit(null);

$this->assertSame($expected, $form->getData());
Expand All @@ -262,7 +265,7 @@ public function testSubmitNull($expected = null, $norm = null, $view = null)

public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = null)
{
$builder = $this->factory->createBuilder($this->getTestedType());
$builder = $this->factory->createBuilder($this->getTestedType(), null, $this->getTestOptions());

if ($builder->getCompound()) {
$emptyData = [];
Expand All @@ -286,4 +289,9 @@ protected function getTestedType()
{
return static::TESTED_TYPE;
}

protected function getTestOptions(): array
{
return [];
}
}
Loading

0 comments on commit c6edc34

Please sign in to comment.