8000 [Form] Deprecated FormValidatorInterface and moved implementations to… · jeremymarc/symfony@6df7a72 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6df7a72

Browse files
committed
[Form] Deprecated FormValidatorInterface and moved implementations to event listeners
1 parent 4631141 commit 6df7a72

File tree

13 files changed

+201
-139
lines changed

13 files changed

+201
-139
lines changed

CHANGELOG-2.1.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
267267
in their name anymore. Their names terminate with "[]" now.
268268
* [BC BREAK] FormType::getDefaultOptions() and FormType::getAllowedOptionValues()
269269
don't receive an options array anymore.
270+
* Deprecated FormValidatorInterface and substituted its implementations
271+
by event subscribers
270272

271273
### HttpFoundation
272274

UPGRADE-2.1.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,14 @@
417417
`FormEvents::PRE_BIND`, `FormEvents::BIND_CLIENT_DATA` or
418418
`FormEvents::BIND_NORM_DATA`.
419419
420+
* The interface FormValidatorInterface was deprecated and will be removed
421+
in Symfony 2.3.
422+
423+
If you implemented custom validators using this interface, you can
424+
substitute them by event listeners listening to the FormEvents::POST_BIND
425+
(or any other of the BIND events). In case you used the CallbackValidator
426+
class, you should now pass the callback directly to `addEventListener`.
427+
420428
### Session
421429
422430
* Flash messages now return an array based on their type. The old method is
@@ -543,6 +551,7 @@ To use mock session storage use the following. `handler_id` is irrelevant in th
543551
session:
544552
storage_id: session.storage.mock_file
545553
```
554+
546555
### WebProfilerBundle
547556
548557
* You must clear old profiles after upgrading to 2.1. If you are using a

src/Symfony/Component/Form/CallbackValidator.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,28 @@
1111

1212
namespace Symfony\Component\Form;
1313

14+
/**
15+
* Deprecated. You should use FormEvents::POST_BIND event listeners instead.
16+
*
17+
* @author Bernhard Schussek <bschussek@gmail.com>
18+
*
19+
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
20+
*/
1421
class CallbackValidator implements FormValidatorInterface
1522
{
1623
private $callback;
1724

25+
/**
26+
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
27+
*/
1828
public function __construct($callback)
1929
{
20-
// TODO validate callback
21-
2230
$this->callback = $callback;
2331
}
2432

33+
/**
34+
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
35+
*/
2536
public function validate(FormInterface $form)
2637
{
2738
return call_user_func($this->callback, $form);

src/Symfony/Component/Form/Extension/Core/Validator/DefaultValidator.php renamed to src/Symfony/Component/Form/Extension/Core/EventListener/ValidationListener.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,30 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\Form\Extension\Core\Validator;
12+
namespace Symfony\Component\Form\Extension\Core\EventListener;
1313

14-
use Symfony\Component\Form\FormInterface;
15-
use Symfony\Component\Form\FormValidatorInterface;
1614
use Symfony\Component\Form\FormError;
15+
use Symfony\Component\Form\FormEvents;
16+
use Symfony\Component\Form\Event\DataEvent;
17+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1718

18-
class DefaultValidator implements FormValidatorInterface
19+
/**
20+
* @author Bernhard Schussek <bschussek@gmail.com>
21+
*/
22+
class ValidationListener implements EventSubscriberInterface
1923
{
20-
public function validate(FormInterface $form)
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
static public function getSubscribedEvents()
2128
{
29+
return array(FormEvents::POST_BIND => 'validateForm');
30+
}
31+
32+
public function validateForm(DataEvent $event)
33+
{
34+
$form = $event->getForm();
35+
2236
if (!$form->isSynchronized()) {
2337
$form->addError(new FormError(
2438
$form->getAttribute('invalid_message'),

src/Symfony/Component/Form/Extension/Core/Type/FieldType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use Symfony\Component\Form\FormFactoryInterface;
2020
use Symfony\Component\Form\FormView;
2121
use Symfony\Component\Form\Extension\Core\EventListener\TrimListener;
22-
use Symfony\Component\Form\Extension\Core\Validator\DefaultValidator;
22+
use Symfony\Component\Form\Extension\Core\EventListener\ValidationListener;
2323
use Symfony\Component\EventDispatcher\EventDispatcher;
2424
use Symfony\Component\Form\Exception\FormException;
2525

@@ -60,7 +60,7 @@ public function buildForm(FormBuilder $builder, array $options)
6060
->setAttribute('invalid_message_parameters', $options['invalid_message_parameters'])
6161
->setAttribute('translation_domain', $options['translation_domain'])
6262
->setData($options['data'])
63-
->addValidator(new DefaultValidator())
63+
->addEventSubscriber(new ValidationListener())
6464
;
6565

6666
if ($options['trim']) {

src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php renamed to src/Symfony/Component/Form/Extension/Validator/EventListener/DelegatingValidationListener.php

Lines changed: 88 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -9,94 +9,33 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\Form\Extension\Validator\Validator;
12+
namespace Symfony\Component\Form\Extension\Validator\EventListener;
1313

14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1415
use Symfony\Component\Form\FormInterface;
15-
use Symfony\Component\Form\FormValidatorInterface;
1616
use Symfony\Component\Form\FormError;
17-
use Symfony\Component\Form\Util\VirtualFormAwareIterator;
17+
use Symfony\Component\Form\FormEvents;
18+
use Symfony\Component\Form\Event\DataEvent;
1819
use Symfony\Component\Form\Exception\FormException;
20+
use Symfony\Component\Form\Util\VirtualFormAwareIterator;
1921
use Symfony\Component\Form\Util\PropertyPath;
2022
use Symfony\Component\Validator\Constraint;
2123
use Symfony\Component\Validator\ValidatorInterface;
2224
use Symfony\Component\Validator\ExecutionContext;
2325

24-
class DelegatingValidator implements FormValidatorInterface
26+
/**
27+
* @author Bernhard Schussek <bschussek@gmail.com>
28+
*/
29+
class DelegatingValidationListener implements EventSubscriberInterface
2530
{
2631
private $validator;
2732

28-
public function __construct(ValidatorInterface $validator)
29-
{
30-
$this->validator = $validator;
31-
}
32-
3333
/**
34-
* Validates the form and its domain object.
35-
*
36-
* @param FormInterface $form A FormInterface instance
34+
* {@inheritdoc}
3735
*/
38-
public function validate(FormInterface $form)
36+
static public function getSubscribedEvents()
3937
{
40-
if ($form->isRoot()) {
41-
$mapping = array();
42-
$forms = array();
43-
44-
$this->buildFormPathMapping($form, $mapping);
45-
$this->buildDataPathMapping($form, $mapping);
46-
$this->buildNamePathMapping($form, $forms);
47-
$this->resolveMappingPlaceholders($mapping, $forms);
48-
49-
// Validate the form in group "Default"
50-
// Validation of the data in the custom group is done by validateData(),
51-
// which is constrained by the Execute constraint
52-
if ($form->hasAttribute('validation_constraint')) {
53-
$violations = $this->validator->validateValue(
54-
$form->getData(),
55-
$form->getAttribute('validation_constraint'),
56-
self::getFormValidationGroups($form)
57-
);
58-
59-
if ($violations) {
60-
foreach ($violations as $violation) {
61-
$propertyPath = new PropertyPath($violation->getPropertyPath());
62-
$template = $violation->getMessageTemplate();
63-
$parameters = $violation->getMessageParameters();
64-
$pluralization = $violation->getMessagePluralization();
65-
$error = new FormError($template, $parameters, $pluralization);
66-
67-
$child = $form;
68-
foreach ($propertyPath->getElements() as $element) {
69-
$children = $child->getChildren();
70-
if (!isset($children[$element])) {
71-
$form->addError($error);
72-
break;
73-
}
74-
75-
$child = $children[$element];
76-
}
77-
78-
$child->addError($error);
79-
}
80-
}
81-
} elseif (count($violations = $this->validator->validate($form))) {
82-
foreach ($violations as $violation) {
83-
$propertyPath = $violation->getPropertyPath();
84-
$template = $violation->getMessageTemplate();
85-
$parameters = $violation->getMessageParameters();
86-
$pluralization = $violation->getMessagePluralization();
87-
$error = new FormError($template, $parameters, $pluralization);
88-
89-
foreach ($mapping as $mappedPath => $child) {
90-
if (preg_match($mappedPath, $propertyPath)) {
91-
$child->addError($error);
92-
continue 2;
93-
}
94-
}
95-
96-
$form->addError($error);
97-
}
98-
}
99-
}
38+
return array(FormEvents::POST_BIND => 'validateForm');
10039
}
10140

10241
/**
@@ -175,6 +114,82 @@ static protected function getFormValidationGroups(FormInterface $form)
175114
return (array) $groups;
176115
}
177116

117+
public function __construct(ValidatorInterface $validator)
118+
{
119+
$this->validator = $validator;
120+
}
121+
122+
/**
123+
* Validates the form and its domain object.
124+
*
125+
* @param DataEvent $event The event object
126+
*/
127+
public function validateForm(DataEvent $event)
128+
{
129+
$form = $event->getForm();
130+
131+
if ($form->isRoot()) {
132+
$mapping = array();
133+
$forms = array();
134+
135+
$this->buildFormPathMapping($form, $mapping);
136+
$this->buildDataPathMapping($form, $mapping);
137+
$this->buildNamePathMapping($form, $forms);
138+
$this->resolveMappingPlaceholders($mapping, $forms);
139+
140+
// Validate the form in group "Default"
141+
// Validation of the data in the custom group is done by validateData(),
142+
// which is constrained by the Execute constraint
143+
if ($form->hasAttribute('validation_constraint')) {
144+
$violations = $this->validator->validateValue(
145+
$form->getData(),
146+
$form->getAttribute('validation_constraint'),
147+
self::getFormValidationGroups($form)
148+
);
149+
150+
if ($violations) {
151+
foreach ($violations as $violation) {
152+
$propertyPath = new PropertyPath($violation->getPropertyPath());
153+
$template = $violation->getMessageTemplate();
154+
$parameters = $violation->getMessageParameters();
155+
$pluralization = $violation->getMessagePluralization();
156+
$error = new FormError($template, $parameters, $pluralization);
157+
158+
$child = $form;
159+
foreach ($propertyPath->getElements() as $element) {
160+
$children = $child->getChildren();
161+
if (!isset($children[$element])) {
162+
$form->addError($error);
163+
break;
164+
}
165+
166+
$child = $children[$element];
167+
}
168+
169+
$child->addError($error);
170+
}
171+
}
172+
} elseif (count($violations = $this->validator->validate($form))) {
173+
foreach ($violations as $violation) {
174+
$propertyPath = $violation->getPropertyPath();
175+
$template = $violation->getMessageTemplate();
176+
$parameters = $violation->getMessageParameters();
177+
$pluralization = $violation->getMessagePluralization();
178+
$error = new FormError($template, $parameters, $pluralization);
179+
180+
foreach ($mapping as $mappedPath => $child) {
181+
if (preg_match($mappedPath, $propertyPath)) {
182+
$child->addError($error);
183+
continue 2;
184+
}
185+
}
186+
187+
$form->addError($error);
188+
}
189+
}
190+
}
191+
}
192+
178193
private function buildFormPathMapping(FormInterface $form, array &$mapping, $formPath = 'children', $namePath = '')
179194
{
180195
foreach ($form->getAttribute('error_mapping') as $nestedDataPath => $nestedNamePath) {

src/Symfony/Component/Form/Extension/Validator/Type/FieldTypeValidatorExtension.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313

1414
use Symfony\Component\Form\AbstractTypeExtension;
1515
use Symfony\Component\Form\FormBuilder;
16-
use Symfony\Component\Form\Extension\Validator\Validator\DelegatingValidator;
16+
use Symfony\Component\Form\Extension\Validator\EventListener\DelegatingValidationListener;
1717
use Symfony\Component\Validator\ValidatorInterface;
1818

19+
/**
20+
* @author Bernhard Schussek <bschussek@gmail.com>
21+
*/
1922
class FieldTypeValidatorExtension extends AbstractTypeExtension
2023
{
2124
private $validator;
@@ -39,7 +42,8 @@ public function buildForm(FormBuilder $builder, array $options)
3942
->setAttribute('validation_groups', $options['validation_groups'])
4043
->setAttribute('validation_constraint', $options['validation_constraint'])
4144
->setAttribute('cascade_validation', $options['cascade_validation'])
42-
->addValidator(new DelegatingValidator($this->validator));
45+
->addEventSubscriber(new DelegatingValidationListener($this->validator))
46+
;
4347
}
4448

4549
public function getDefaultOptions()

src/Symfony/Component/Form/Form.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,6 @@ public function bind($clientData)
573573
$validator->validate($this);
574574
}
575575

576-
$event = new DataEvent($this, $clientData);
577-
$this->dispatcher->dispatch(FormEvents::POST_VALIDATE, $event);
578-
579576
return $this;
580577
}
581578

@@ -808,6 +805,8 @@ public function getClientTransformers()
808805
* Returns the Validators
809806
*
810807
* @return array An array of FormValidatorInterface
808+
*
809+
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
811810
*/
812811
public function getValidators()
813812
{

src/Symfony/Component/Form/FormBuilder.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1818
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1919

20+
/**
21+
* @author Bernhard Schussek <bschussek@gmail.com>
22+
*/
2023
class FormBuilder
2124
{
2225
/**
@@ -261,6 +264,8 @@ public function getErrorBubbling()
261264
* @param FormValidatorInterface $validator The validator
262265
*
263266
* @return FormBuilder The current builder
267+
*
268+
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
264269
*/
265270
public function addValidator(FormValidatorInterface $validator)
266271
{
@@ -273,6 +278,8 @@ public function addValidator(FormValidatorInterface $validator)
273278
* Returns the validators used by the form.
274279
*
275280
* @return array An array of FormValidatorInterface
281+
*
282+
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
276283
*/
277284
public function getValidators()
278285
{

src/Symfony/Component/Form/FormEvents.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,4 @@ final class FormEvents
2929
const BIND_NORM_DATA = 'form.bind_norm_data';
3030

3131
const SET_DATA = 'form.set_data';
32-
33-
const POST_VALIDATE = 'form.post_validate';
3432
}

0 commit comments

Comments
 (0)
0