diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md new file mode 100644 index 000000000000..c88642f610ca --- /dev/null +++ b/UPGRADE-4.3.md @@ -0,0 +1,7 @@ +UPGRADE FROM 4.2 to 4.3 +======================= + +Config +------ + + * Deprecated using environment variables with `cannotBeEmpty()` if the value is validated with `validate()` diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 4ec9e24f4f0c..7a845414bd86 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -18,6 +18,7 @@ Config * Added the `getChildNodeDefinitions()` method to `ParentNodeDefinitionInterface`. * The `Processor` class has been made final * Removed `FileLoaderLoadException`, use `LoaderLoadException` instead. + * Using environment variables with `cannotBeEmpty()` if the value is validated with `validate()` will throw an exception. Console ------- diff --git a/composer.json b/composer.json index 839e21780b88..8eeac423c69d 100644 --- a/composer.json +++ b/composer.json @@ -147,7 +147,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index db7c8ce7a341..7c0bed953db8 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -66,7 +66,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index ce7fee470b24..2cb3654013d3 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -46,7 +46,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bridge/PhpUnit/composer.json b/src/Symfony/Bridge/PhpUnit/composer.json index 4d72603eb452..0c2f6d80492e 100644 --- a/src/Symfony/Bridge/PhpUnit/composer.json +++ b/src/Symfony/Bridge/PhpUnit/composer.json @@ -40,7 +40,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" }, "thanks": { "name": "phpunit/phpunit", diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index 648bf8990fb6..d5ce7a3e3989 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -35,7 +35,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 32e78d41a14d..7e333592a129 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -28,7 +28,7 @@ {%- endblock form_widget_compound -%} {%- block collection_widget -%} - {% if prototype is defined %} + {% if prototype is defined and prototype.rendered is same as(false) %} {%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%} {% endif %} {{- block('form_widget') -}} diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index ec0d36a2b99e..440f4250cf8d 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -70,7 +70,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bundle/DebugBundle/composer.json b/src/Symfony/Bundle/DebugBundle/composer.json index 535d0edfa805..76f7a86f96a2 100644 --- a/src/Symfony/Bundle/DebugBundle/composer.json +++ b/src/Symfony/Bundle/DebugBundle/composer.json @@ -44,7 +44,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index fa14dcc25edf..8d516821bb13 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -98,7 +98,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 5a03f8f7fa84..23b40ea14463 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -64,7 +64,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index d9526cf7d541..5376f90e126a 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -54,7 +54,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 79f4ddb596cc..af07f8cf8cd4 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -44,7 +44,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Bundle/WebServerBundle/composer.json b/src/Symfony/Bundle/WebServerBundle/composer.json index 4a981ea93e41..bf2e67a8368b 100644 --- a/src/Symfony/Bundle/WebServerBundle/composer.json +++ b/src/Symfony/Bundle/WebServerBundle/composer.json @@ -37,7 +37,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/Asset/composer.json b/src/Symfony/Component/Asset/composer.json index bcf70fc18318..cfdd49546f5e 100644 --- a/src/Symfony/Component/Asset/composer.json +++ b/src/Symfony/Component/Asset/composer.json @@ -34,7 +34,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index 0607378c4d36..4c0567b5da9e 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -35,7 +35,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index 8f9e669a3322..c11af6d8f19a 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -51,7 +51,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/Config/CHANGELOG.md b/src/Symfony/Component/Config/CHANGELOG.md index fea35f9e47be..5b4f60a2722a 100644 --- a/src/Symfony/Component/Config/CHANGELOG.md +++ b/src/Symfony/Component/Config/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.3.0 +----- + + * deprecated using environment variables with `cannotBeEmpty()` if the value is validated with `validate()` + 4.2.0 ----- diff --git a/src/Symfony/Component/Config/Definition/ScalarNode.php b/src/Symfony/Component/Config/Definition/ScalarNode.php index ee870b6a85ea..77503bfd6e1f 100644 --- a/src/Symfony/Component/Config/Definition/ScalarNode.php +++ b/src/Symfony/Component/Config/Definition/ScalarNode.php @@ -48,6 +48,8 @@ protected function validateType($value) */ protected function isValueEmpty($value) { + // assume environment variables are never empty (which in practice is likely to be true during runtime) + // not doing so breaks many configs that are valid today if ($this->isHandlingPlaceholder()) { return false; } diff --git a/src/Symfony/Component/Config/Definition/VariableNode.php b/src/Symfony/Component/Config/Definition/VariableNode.php index 1a3442d9613d..0d722c6bd28a 100644 --- a/src/Symfony/Component/Config/Definition/VariableNode.php +++ b/src/Symfony/Component/Config/Definition/VariableNode.php @@ -81,6 +81,19 @@ protected function validateType($value) */ protected function finalizeValue($value) { + // deny environment variables only when using custom validators + // this avoids ever passing an empty value to final validation closures + if (!$this->allowEmptyValue && $this->isHandlingPlaceholder() && $this->finalValidationClosures) { + @trigger_error(sprintf('Setting path "%s" to an environment variable is deprecated since Symfony 4.3. Remove "cannotBeEmpty()", "validate()" or include a prefix/suffix value instead.', $this->getPath()), E_USER_DEPRECATED); +// $e = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an environment variable when empty values are not allowed by definition and are validated.', $this->getPath(), json_encode($value))); +// if ($hint = $this->getInfo()) { +// $e->addHint($hint); +// } +// $e->setPath($this->getPath()); +// +// throw $e; + } + if (!$this->allowEmptyValue && $this->isValueEmpty($value)) { $ex = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an empty value, but got %s.', $this->getPath(), json_encode($value))); if ($hint = $this->getInfo()) { @@ -120,6 +133,8 @@ protected function mergeValues($leftSide, $rightSide) * @param mixed $value * * @return bool + * + * @see finalizeValue() */ protected function isValueEmpty($value) { diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index 35fbffdb69a4..aa87fe4f3889 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -41,7 +41,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index ca1a9269f309..64f63aeb23e9 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -47,7 +47,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/CssSelector/composer.json b/src/Symfony/Component/CssSelector/composer.json index ebe7d0d5c1ee..91e64f27d9b2 100644 --- a/src/Symfony/Component/CssSelector/composer.json +++ b/src/Symfony/Component/CssSelector/composer.json @@ -31,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } } } diff --git a/src/Symfony/Component/Debug/CHANGELOG.md b/src/Symfony/Component/Debug/CHANGELOG.md index 122af73174bf..2b7bfc8ba30e 100644 --- a/src/Symfony/Component/Debug/CHANGELOG.md +++ b/src/Symfony/Component/Debug/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.3.0 +----- + +* made the `ErrorHandler` and `ExceptionHandler` classes final + 4.0.0 ----- diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index ecae93dbc1dd..af38e6486571 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -45,6 +45,8 @@ * * @author Nicolas Grekas
* @author Grégoire Pineau
+ *
+ * @final since Symfony 4.3
*/
class ExceptionHandler
{
diff --git a/src/Symfony/Component/Debug/composer.json b/src/Symfony/Component/Debug/composer.json
index 45799e2e60f6..7fd5ff9c93ab 100644
--- a/src/Symfony/Component/Debug/composer.json
+++ b/src/Symfony/Component/Debug/composer.json
@@ -34,7 +34,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
index 2cc1a4972593..470331d9b7ce 100644
--- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md
+++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+4.3.0
+-----
+
+ * added `%env(default:...)%` processor to fallback to a default value
+
4.2.0
-----
diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php
index fe23e8d78a13..abf2d0c192ce 100644
--- a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php
+++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php
@@ -43,6 +43,7 @@ public static function getProvidedTypes()
'json' => 'array',
'key' => 'bool|int|float|string|array',
'resolve' => 'string',
+ 'default' => 'bool|int|float|string|array',
'string' => 'string',
);
}
@@ -56,7 +57,7 @@ public function getEnv($prefix, $name, \Closure $getEnv)
if ('key' === $prefix) {
if (false === $i) {
- throw new RuntimeException(sprintf('Invalid configuration: env var "key:%s" does not contain a key specifier.', $name));
+ throw new RuntimeException(sprintf('Invalid env "key:%s": a key specifier should be provided.', $name));
}
$next = substr($name, $i + 1);
@@ -66,19 +67,39 @@ public function getEnv($prefix, $name, \Closure $getEnv)
if (!\is_array($array)) {
throw new RuntimeException(sprintf('Resolved value of "%s" did not result in an array value.', $next));
}
- if (!array_key_exists($key, $array)) {
- throw new RuntimeException(sprintf('Key "%s" not found in "%s" (resolved from "%s")', $key, json_encode($array), $next));
+
+ if (!isset($array[$key]) && !array_key_exists($key, $array)) {
+ throw new EnvNotFoundException(sprintf('Key "%s" not found in "%s" (resolved from "%s").', $key, json_encode($array), $next));
}
return $array[$key];
}
+ if ('default' === $prefix) {
+ if (false === $i) {
+ throw new RuntimeException(sprintf('Invalid env "default:%s": a fallback parameter should be provided.', $name));
+ }
+
+ $next = substr($name, $i + 1);
+ $default = substr($name, 0, $i);
+
+ if (!$this->container->hasParameter($default)) {
+ throw new RuntimeException(sprintf('Invalid env fallback in "default:%s": parameter "%s" not found.', $name, $default));
+ }
+
+ try {
+ return $getEnv($next);
+ } catch (EnvNotFoundException $e) {
+ return $this->container->getParameter($default);
+ }
+ }
+
if ('file' === $prefix) {
if (!is_scalar($file = $getEnv($name))) {
throw new RuntimeException(sprintf('Invalid file name: env var "%s" is non-scalar.', $name));
}
if (!file_exists($file)) {
- throw new RuntimeException(sprintf('Env "file:%s" not found: %s does not exist.', $name, $file));
+ throw new EnvNotFoundException(sprintf('File "%s" not found (resolved from "%s").', $file, $name));
}
return file_get_contents($file);
@@ -94,7 +115,7 @@ public function getEnv($prefix, $name, \Closure $getEnv)
$env = $_SERVER[$name];
} elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues
if (!$this->container->hasParameter("env($name)")) {
- throw new EnvNotFoundException($name);
+ throw new EnvNotFoundException(sprintf('Environment variable not found: "%s".', $name));
}
if (null === $env = $this->container->getParameter("env($name)")) {
diff --git a/src/Symfony/Component/DependencyInjection/Exception/EnvNotFoundException.php b/src/Symfony/Component/DependencyInjection/Exception/EnvNotFoundException.php
index 6ed18e06807f..04ac84800abc 100644
--- a/src/Symfony/Component/DependencyInjection/Exception/EnvNotFoundException.php
+++ b/src/Symfony/Component/DependencyInjection/Exception/EnvNotFoundException.php
@@ -18,8 +18,4 @@
*/
class EnvNotFoundException extends InvalidArgumentException
{
- public function __construct(string $name)
- {
- parent::__construct(sprintf('Environment variable not found: "%s".', $name));
- }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php
index 4681092ca784..93d3c16ff94d 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php
@@ -40,6 +40,7 @@ public function testSimpleProcessor()
'json' => array('array'),
'key' => array('bool', 'int', 'float', 'string', 'array'),
'resolve' => array('string'),
+ 'default' => array('bool', 'int', 'float', 'string', 'array'),
'string' => array('string'),
);
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
index 0638f90417df..c544015d9016 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php
@@ -211,6 +211,38 @@ public function testEmptyEnvWhichCannotBeEmptyForScalarNode(): void
$this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig()));
}
+ /**
+ * NOT LEGACY (test exception in 5.0).
+ *
+ * @group legacy
+ * @expectedDeprecation Setting path "env_extension.scalar_node_not_empty_validated" to an environment variable is deprecated since Symfony 4.3. Remove "cannotBeEmpty()", "validate()" or include a prefix/suffix value instead.
+ */
+ public function testEmptyEnvWhichCannotBeEmptyForScalarNodeWithValidation(): void
+ {
+ $container = new ContainerBuilder();
+ $container->registerExtension($ext = new EnvExtension());
+ $container->prependExtensionConfig('env_extension', $expected = array(
+ 'scalar_node_not_empty_validated' => '%env(SOME)%',
+ ));
+
+ $this->doProcess($container);
+
+ $this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig()));
+ }
+
+ public function testPartialEnvWhichCannotBeEmptyForScalarNode(): void
+ {
+ $container = new ContainerBuilder();
+ $container->registerExtension($ext = new EnvExtension());
+ $container->prependExtensionConfig('env_extension', $expected = array(
+ 'scalar_node_not_empty_validated' => 'foo %env(SOME)% bar',
+ ));
+
+ $this->doProcess($container);
+
+ $this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig()));
+ }
+
public function testEnvWithVariableNode(): void
{
$container = new ContainerBuilder();
@@ -282,6 +314,14 @@ public function getConfigTreeBuilder()
->children()
->scalarNode('scalar_node')->end()
->scalarNode('scalar_node_not_empty')->cannotBeEmpty()->end()
+ ->scalarNode('scalar_node_not_empty_validated')
+ ->cannotBeEmpty()
+ ->validate()
+ ->always(function ($value) {
+ return $value;
+ })
+ ->end()
+ ->end()
->integerNode('int_node')->end()
->floatNode('float_node')->end()
->booleanNode('bool_node')->end()
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
index cb41a6d33fb3..2063c25910c8 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
@@ -439,6 +439,28 @@ public function testDumpedCsvEnvParameters()
$this->assertSame(array('foo', 'bar'), $container->getParameter('hello'));
}
+ public function testDumpedDefaultEnvParameters()
+ {
+ $container = new ContainerBuilder();
+ $container->setParameter('fallback_param', 'baz');
+ $container->setParameter('fallback_env', '%env(foobar)%');
+ $container->setParameter('env(foobar)', 'foobaz');
+ $container->setParameter('env(foo)', '{"foo": "bar"}');
+ $container->setParameter('hello', '%env(default:fallback_param:bar)%');
+ $container->setParameter('hello-bar', '%env(default:fallback_env:key:baz:json:foo)%');
+ $container->compile();
+
+ $dumper = new PhpDumper($container);
+ $dumper->dump();
+
+ $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_default_env.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_DefaultParameters')));
+
+ require self::$fixturesPath.'/php/services_default_env.php';
+ $container = new \Symfony_DI_PhpDumper_Test_DefaultParameters();
+ $this->assertSame('baz', $container->getParameter('hello'));
+ $this->assertSame('foobaz', $container->getParameter('hello-bar'));
+ }
+
public function testDumpedJsonEnvParameters()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php b/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php
index 5cd3a68b21ba..b244537354e4 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php
@@ -317,7 +317,7 @@ public function testGetEnvUnknown()
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
- * @expectedExceptionMessage Invalid configuration: env var "key:foo" does not contain a key specifier.
+ * @expectedExceptionMessage Invalid env "key:foo": a key specifier should be provided.
*/
public function testGetEnvKeyInvalidKey()
{
@@ -355,7 +355,7 @@ public function noArrayValues()
}
/**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\EnvNotFoundException
* @expectedExceptionMessage Key "index" not found in
* @dataProvider invalidArrayValues
*/
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_default_env.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_default_env.php
new file mode 100644
index 000000000000..c9bdb62d75f1
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_default_env.php
@@ -0,0 +1,130 @@
+parameters = $this->getDefaultParameters();
+
+ $this->services = $this->privates = array();
+
+ $this->aliases = array();
+ }
+
+ public function compile()
+ {
+ throw new LogicException('You cannot compile a dumped container that was already compiled.');
+ }
+
+ public function isCompiled()
+ {
+ return true;
+ }
+
+ public function getRemovedIds()
+ {
+ return array(
+ 'Psr\\Container\\ContainerInterface' => true,
+ 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
+ );
+ }
+
+ public function getParameter($name)
+ {
+ $name = (string) $name;
+
+ if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) {
+ throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
+ }
+ if (isset($this->loadedDynamicParameters[$name])) {
+ return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
+ }
+
+ return $this->parameters[$name];
+ }
+
+ public function hasParameter($name)
+ {
+ $name = (string) $name;
+
+ return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
+ }
+
+ public function setParameter($name, $value)
+ {
+ throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
+ }
+
+ public function getParameterBag()
+ {
+ if (null === $this->parameterBag) {
+ $parameters = $this->parameters;
+ foreach ($this->loadedDynamicParameters as $name => $loaded) {
+ $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
+ }
+ $this->parameterBag = new FrozenParameterBag($parameters);
+ }
+
+ return $this->parameterBag;
+ }
+
+ private $loadedDynamicParameters = array(
+ 'fallback_env' => false,
+ 'hello' => false,
+ 'hello-bar' => false,
+ );
+ private $dynamicParameters = array();
+
+ /**
+ * Computes a dynamic parameter.
+ *
+ * @param string $name The name of the dynamic parameter to load
+ *
+ * @return mixed The value of the dynamic parameter
+ *
+ * @throws InvalidArgumentException When the dynamic parameter does not exist
+ */
+ private function getDynamicParameter($name)
+ {
+ switch ($name) {
+ case 'fallback_env': $value = $this->getEnv('foobar'); break;
+ case 'hello': $value = $this->getEnv('default:fallback_param:bar'); break;
+ case 'hello-bar': $value = $this->getEnv('default:fallback_env:key:baz:json:foo'); break;
+ default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
+ }
+ $this->loadedDynamicParameters[$name] = true;
+
+ return $this->dynamicParameters[$name] = $value;
+ }
+
+ /**
+ * Gets the default parameters.
+ *
+ * @return array An array of the default parameters
+ */
+ protected function getDefaultParameters()
+ {
+ return array(
+ 'fallback_param' => 'baz',
+ 'env(foobar)' => 'foobaz',
+ 'env(foo)' => '{"foo": "bar"}',
+ );
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json
index 32f52797e434..4acf55465075 100644
--- a/src/Symfony/Component/DependencyInjection/composer.json
+++ b/src/Symfony/Component/DependencyInjection/composer.json
@@ -22,7 +22,7 @@
},
"require-dev": {
"symfony/yaml": "~3.4|~4.0",
- "symfony/config": "~4.2",
+ "symfony/config": "^4.3",
"symfony/expression-language": "~3.4|~4.0"
},
"suggest": {
@@ -33,7 +33,7 @@
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them"
},
"conflict": {
- "symfony/config": "<4.2",
+ "symfony/config": "<4.3",
"symfony/finder": "<3.4",
"symfony/proxy-manager-bridge": "<3.4",
"symfony/yaml": "<3.4"
@@ -51,7 +51,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/DomCrawler/CHANGELOG.md b/src/Symfony/Component/DomCrawler/CHANGELOG.md
index dc773be06d65..3accde4bf573 100644
--- a/src/Symfony/Component/DomCrawler/CHANGELOG.md
+++ b/src/Symfony/Component/DomCrawler/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+4.3.0
+-----
+
+* Added return of element name (`_name`) in `extract()` method.
+
4.2.0
-----
diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php
index 455e030955ea..a70c6466e068 100644
--- a/src/Symfony/Component/DomCrawler/Crawler.php
+++ b/src/Symfony/Component/DomCrawler/Crawler.php
@@ -658,6 +658,8 @@ public function extract($attributes)
foreach ($attributes as $attribute) {
if ('_text' === $attribute) {
$elements[] = $node->nodeValue;
+ } elseif ('_name' === $attribute) {
+ $elements[] = $node->nodeName;
} else {
$elements[] = $node->getAttribute($attribute);
}
diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
index 9e73eaae1d9c..254b1ba7f320 100644
--- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
+++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php
@@ -416,6 +416,8 @@ public function testExtract()
$this->assertEquals(array(array(), array(), array()), $crawler->extract(array()), '->extract() returns empty arrays if the attribute list is empty');
$this->assertEquals(array(), $this->createTestCrawler()->filterXPath('//ol')->extract('_text'), '->extract() returns an empty array if the node list is empty');
+
+ $this->assertEquals(array(array('One', 'li'), array('Two', 'li'), array('Three', 'li')), $crawler->extract(array('_text', '_name')), '->extract() returns an array of extracted data from the node list');
}
public function testFilterXpathComplexQueries()
diff --git a/src/Symfony/Component/DomCrawler/composer.json b/src/Symfony/Component/DomCrawler/composer.json
index 167d0fdfe50c..b3173484c1e7 100644
--- a/src/Symfony/Component/DomCrawler/composer.json
+++ b/src/Symfony/Component/DomCrawler/composer.json
@@ -35,7 +35,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Dotenv/composer.json b/src/Symfony/Component/Dotenv/composer.json
index 6590da03e516..872ff3a4c5be 100644
--- a/src/Symfony/Component/Dotenv/composer.json
+++ b/src/Symfony/Component/Dotenv/composer.json
@@ -30,7 +30,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json
index 6c75dfbb0052..6cdc762bc301 100644
--- a/src/Symfony/Component/EventDispatcher/composer.json
+++ b/src/Symfony/Component/EventDispatcher/composer.json
@@ -42,7 +42,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/ExpressionLanguage/composer.json b/src/Symfony/Component/ExpressionLanguage/composer.json
index 2e699629e8eb..66581371f907 100644
--- a/src/Symfony/Component/ExpressionLanguage/composer.json
+++ b/src/Symfony/Component/ExpressionLanguage/composer.json
@@ -29,7 +29,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Filesystem/composer.json b/src/Symfony/Component/Filesystem/composer.json
index ee8a319a7d1c..d13397b42410 100644
--- a/src/Symfony/Component/Filesystem/composer.json
+++ b/src/Symfony/Component/Filesystem/composer.json
@@ -28,7 +28,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Finder/composer.json b/src/Symfony/Component/Finder/composer.json
index 37d34a5e51d7..05d5d1bb9e9f 100644
--- a/src/Symfony/Component/Finder/composer.json
+++ b/src/Symfony/Component/Finder/composer.json
@@ -27,7 +27,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json
index 49448badc8db..4f72f19e8e5b 100644
--- a/src/Symfony/Component/Form/composer.json
+++ b/src/Symfony/Component/Form/composer.json
@@ -60,7 +60,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json
index 76381a7c46a0..49ab5c64275c 100644
--- a/src/Symfony/Component/HttpFoundation/composer.json
+++ b/src/Symfony/Component/HttpFoundation/composer.json
@@ -32,7 +32,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index 380647b50c13..c5aea60154b1 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -73,15 +73,15 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private $requestStackSize = 0;
private $resetServices = false;
- const VERSION = '4.2.1-DEV';
- const VERSION_ID = 40201;
+ const VERSION = '4.3.0-DEV';
+ const VERSION_ID = 40300;
const MAJOR_VERSION = 4;
- const MINOR_VERSION = 2;
- const RELEASE_VERSION = 1;
+ const MINOR_VERSION = 3;
+ const RELEASE_VERSION = 0;
const EXTRA_VERSION = 'DEV';
- const END_OF_MAINTENANCE = '07/2019';
- const END_OF_LIFE = '01/2020';
+ const END_OF_MAINTENANCE = '01/2020';
+ const END_OF_LIFE = '07/2020';
public function __construct(string $environment, bool $debug)
{
diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json
index 1e5684d57990..a27f34c2f133 100644
--- a/src/Symfony/Component/HttpKernel/composer.json
+++ b/src/Symfony/Component/HttpKernel/composer.json
@@ -67,7 +67,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Inflector/composer.json b/src/Symfony/Component/Inflector/composer.json
index b4312cd037df..2a4e29695d85 100644
--- a/src/Symfony/Component/Inflector/composer.json
+++ b/src/Symfony/Component/Inflector/composer.json
@@ -35,7 +35,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Intl/composer.json b/src/Symfony/Component/Intl/composer.json
index b0f3e3b6d53c..64a2ebf1a64d 100644
--- a/src/Symfony/Component/Intl/composer.json
+++ b/src/Symfony/Component/Intl/composer.json
@@ -43,7 +43,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Ldap/composer.json b/src/Symfony/Component/Ldap/composer.json
index 77c3d773ce5d..e8fb2720f4d1 100644
--- a/src/Symfony/Component/Ldap/composer.json
+++ b/src/Symfony/Component/Ldap/composer.json
@@ -32,7 +32,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Lock/composer.json b/src/Symfony/Component/Lock/composer.json
index 22704c6e5c36..7c5fa0acd599 100644
--- a/src/Symfony/Component/Lock/composer.json
+++ b/src/Symfony/Component/Lock/composer.json
@@ -32,7 +32,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Messenger/composer.json b/src/Symfony/Component/Messenger/composer.json
index 077a5feb0808..f828b6445194 100644
--- a/src/Symfony/Component/Messenger/composer.json
+++ b/src/Symfony/Component/Messenger/composer.json
@@ -42,7 +42,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/OptionsResolver/composer.json b/src/Symfony/Component/OptionsResolver/composer.json
index 1c819495bf89..6753856f56b0 100644
--- a/src/Symfony/Component/OptionsResolver/composer.json
+++ b/src/Symfony/Component/OptionsResolver/composer.json
@@ -27,7 +27,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Process/composer.json b/src/Symfony/Component/Process/composer.json
index 44bad06b597b..d3efd0238207 100644
--- a/src/Symfony/Component/Process/composer.json
+++ b/src/Symfony/Component/Process/composer.json
@@ -27,7 +27,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/PropertyAccess/composer.json b/src/Symfony/Component/PropertyAccess/composer.json
index 33f9b188d0d1..bd81e5c260cc 100644
--- a/src/Symfony/Component/PropertyAccess/composer.json
+++ b/src/Symfony/Component/PropertyAccess/composer.json
@@ -34,7 +34,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json
index 357b05da9369..bfa0fd3eccac 100644
--- a/src/Symfony/Component/PropertyInfo/composer.json
+++ b/src/Symfony/Component/PropertyInfo/composer.json
@@ -53,7 +53,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Routing/composer.json b/src/Symfony/Component/Routing/composer.json
index be489ee98326..11fd7ee68cda 100644
--- a/src/Symfony/Component/Routing/composer.json
+++ b/src/Symfony/Component/Routing/composer.json
@@ -49,7 +49,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Security/Core/composer.json b/src/Symfony/Component/Security/Core/composer.json
index 4df719003045..f4128c65c2bc 100644
--- a/src/Symfony/Component/Security/Core/composer.json
+++ b/src/Symfony/Component/Security/Core/composer.json
@@ -45,7 +45,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Security/Csrf/composer.json b/src/Symfony/Component/Security/Csrf/composer.json
index cdc19ade22f1..716951f95bdf 100644
--- a/src/Symfony/Component/Security/Csrf/composer.json
+++ b/src/Symfony/Component/Security/Csrf/composer.json
@@ -37,7 +37,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Security/Guard/composer.json b/src/Symfony/Component/Security/Guard/composer.json
index 982b16f012a3..44adaa6e11e8 100644
--- a/src/Symfony/Component/Security/Guard/composer.json
+++ b/src/Symfony/Component/Security/Guard/composer.json
@@ -32,7 +32,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json
index ef81706f2a5f..7047eba06e9e 100644
--- a/src/Symfony/Component/Security/Http/composer.json
+++ b/src/Symfony/Component/Security/Http/composer.json
@@ -44,7 +44,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json
index 6cf567f2b01f..80e62d923a56 100644
--- a/src/Symfony/Component/Security/composer.json
+++ b/src/Symfony/Component/Security/composer.json
@@ -59,7 +59,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json
index 52961bb7c052..9e86c07e73c3 100644
--- a/src/Symfony/Component/Serializer/composer.json
+++ b/src/Symfony/Component/Serializer/composer.json
@@ -58,7 +58,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Stopwatch/composer.json b/src/Symfony/Component/Stopwatch/composer.json
index 356b1fec17d4..2ac6e03e29c2 100644
--- a/src/Symfony/Component/Stopwatch/composer.json
+++ b/src/Symfony/Component/Stopwatch/composer.json
@@ -28,7 +28,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Templating/composer.json b/src/Symfony/Component/Templating/composer.json
index 9e56b0247cc8..f6474495d568 100644
--- a/src/Symfony/Component/Templating/composer.json
+++ b/src/Symfony/Component/Templating/composer.json
@@ -34,7 +34,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Translation/composer.json b/src/Symfony/Component/Translation/composer.json
index 7d5df7302530..51be0d60bd0e 100644
--- a/src/Symfony/Component/Translation/composer.json
+++ b/src/Symfony/Component/Translation/composer.json
@@ -51,7 +51,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "4.3-dev"
}
}
}
diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md
index 3863b5717a1f..e2dfc921e40b 100644
--- a/src/Symfony/Component/Validator/CHANGELOG.md
+++ b/src/Symfony/Component/Validator/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+4.3.0
+-----
+
+ * added options `iban` and `ibanPropertyPath` to Bic constraint
+
4.2.0
-----
diff --git a/src/Symfony/Component/Validator/Constraints/Bic.php b/src/Symfony/Component/Validator/Constraints/Bic.php
index 9af23c8ddb89..2e1fa68df123 100644
--- a/src/Symfony/Component/Validator/Constraints/Bic.php
+++ b/src/Symfony/Component/Validator/Constraints/Bic.php
@@ -12,7 +12,9 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Intl\Intl;
+use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\LogicException;
/**
@@ -28,6 +30,7 @@ class Bic extends Constraint
const INVALID_BANK_CODE_ERROR = '00559357-6170-4f29-aebd-d19330aa19cf';
const INVALID_COUNTRY_CODE_ERROR = '1ce76f8d-3c1f-451c-9e62-fe9c3ed486ae';
const INVALID_CASE_ERROR = '11884038-3312-4ae5-9d04-699f782130c7';
+ const INVALID_IBAN_COUNTRY_CODE_ERROR = '29a2c3bb-587b-4996-b6f5-53081364cea5';
protected static $errorNames = array(
self::INVALID_LENGTH_ERROR => 'INVALID_LENGTH_ERROR',
@@ -38,6 +41,9 @@ class Bic extends Constraint
);
public $message = 'This is not a valid Business Identifier Code (BIC).';
+ public $ibanMessage = 'This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.';
+ public $iban;
+ public $ibanPropertyPath;
public function __construct($options = null)
{
@@ -46,6 +52,14 @@ public function __construct($options = null)
@trigger_error(sprintf('Using the "%s" constraint without the "symfony/intl" component installed is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED);
}
+ if (isset($options['iban']) && isset($options['ibanPropertyPath'])) {
+ throw new ConstraintDefinitionException(sprintf('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time.', self::class));
+ }
+
+ if (isset($options['ibanPropertyPath']) && !class_exists(PropertyAccess::class)) {
+ throw new LogicException(sprintf('The "symfony/property-access" component is required to use the "%s" constraint with the "ibanPropertyPath" option.', self::class));
+ }
+
parent::__construct($options);
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/BicValidator.php b/src/Symfony/Component/Validator/Constraints/BicValidator.php
index a34ffa038bf5..23c33c812e42 100644
--- a/src/Symfony/Component/Validator/Constraints/BicValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/BicValidator.php
@@ -12,8 +12,12 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Intl\Intl;
+use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\LogicException;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;
@@ -25,6 +29,13 @@
*/
class BicValidator extends ConstraintValidator
{
+ private $propertyAccessor;
+
+ public function __construct(PropertyAccessor $propertyAccessor = null)
+ {
+ $this->propertyAccessor = $propertyAccessor;
+ }
+
/**
* {@inheritdoc}
*/
@@ -100,5 +111,39 @@ public function validate($value, Constraint $constraint)
return;
}
+
+ // check against an IBAN
+ $iban = $constraint->iban;
+ $path = $constraint->ibanPropertyPath;
+ if ($path && null !== $object = $this->context->getObject()) {
+ try {
+ $iban = $this->getPropertyAccessor()->getValue($object, $path);
+ } catch (NoSuchPropertyException $e) {
+ throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s', $path, \get_class($constraint), $e->getMessage()), 0, $e);
+ }
+ }
+ if (!$iban) {
+ return;
+ }
+ $ibanCountryCode = substr($iban, 0, 2);
+ if (ctype_alpha($ibanCountryCode) && substr($canonicalize, 4, 2) !== $ibanCountryCode) {
+ $this->context->buildViolation($constraint->ibanMessage)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setParameter('{{ iban }}', $iban)
+ ->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
+ ->addViolation();
+ }
+ }
+
+ private function getPropertyAccessor(): PropertyAccessor
+ {
+ if (null === $this->propertyAccessor) {
+ if (!class_exists(PropertyAccess::class)) {
+ throw new LogicException('Unable to use property path as the Symfony PropertyAccess component is not installed.');
+ }
+ $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ return $this->propertyAccessor;
}
}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
index 4bb2760b418e..30e6804c7b83 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
@@ -326,6 +326,10 @@