Skip to content

Commit a32e819

Browse files
committed
bug #11350 [2.5][Form] solved dependency to ValidatorInterface, fix #11036 (Sebastian Blum)
This PR was squashed before being merged into the 2.6-dev branch (closes #11350). Discussion ---------- [2.5][Form] solved dependency to ValidatorInterface, fix #11036 | Q | A | ------------- | --- | Bug fix? | [yes] | New feature? | [no] | BC breaks? | [no] | Deprecations? | [no] | Tests pass? | [yes] | Fixed tickets | #11036, #11345 | License | MIT | Doc PR | Since Symfony 2.5 The problem was that the form component has a hardcoded depencency to the deprecated validator component (api Version 2.4) The pull request fixes the dependency to the validator component and supports now both implementations, apiVersion 2.5 and apiVersion 2.4 of the validator component. @symfony Core Members please review the changes https://github.com/sebastianblum/symfony/blob/0a1e9c208f8730219bebf89f6696b246a0c88da7/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php I'm not sure if it was the right solution Commits ------- ab765c9 [2.5][Form] solved dependency to ValidatorInterface, fix #11036
2 parents 890cd39 + ab765c9 commit a32e819

File tree

6 files changed

+189
-9
lines changed

6 files changed

+189
-9
lines changed

src/Symfony/Component/Form/Extension/Validator/EventListener/ValidationListener.php

+11-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1515
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapperInterface;
16-
use Symfony\Component\Validator\ValidatorInterface;
16+
use Symfony\Component\Validator\Validator\ValidatorInterface;
17+
use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
1718
use Symfony\Component\Form\FormEvents;
1819
use Symfony\Component\Form\FormEvent;
1920
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
@@ -35,8 +36,16 @@ public static function getSubscribedEvents()
3536
return array(FormEvents::POST_SUBMIT => 'validateForm');
3637
}
3738

38-
public function __construct(ValidatorInterface $validator, ViolationMapperInterface $violationMapper)
39+
/**
40+
* @param ValidatorInterface|LegacyValidatorInterface $validator
41+
* @param ViolationMapperInterface $violationMapper
42+
*/
43+
public function __construct($validator, ViolationMapperInterface $violationMapper)
3944
{
45+
if (!$validator instanceof ValidatorInterface && !$validator instanceof LegacyValidatorInterface) {
46+
throw new \InvalidArgumentException('Validator must be instance of Symfony\Component\Validator\Validator\ValidatorInterface or Symfony\Component\Validator\ValidatorInterface');
47+
}
48+
4049
$this->validator = $validator;
4150
$this->violationMapper = $violationMapper;
4251
}

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
use Symfony\Component\Form\FormBuilderInterface;
1515
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper;
1616
use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener;
17-
use Symfony\Component\Validator\ValidatorInterface;
17+
use Symfony\Component\Validator\Validator\ValidatorInterface;
18+
use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
1819
use Symfony\Component\OptionsResolver\Options;
1920
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
2021

@@ -33,8 +34,15 @@ class FormTypeValidatorExtension extends BaseValidatorExtension
3334
*/
3435
private $violationMapper;
3536

36-
public function __construct(ValidatorInterface $validator)
37+
/**
38+
* @param ValidatorInterface|LegacyValidatorInterface $validator
39+
*/
40+
public function __construct($validator)
3741
{
42+
if (!$validator instanceof ValidatorInterface && !$validator instanceof LegacyValidatorInterface) {
43+
throw new \InvalidArgumentException('Validator must be instance of Symfony\Component\Validator\Validator\ValidatorInterface or Symfony\Component\Validator\ValidatorInterface');
44+
}
45+
3846
$this->validator = $validator;
3947
$this->violationMapper = new ViolationMapper();
4048
}

src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php

+22-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313

1414
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
1515
use Symfony\Component\Form\AbstractExtension;
16-
use Symfony\Component\Validator\ValidatorInterface;
1716
use Symfony\Component\Validator\Constraints\Valid;
17+
use Symfony\Component\Validator\Mapping\ClassMetadata;
18+
use Symfony\Component\Validator\Validator\ValidatorInterface;
19+
use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
1820

1921
/**
2022
* Extension supporting the Symfony2 Validator component in forms.
@@ -25,17 +27,32 @@ class ValidatorExtension extends AbstractExtension
2527
{
2628
private $validator;
2729

28-
public function __construct(ValidatorInterface $validator)
30+
/**
31+
* @param ValidatorInterface|LegacyValidatorInterface $validator
32+
*/
33+
public function __construct($validator)
2934
{
30-
$this->validator = $validator;
35+
// since validator apiVersion 2.5
36+
if ($validator instanceof ValidatorInterface) {
37+
$this->validator = $validator;
38+
39+
/** @var $metadata ClassMetadata */
40+
$metadata = $this->validator->getMetadataFor('Symfony\Component\Form\Form');
41+
// until validator apiVersion 2.4
42+
} elseif ($validator instanceof LegacyValidatorInterface) {
43+
$this->validator = $validator;
44+
45+
/** @var $metadata ClassMetadata */
46+
$metadata = $this->validator->getMetadataFactory()->getMetadataFor('Symfony\Component\Form\Form');
47+
} else {
48+
throw new \InvalidArgumentException('Validator must be instance of Symfony\Component\Validator\Validator\ValidatorInterface or Symfony\Component\Validator\ValidatorInterface');
49+
}
3150

3251
// Register the form constraints in the validator programmatically.
3352
// This functionality is required when using the Form component without
3453
// the DIC, where the XML file is loaded automatically. Thus the following
3554
// code must be kept synchronized with validation.xml
3655

37-
/** @var \Symfony\Component\Validator\Mapping\ClassMetadata $metadata */
38-
$metadata = $this->validator->getMetadataFactory()->getMetadataFor('Symfony\Component\Form\Form');
3956
$metadata->addConstraint(new Form());
4057
$metadata->addPropertyConstraint('children', new Valid());
4158
}

