From a74b758ca2d855ac46757fdae4481a32391e98b7 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Wed, 6 Aug 2014 13:56:27 +0200 Subject: [PATCH] [FrameworkBundle] Fixed validator factory definition when the Validator API is "auto" for PHP < 5.3.9 --- .../DependencyInjection/Configuration.php | 17 +++- .../FrameworkExtension.php | 30 +++--- .../DependencyInjection/ConfigurationTest.php | 2 +- .../Fixtures/php/validation_2_5_api.php | 9 ++ .../Fixtures/php/validation_2_5_bc_api.php | 9 ++ .../Fixtures/php/validation_auto_api.php | 9 ++ .../Fixtures/php/validation_implicit_api.php | 8 ++ .../Fixtures/xml/validation_2_5_api.xml | 12 +++ .../Fixtures/xml/validation_2_5_bc_api.xml | 12 +++ .../Fixtures/xml/validation_auto_api.xml | 12 +++ .../Fixtures/xml/validation_implicit_api.xml | 12 +++ .../Fixtures/yml/validation_2_5_api.yml | 5 + .../Fixtures/yml/validation_2_5_bc_api.yml | 5 + .../Fixtures/yml/validation_auto_api.yml | 5 + .../Fixtures/yml/validation_implicit_api.yml | 4 + .../FrameworkExtensionTest.php | 91 ++++++++++++++++++- 16 files changed, 221 insertions(+), 21 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_api.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_bc_api.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_auto_api.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_implicit_api.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_api.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_bc_api.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_auto_api.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_implicit_api.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_api.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_bc_api.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_auto_api.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_implicit_api.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 668eecde1b..3a3cb9d916 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -457,8 +457,8 @@ class Configuration implements ConfigurationInterface ->booleanNode('strict_email')->defaultFalse()->end() ->enumNode('api') ->values(array('2.4', '2.5', '2.5-bc', 'auto')) - ->defaultValue('auto') ->beforeNormalization() + // XML/YAML parse as numbers, not as strings ->ifTrue(function ($v) { return is_scalar($v); }) ->then(function ($v) { return (string) $v; }) ->end() @@ -466,6 +466,21 @@ class Configuration implements ConfigurationInterface ->end() ->end() ->end() + ->validate() + ->ifTrue(function ($v) { return !isset($v['validation']['api']) || 'auto' === $v['validation']['api']; }) + ->then(function ($v) { + // This condition is duplicated in ValidatorBuilder. This + // duplication is necessary in order to know the desired + // API version already during container configuration + // (to adjust service classes etc.) + // See https://github.com/symfony/symfony/issues/11580 + $v['validation']['api'] = version_compare(PHP_VERSION, '5.3.9', '<') + ? '2.4' + : '2.5-bc'; + + return $v; + }) + ->end() ; } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 15e0801fb9..275a6ef60d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -714,21 +714,23 @@ class FrameworkExtension extends Extension $validatorBuilder->addMethodCall('setMetadataCache', array(new Reference('validator.mapping.cache.'.$config['cache']))); } - if ('auto' !== $config['api']) { - switch ($config['api']) { - case '2.4': - $api = Validation::API_VERSION_2_4; - break; - case '2.5': - $api = Validation::API_VERSION_2_5; - break; - default: - $api = Validation::API_VERSION_2_5_BC; - break; - } - - $validatorBuilder->addMethodCall('setApiVersion', array($api)); + switch ($config['api']) { + case '2.4': + $api = Validation::API_VERSION_2_4; + break; + case '2.5': + $api = Validation::API_VERSION_2_5; + break; + default: + $api = Validation::API_VERSION_2_5_BC; + break; } + + $validatorBuilder->addMethodCall('setApiVersion', array($api)); + + // You can use this parameter to check the API version in your own + // bundle extension classes + $container->setParameter('validator.api', $api); } private function getValidatorXmlMappingFiles(ContainerBuilder $container) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 794ca1922c..156a73325d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -129,7 +129,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase 'static_method' => array('loadValidatorMetadata'), 'translation_domain' => 'validators', 'strict_email' => false, - 'api' => 'auto', + 'api' => version_compare(PHP_VERSION, '5.3.9', '<') ? '2.4' : '2.5-bc', ), 'annotations' => array( 'cache' => 'file', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_api.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_api.php new file mode 100644 index 0000000000..20fceba039 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_api.php @@ -0,0 +1,9 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'validation' => array( + 'enabled' => true, + 'api' => '2.5', + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_bc_api.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_bc_api.php new file mode 100644 index 0000000000..02386dbe09 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_2_5_bc_api.php @@ -0,0 +1,9 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'validation' => array( + 'enabled' => true, + 'api' => '2.5-bc', + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_auto_api.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_auto_api.php new file mode 100644 index 0000000000..1d603a564f --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_auto_api.php @@ -0,0 +1,9 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'validation' => array( + 'enabled' => true, + 'api' => 'auto', + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_implicit_api.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_implicit_api.php new file mode 100644 index 0000000000..855abbb39c --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/validation_implicit_api.php @@ -0,0 +1,8 @@ +loadFromExtension('framework', array( + 'secret' => 's3cr3t', + 'validation' => array( + 'enabled' => true, + ), +)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_api.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_api.xml new file mode 100644 index 0000000000..213d281f4b --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_api.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_bc_api.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_bc_api.xml new file mode 100644 index 0000000000..38eff2fddd --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_2_5_bc_api.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_auto_api.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_auto_api.xml new file mode 100644 index 0000000000..2be409bfb6 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_auto_api.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_implicit_api.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_implicit_api.xml new file mode 100644 index 0000000000..a41c8f23c9 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/validation_implicit_api.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_api.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_api.yml new file mode 100644 index 0000000000..d1af6c4e27 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_api.yml @@ -0,0 +1,5 @@ +framework: + secret: s3cr3t + validation: + enabled: true + api: 2.5 diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_bc_api.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_bc_api.yml new file mode 100644 index 0000000000..ebf12e06f8 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_2_5_bc_api.yml @@ -0,0 +1,5 @@ +framework: + secret: s3cr3t + validation: + enabled: true + api: 2.5-bc diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_auto_api.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_auto_api.yml new file mode 100644 index 0000000000..27619e63ed --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_auto_api.yml @@ -0,0 +1,5 @@ +framework: + secret: s3cr3t + validation: + enabled: true + api: auto diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_implicit_api.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_implicit_api.yml new file mode 100644 index 0000000000..9b3aa63010 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/validation_implicit_api.yml @@ -0,0 +1,4 @@ +framework: + secret: s3cr3t + validation: + enabled: true diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 12bc95d0c2..7bd57457d9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -265,7 +265,7 @@ abstract class FrameworkExtensionTest extends TestCase $calls = $container->getDefinition('validator.builder')->getMethodCalls(); - $this->assertCount(6, $calls); + $this->assertCount(7, $calls); $this->assertSame('setConstraintValidatorFactory', $calls[0][0]); $this->assertEquals(array(new Reference('validator.validator_factory')), $calls[0][1]); $this->assertSame('setTranslator', $calls[1][0]); @@ -278,6 +278,13 @@ abstract class FrameworkExtensionTest extends TestCase $this->assertSame(array('loadValidatorMetadata'), $calls[4][1]); $this->assertSame('setMetadataCache', $calls[5][0]); $this->assertEquals(array(new Reference('validator.mapping.cache.apc')), $calls[5][1]); + $this->assertSame('setApiVersion', $calls[6][0]); + + if (version_compare(PHP_VERSION, '5.3.9', '<')) { + $this->assertEquals(array(Validation::API_VERSION_2_4), $calls[6][1]); + } else { + $this->assertEquals(array(Validation::API_VERSION_2_5_BC), $calls[6][1]); + } } public function testFullyConfiguredValidationService() @@ -319,7 +326,7 @@ abstract class FrameworkExtensionTest extends TestCase $calls = $container->getDefinition('validator.builder')->getMethodCalls(); - $this->assertCount(6, $calls); + $this->assertCount(7, $calls); $this->assertSame('enableAnnotationMapping', $calls[4][0]); $this->assertEquals(array(new Reference('annotation_reader')), $calls[4][1]); $this->assertSame('addMethodMapping', $calls[5][0]); @@ -337,7 +344,7 @@ abstract class FrameworkExtensionTest extends TestCase $calls = $container->getDefinition('validator.builder')->getMethodCalls(); - $this->assertCount(7, $calls); + $this->assertCount(8, $calls); $this->assertSame('addXmlMappings', $calls[3][0]); $this->assertSame('addYamlMappings', $calls[4][0]); $this->assertSame('enableAnnotationMapping', $calls[5][0]); @@ -360,12 +367,12 @@ abstract class FrameworkExtensionTest extends TestCase $calls = $container->getDefinition('validator.builder')->getMethodCalls(); - $this->assertCount(4, $calls); + $this->assertCount(5, $calls); $this->assertSame('addXmlMappings', $calls[3][0]); // no cache, no annotations, no static methods } - public function testValidationApiVersion() + public function testValidation2Dot4Api() { $container = $this->createContainerFromFile('validation_2_4_api'); @@ -380,6 +387,80 @@ abstract class FrameworkExtensionTest extends TestCase // no cache, no annotations } + public function testValidation2Dot5Api() + { + $container = $this->createContainerFromFile('validation_2_5_api'); + + $calls = $container->getDefinition('validator.builder')->getMethodCalls(); + + $this->assertCount(6, $calls); + $this->assertSame('addXmlMappings', $calls[3][0]); + $this->assertSame('addMethodMapping', $calls[4][0]); + $this->assertSame(array('loadValidatorMetadata'), $calls[4][1]); + $this->assertSame('setApiVersion', $calls[5][0]); + $this->assertSame(array(Validation::API_VERSION_2_5), $calls[5][1]); + // no cache, no annotations + } + + public function testValidation2Dot5BcApi() + { + $container = $this->createContainerFromFile('validation_2_5_bc_api'); + + $calls = $container->getDefinition('validator.builder')->getMethodCalls(); + + $this->assertCount(6, $calls); + $this->assertSame('addXmlMappings', $calls[3][0]); + $this->assertSame('addMethodMapping', $calls[4][0]); + $this->assertSame(array('loadValidatorMetadata'), $calls[4][1]); + $this->assertSame('setApiVersion', $calls[5][0]); + $this->assertSame(array(Validation::API_VERSION_2_5_BC), $calls[5][1]); + // no cache, no annotations + } + + public function testValidationImplicitApi() + { + $container = $this->createContainerFromFile('validation_implicit_api'); + + $calls = $container->getDefinition('validator.builder')->getMethodCalls(); + + $this->assertCount(6, $calls); + $this->assertSame('addXmlMappings', $calls[3][0]); + $this->assertSame('addMethodMapping', $calls[4][0]); + $this->assertSame(array('loadValidatorMetadata'), $calls[4][1]); + $this->assertSame('setApiVersion', $calls[5][0]); + // no cache, no annotations + + if (version_compare(PHP_VERSION, '5.3.9', '<')) { + $this->assertSame(array(Validation::API_VERSION_2_4), $calls[5][1]); + } else { + $this->assertSame(array(Validation::API_VERSION_2_5_BC), $calls[5][1]); + } + } + + /** + * This feature is equivalent to the implicit api, only that the "api" + * key is explicitly set to "auto". + */ + public function testValidationAutoApi() + { + $container = $this->createContainerFromFile('validation_auto_api'); + + $calls = $container->getDefinition('validator.builder')->getMethodCalls(); + + $this->assertCount(6, $calls); + $this->assertSame('addXmlMappings', $calls[3][0]); + $this->assertSame('addMethodMapping', $calls[4][0]); + $this->assertSame(array('loadValidatorMetadata'), $calls[4][1]); + $this->assertSame('setApiVersion', $calls[5][0]); + // no cache, no annotations + + if (version_compare(PHP_VERSION, '5.3.9', '<')) { + $this->assertSame(array(Validation::API_VERSION_2_4), $calls[5][1]); + } else { + $this->assertSame(array(Validation::API_VERSION_2_5_BC), $calls[5][1]); + } + } + public function testFormsCanBeEnabledWithoutCsrfProtection() { $container = $this->createContainerFromFile('form_no_csrf');