Skip to content

Commit 07ed34a

Browse files
committed
simplify the form type extension registration
1 parent 40ad682 commit 07ed34a

25 files changed

+404
-74
lines changed

AbstractExtension.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,21 @@ private function initTypeExtensions()
175175
throw new UnexpectedTypeException($extension, 'Symfony\Component\Form\FormTypeExtensionInterface');
176176
}
177177

178-
$type = $extension->getExtendedType();
178+
if (method_exists($extension, 'getExtendedTypes')) {
179+
$extendedTypes = array();
179180

180-
$this->typeExtensions[$type][] = $extension;
181+
foreach ($extension::getExtendedTypes() as $extendedType) {
182+
$extendedTypes[] = $extendedType;
183+
}
184+
} else {
185+
@trigger_error(sprintf('Not implementing the static getExtendedTypes() method in %s when implementing the %s is deprecated since Symfony 4.2. The method will be added to the interface in 5.0.', \get_class($extension), FormTypeExtensionInterface::class), E_USER_DEPRECATED);
186+
187+
$extendedTypes = array($extension->getExtendedType());
188+
}
189+
190+
foreach ($extendedTypes as $extendedType) {
191+
$this->typeExtensions[$extendedType][] = $extension;
192+
}
181193
}
182194
}
183195

AbstractTypeExtension.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Form;
1313

14+
use Symfony\Component\Form\Exception\LogicException;
1415
use Symfony\Component\OptionsResolver\OptionsResolver;
1516

1617
/**
@@ -45,4 +46,22 @@ public function finishView(FormView $view, FormInterface $form, array $options)
4546
public function configureOptions(OptionsResolver $resolver)
4647
{
4748
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*
53+
* @deprecated since Symfony 4.2, use getExtendedTypes() instead.
54+
*/
55+
public function getExtendedType()
56+
{
57+
if (!method_exists($this, 'getExtendedTypes')) {
58+
throw new LogicException(sprintf('You need to implement the static getExtendedTypes() method when implementing the %s in %s.', FormTypeExtensionInterface::class, static::class));
59+
}
60+
61+
@trigger_error(sprintf('The %s::getExtendedType() method is deprecated since Symfony 4.2 and will be removed in 5.0. Use getExtendedTypes() instead.', \get_class($this)), E_USER_DEPRECATED);
62+
63+
foreach (static::getExtendedTypes() as $extendedType) {
64+
return $extendedType;
65+
}
66+
}
4867
}

CHANGELOG.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,36 @@ CHANGELOG
44
4.2.0
55
-----
66

7+
* The `getExtendedType()` method of the `FormTypeExtensionInterface` is deprecated and will be removed in 5.0. Type
8+
extensions must implement the static `getExtendedTypes()` method instead and return an iterable of extended types.
9+
10+
Before:
11+
12+
```php
13+
class FooTypeExtension extends AbstractTypeExtension
14+
{
15+
public function getExtendedType()
16+
{
17+
return FormType::class;
18+
}
19+
20+
// ...
21+
}
22+
```
23+
24+
After:
25+
26+
```php
27+
class FooTypeExtension extends AbstractTypeExtension
28+
{
29+
public static function getExtendedTypes(): iterable
30+
{
31+
return array(FormType::class);
32+
}
33+
34+
// ...
35+
}
36+
```
737
* deprecated the `$scale` argument of the `IntegerToLocalizedStringTransformer`
838
* added `Symfony\Component\Form\ClearableErrorsInterface`
939
* deprecated calling `FormRenderer::searchAndRenderBlock` for fields which were already rendered

DependencyInjection/FormPass.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\DependencyInjection\ContainerBuilder;
1919
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
2020
use Symfony\Component\DependencyInjection\Reference;
21+
use Symfony\Component\Form\FormTypeExtensionInterface;
2122

2223
/**
2324
* Adds all services with the tags "form.type", "form.type_extension" and
@@ -92,13 +93,27 @@ private function processFormTypeExtensions(ContainerBuilder $container)
9293

9394
$tag = $serviceDefinition->getTag($this->formTypeExtensionTag);
9495
if (isset($tag[0]['extended_type'])) {
95-
$extendedType = $tag[0]['extended_type'];
96+
if (!method_exists($serviceDefinition->getClass(), 'getExtendedTypes')) {
97+
@trigger_error(sprintf('Not implementing the static getExtendedTypes() method in %s when implementing the %s is deprecated since Symfony 4.2. The method will be added to the interface in 5.0.', $serviceDefinition->getClass(), FormTypeExtensionInterface::class), E_USER_DEPRECATED);
98+
}
99+
100+
$typeExtensions[$tag[0]['extended_type']][] = new Reference($serviceId);
101+
$typeExtensionsClasses[] = $serviceDefinition->getClass();
102+
} elseif (method_exists($serviceDefinition->getClass(), 'getExtendedTypes')) {
103+
$extendsTypes = false;
104+
105+
foreach ($serviceDefinition->getClass()::getExtendedTypes() as $extendedType) {
106+
$typeExtensions[$extendedType][] = new Reference($serviceId);
107+
$typeExtensionsClasses[] = $serviceDefinition->getClass();
108+
$extendsTypes = true;
109+
}
110+
111+
if (!$extendsTypes) {
112+
throw new InvalidArgumentException(sprintf('The getExtendedTypes() method for service "%s" does not return any extended types.', $serviceId));
113+
}
96114
} else {
97-
throw new InvalidArgumentException(sprintf('"%s" tagged services must have the extended type configured using the extended_type/extended-type attribute, none was configured for the "%s" service.', $this->formTypeExtensionTag, $serviceId));
115+
throw new InvalidArgumentException(sprintf('"%s" tagged services have to implement the static getExtendedTypes() method. The class for service "%s" does not implement it.', $this->formTypeExtensionTag, $serviceId));
98116
}
99-
100-
$typeExtensions[$extendedType][] = new Reference($serviceId);
101-
$typeExtensionsClasses[] = $serviceDefinition->getClass();
102117
}
103118

104119
foreach ($typeExtensions as $extendedType => $extensions) {

Extension/Csrf/Type/FormTypeCsrfExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\Csrf\Type;
1313

1414
use Symfony\Component\Form\AbstractTypeExtension;
15+
use Symfony\Component\Form\Extension\Core\Type\FormType;
1516
use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener;
1617
use Symfony\Component\Form\FormBuilderInterface;
1718
use Symfony\Component\Form\FormInterface;
@@ -114,8 +115,8 @@ public function configureOptions(OptionsResolver $resolver)
114115
/**
115116
* {@inheritdoc}
116117
*/
117-
public function getExtendedType()
118+
public static function getExtendedTypes(): iterable
118119
{
119-
return 'Symfony\Component\Form\Extension\Core\Type\FormType';
120+
return array(FormType::class);
120121
}
121122
}