src/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php

+26
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,30 @@ public function testValidateWithEmptyViolationList()
158158

159159
$this->listener->validateForm(new FormEvent($form, null));
160160
}
161+
162+
public function testValidatorInterfaceSinceSymfony25()
163+
{
164+
// Mock of ValidatorInterface since apiVersion 2.5
165+
$validator = $this->getMock('Symfony\Component\Validator\Validator\ValidatorInterface');
166+
167+
$listener = new ValidationListener($validator, $this->violationMapper);
168+
$this->assertAttributeSame($validator, 'validator', $listener);
169+
}
170+
171+
public function testValidatorInterfaceUntilSymfony24()
172+
{
173+
// Mock of ValidatorInterface until apiVersion 2.4
174+
$validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface');
175+
176+
$listener = new ValidationListener($validator, $this->violationMapper);
177+
$this->assertAttributeSame($validator, 'validator', $listener);
178+
}
179+
180+
/**
181+
* @expectedException \InvalidArgumentException
182+
*/
183+
public function testInvalidValidatorInterface()
184+
{
185+
new ValidationListener(null, $this->violationMapper);
186+
}
161187
}

src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php

+27
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

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

14+
use Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension;
1415
use Symfony\Component\Validator\ConstraintViolationList;
1516

1617
class FormTypeValidatorExtensionTest extends BaseValidatorExtensionTest
@@ -36,6 +37,32 @@ public function testSubmitValidatesData()
3637
$form->submit(array());
3738
}
3839

40+
public function testValidatorInterfaceSinceSymfony25()
41+
{
42+
// Mock of ValidatorInterface since apiVersion 2.5
43+
$validator = $this->getMock('Symfony\Component\Validator\Validator\ValidatorInterface');
44+
45+
$formTypeValidatorExtension = new FormTypeValidatorExtension($validator);
46+
$this->assertAttributeSame($validator, 'validator', $formTypeValidatorExtension);
47+
}
48+
49+
public function testValidatorInterfaceUntilSymfony24()
50+
{
51+
// Mock of ValidatorInterface until apiVersion 2.4
52+
$validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface');
53+
54+
$formTypeValidatorExtension = new FormTypeValidatorExtension($validator);
55+
$this->assertAttributeSame($validator, 'validator', $formTypeValidatorExtension);
56+
}
57+
58+
/**
59+
* @expectedException \InvalidArgumentException
60+
*/
61+
public function testInvalidValidatorInterface()
62+
{
63+
new FormTypeValidatorExtension(null);
64+
}
65+
3966
protected function createForm(array $options = array())
4067
{
4168
return $this->factory->create('form', null, $options);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests\Extension\Validator;
13+
14+
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
15+
16+
class ValidatorExtensionTest extends \PHPUnit_Framework_TestCase
17+
{
18+
public function testValidatorInterfaceSinceSymfony25()
19+
{
20+
$classMetaData = $this->createClassMetaDataMock();
21+
22+
// Mock of ValidatorInterface since apiVersion 2.5
23+
$validator = $this->getMock('Symfony\Component\Validator\Validator\ValidatorInterface');
24+
25+
$validator
26+
->expects($this->once())
27+
->method('getMetadataFor')
28+
->with($this->identicalTo('Symfony\Component\Form\Form'))
29+
->will($this->returnValue($classMetaData))
30+
;
31+
32+
$validatorExtension = new ValidatorExtension($validator);
33+
$this->assertAttributeSame($validator, 'validator', $validatorExtension);
34+
}
35+
36+
public function testValidatorInterfaceUntilSymfony24()
37+
{
38+
$classMetaData = $this->createClassMetaDataMock();
39+
40+
$metaDataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
41+
42+
$metaDataFactory
43+
->expects($this->once())
44+
->method('getMetadataFor')
45+
->with($this->identicalTo('Symfony\Component\Form\Form'))
46+
->will($this->returnValue($classMetaData))
47+
;
48+
49+
// Mock of ValidatorInterface until apiVersion 2.4
50+
$validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface');
51+
52+
$validator
53+
->expects($this->once())
54+
->method('getMetadataFactory')
55+
->will($this->returnValue($metaDataFactory))
56+
;
57+
58+
$validatorExtension = new ValidatorExtension($validator);
59+
$this->assertAttributeSame($validator, 'validator', $validatorExtension);
60+
}
61+
62+
/**
63+
* @expectedException \InvalidArgumentException
64+
*/
65+
public function testInvalidValidatorInterface()
66+
{
67+
new ValidatorExtension(null);
68+
}
69+
70+
/**
71+
* @return mixed
72+
*/
73+
private function createClassMetaDataMock()
74+
{
75+
$classMetaData = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
76+
->disableOriginalConstructor()
77+
->getMock();
78+
79+
$classMetaData
80+
->expects($this->once())
81+
->method('addConstraint')
82+
->with($this->isInstanceOf('Symfony\Component\Form\Extension\Validator\Constraints\Form'));
83+
$classMetaData
84+
->expects($this->once())
85+
->method('addPropertyConstraint')
86+
->with(
87+
$this->identicalTo('children'),
88+
$this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid')
89+
);
90+
91+
return $classMetaData;
92+
}
93+
}

0 commit comments

Comments
 (0)