Extension/DataCollector/Type/DataCollectorTypeExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\DataCollector\Type;
1313

1414
use Symfony\Component\Form\AbstractTypeExtension;
15+
use Symfony\Component\Form\Extension\Core\Type\FormType;
1516
use Symfony\Component\Form\Extension\DataCollector\EventListener\DataCollectorListener;
1617
use Symfony\Component\Form\Extension\DataCollector\FormDataCollectorInterface;
1718
use Symfony\Component\Form\FormBuilderInterface;
@@ -45,8 +46,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4546
/**
4647
* {@inheritdoc}
4748
*/
48-
public function getExtendedType()
49+
public static function getExtendedTypes(): iterable
4950
{
50-
return 'Symfony\Component\Form\Extension\Core\Type\FormType';
51+
return array(FormType::class);
5152
}
5253
}

Extension/DependencyInjection/DependencyInjectionExtension.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,19 @@ public function getTypeExtensions($name)
5858
foreach ($this->typeExtensionServices[$name] as $serviceId => $extension) {
5959
$extensions[] = $extension;
6060

61-
// validate result of getExtendedType() to ensure it is consistent with the service definition
62-
if ($extension->getExtendedType() !== $name) {
63-
throw new InvalidArgumentException(sprintf('The extended type specified for the service "%s" does not match the actual extended type. Expected "%s", given "%s".', $serviceId, $name, $extension->getExtendedType()));
61+
if (method_exists($extension, 'getExtendedTypes')) {
62+
$extendedTypes = array();
63+
64+
foreach ($extension::getExtendedTypes() as $extendedType) {
65+
$extendedTypes[] = $extendedType;
66+
}
67+
} else {
68+
$extendedTypes = array($extension->getExtendedType());
69+
}
70+
71+
// validate the result of getExtendedTypes()/getExtendedType() to ensure it is consistent with the service definition
72+
if (!\in_array($name, $extendedTypes, true)) {
73+
throw new InvalidArgumentException(sprintf('The extended type specified for the service "%s" does not match the actual extended type. Expected "%s", given "%s".', $serviceId, $name, implode(', ', $extendedTypes)));
6474
}
6575
}
6676
}

Extension/HttpFoundation/Type/FormTypeHttpFoundationExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\HttpFoundation\Type;
1313

1414
use Symfony\Component\Form\AbstractTypeExtension;
15+
use Symfony\Component\Form\Extension\Core\Type\FormType;
1516
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler;
1617
use Symfony\Component\Form\FormBuilderInterface;
1718
use Symfony\Component\Form\RequestHandlerInterface;
@@ -39,8 +40,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
3940
/**
4041
* {@inheritdoc}
4142
*/
42-
public function getExtendedType()
43+
public static function getExtendedTypes(): iterable
4344
{
44-
return 'Symfony\Component\Form\Extension\Core\Type\FormType';
45+
return array(FormType::class);
4546
}
4647
}

Extension/Validator/Type/FormTypeValidatorExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Form\Extension\Validator\Type;
1313

14+
use Symfony\Component\Form\Extension\Core\Type\FormType;
1415
use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener;
1516
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper;
1617
use Symfony\Component\Form\FormBuilderInterface;
@@ -67,8 +68,8 @@ public function configureOptions(OptionsResolver $resolver)
6768
/**
6869
* {@inheritdoc}
6970
*/
70-
public function getExtendedType()
71+
public static function getExtendedTypes(): iterable
7172
{
72-
return 'Symfony\Component\Form\Extension\Core\Type\FormType';
73+
return array(FormType::class);
7374
}
7475
}

Extension/Validator/Type/RepeatedTypeValidatorExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\Validator\Type;
1313

1414
use Symfony\Component\Form\AbstractTypeExtension;
15+
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
1516
use Symfony\Component\OptionsResolver\Options;
1617
use Symfony\Component\OptionsResolver\OptionsResolver;
1718

@@ -38,8 +39,8 @@ public function configureOptions(OptionsResolver $resolver)
3839
/**
3940
* {@inheritdoc}
4041
*/
41-
public function getExtendedType()
42+
public static function getExtendedTypes(): iterable
4243
{
43-
return 'Symfony\Component\Form\Extension\Core\Type\RepeatedType';
44+
return array(RepeatedType::class);
4445
}
4546
}

0 commit comments

Comments
 (0)