From 7ed6d35f2cbd21ee5b6ec019787a664003097ced Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 17 Nov 2019 15:29:13 +0100 Subject: [PATCH 01/16] bumped Symfony version to 4.4.0 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 4b1ee5ea0aaed..47f0b49b58d8d 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '4.4.0-RC1'; + const VERSION = '4.4.0-DEV'; const VERSION_ID = 40400; const MAJOR_VERSION = 4; const MINOR_VERSION = 4; const RELEASE_VERSION = 0; - const EXTRA_VERSION = 'RC1'; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2022'; const END_OF_LIFE = '11/2023'; From 7b7f9667119a7de82cc9d2c8a828d4d479929697 Mon Sep 17 00:00:00 2001 From: Nardberjean Date: Sun, 17 Nov 2019 11:11:27 -0500 Subject: [PATCH 02/16] Update HttpKernel.php --- src/Symfony/Component/HttpKernel/HttpKernel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/HttpKernel.php b/src/Symfony/Component/HttpKernel/HttpKernel.php index bca2cd1688e8e..9769d5e802b2d 100644 --- a/src/Symfony/Component/HttpKernel/HttpKernel.php +++ b/src/Symfony/Component/HttpKernel/HttpKernel.php @@ -62,7 +62,7 @@ public function __construct(EventDispatcherInterface $dispatcher, ControllerReso */ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { - $request->headers->set('X-Php-Ob-Level', ob_get_level()); + $request->headers->set('X-Php-Ob-Level', (string) ob_get_level()); try { return $this->handleRaw($request, $type); From c194fffaef3d5df57186117c96f8e99aed82fbbe Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 17 Nov 2019 22:18:02 +0100 Subject: [PATCH 03/16] Adjust pull request template for 5.0 branchout --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b863dea0cbf9a..4d7b45b66b560 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ | Q | A | ------------- | --- -| Branch? | 4.4 for features / 3.4 or 4.3 for bug fixes +| Branch? | master for features / 3.4, 4.3, 4.4 or 5.0 for bug fixes | Bug fix? | yes/no | New feature? | yes/no | Deprecations? | yes/no From 934e05c00b89cba6171eeeb19f93e68f43f8352a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 17 Nov 2019 22:52:25 +0100 Subject: [PATCH 04/16] Fix PR template --- .github/PULL_REQUEST_TEMPLATE.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4d7b45b66b560..0d234d8fe9b7f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,6 +16,5 @@ Additionally (see https://symfony.com/roadmap): - Never break backward compatibility (see https://symfony.com/bc). - Bug fixes must be submitted against the lowest maintained branch where they apply (lowest branches are regularly merged to upper ones so they get the fixes too.) - - Features and deprecations must be submitted against branch 4.4. - - Legacy code removals go to the master branch. + - Features and deprecations must be submitted against branch master. --> From e7d0787a4dfe68c33c81f09aa8fb59fe67ea90dc Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 17 Nov 2019 16:24:49 +0100 Subject: [PATCH 05/16] [Finder] Fixed docs --- src/Symfony/Component/Finder/Finder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index c8f642d872ce3..d2ea17d87a00f 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -736,7 +736,7 @@ private function searchInDirectory($dir) /** * Normalizes given directory names by removing trailing slashes. * - * Excluding: (s)ftp:// wrapper + * Excluding: (s)ftp:// or ssh2.(s)ftp:// wrapper * * @param string $dir * From 4132a6039264fc990879dabfcfb68d4dac68e984 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sun, 17 Nov 2019 23:40:05 +0100 Subject: [PATCH 06/16] [Security] Fix best encoder not wired using migrate_from --- .../Component/Security/Core/Encoder/EncoderFactory.php | 4 +++- .../Security/Core/Tests/Encoder/EncoderFactoryTest.php | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php b/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php index a58442769bde0..4bc9596ce3f8c 100644 --- a/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php +++ b/src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php @@ -114,7 +114,9 @@ private function getEncoderConfigFromAlgorithm(array $config): array } if ($fromEncoders = ($config['migrate_from'] ?? false)) { - $encoderChain = []; + unset($config['migrate_from']); + $encoderChain = [$this->createEncoder($config, true)]; + foreach ($fromEncoders as $name) { if ($encoder = $this->encoders[$name] ?? false) { $encoder = $encoder instanceof PasswordEncoderInterface ? $encoder : $this->createEncoder($encoder, true); diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php index c8d73d5b15841..a25f23528708e 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/EncoderFactoryTest.php @@ -143,9 +143,7 @@ public function testMigrateFrom() $factory = new EncoderFactory([ 'digest_encoder' => $digest = new MessageDigestPasswordEncoder('sha256'), - 'pbdkf2' => $digest = new MessageDigestPasswordEncoder('sha256'), - 'bcrypt_encoder' => ['algorithm' => 'bcrypt'], - SomeUser::class => ['algorithm' => 'sodium', 'migrate_from' => ['bcrypt_encoder', 'digest_encoder']], + SomeUser::class => ['algorithm' => 'sodium', 'migrate_from' => ['bcrypt', 'digest_encoder']], ]); $encoder = $factory->getEncoder(SomeUser::class); @@ -154,6 +152,7 @@ public function testMigrateFrom() $this->assertTrue($encoder->isPasswordValid((new SodiumPasswordEncoder())->encodePassword('foo', null), 'foo', null)); $this->assertTrue($encoder->isPasswordValid((new NativePasswordEncoder(null, null, null, \PASSWORD_BCRYPT))->encodePassword('foo', null), 'foo', null)); $this->assertTrue($encoder->isPasswordValid($digest->encodePassword('foo', null), 'foo', null)); + $this->assertStringStartsWith(SODIUM_CRYPTO_PWHASH_STRPREFIX, $encoder->encodePassword('foo', null)); } public function testDefaultMigratingEncoders() From 754fbe41fb2ed8335236d5cd42fe42a4fe0a651f Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 17 Nov 2019 22:49:13 +0000 Subject: [PATCH 07/16] Removed extra whitespace --- .../Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php index 68a9d6bb14dc6..84cb9da42413f 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php +++ b/src/Symfony/Component/ErrorHandler/ErrorRenderer/HtmlErrorRenderer.php @@ -52,7 +52,7 @@ public function __construct(bool $debug = false, string $charset = null, $fileLi /** * {@inheritdoc} */ - public function render(\Throwable $exception): FlattenException + public function render(\Throwable $exception): FlattenException { $exception = FlattenException::createFromThrowable($exception, null, [ 'Content-Type' => 'text/html; charset='.$this->charset, From aab9b43d03b6c30cae12f1c594e813c1820f8c6f Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Mon, 18 Nov 2019 00:27:40 +0100 Subject: [PATCH 08/16] [HttpKernel] Make ErrorListener::onKernelException()'s dispatcher argument explicit --- .../Component/HttpKernel/EventListener/ErrorListener.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php index 77da3ce3e7a86..4d855b724e349 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php @@ -46,7 +46,7 @@ public function logKernelException(ExceptionEvent $event) $this->logException($event->getThrowable(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine())); } - public function onKernelException(ExceptionEvent $event) + public function onKernelException(ExceptionEvent $event, string $eventName = null, EventDispatcherInterface $eventDispatcher = null) { if (null === $this->controller) { return; @@ -54,7 +54,6 @@ public function onKernelException(ExceptionEvent $event) $exception = $event->getThrowable(); $request = $this->duplicateRequest($exception, $event->getRequest()); - $eventDispatcher = \func_num_args() > 2 ? func_get_arg(2) : null; try { $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false); From 8a460cefef67c8335f59ba299d859e31dc94123e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Mon, 18 Nov 2019 11:11:23 +0100 Subject: [PATCH 09/16] States that the HttpClient provides a Http Async implementation --- src/Symfony/Component/HttpClient/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/HttpClient/composer.json b/src/Symfony/Component/HttpClient/composer.json index d0722a70e2166..e734b21554df6 100644 --- a/src/Symfony/Component/HttpClient/composer.json +++ b/src/Symfony/Component/HttpClient/composer.json @@ -15,6 +15,7 @@ } ], "provide": { + "php-http/async-client-implementation": "*", "php-http/client-implementation": "*", "psr/http-client-implementation": "1.0", "symfony/http-client-implementation": "1.1" From d811b0e9b50bb628e3e30429b6a4c7a931f0d30b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 19 Nov 2019 08:54:33 +0100 Subject: [PATCH 10/16] allow button names to start with uppercase letter --- UPGRADE-4.3.md | 2 +- UPGRADE-5.0.md | 2 +- src/Symfony/Component/Form/ButtonBuilder.php | 2 +- src/Symfony/Component/Form/CHANGELOG.md | 2 +- src/Symfony/Component/Form/Tests/ButtonBuilderTest.php | 8 -------- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md index 86155031fa29e..e3a4ac469d056 100644 --- a/UPGRADE-4.3.md +++ b/UPGRADE-4.3.md @@ -96,7 +96,7 @@ Form ---- * Using the `format` option of `DateType` and `DateTimeType` when the `html5` option is enabled is deprecated. - * Using names for buttons that do not start with a lowercase letter, a digit, or an underscore is deprecated and will lead to an + * Using names for buttons that do not start with a letter, a digit, or an underscore is deprecated and will lead to an exception in 5.0. * Using names for buttons that do not contain only letters, digits, underscores, hyphens, and colons is deprecated and will lead to an exception in 5.0. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 455cd0d62ad09..302cea6dec969 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -110,7 +110,7 @@ Form ---- * Removed support for using the `format` option of `DateType` and `DateTimeType` when the `html5` option is enabled. - * Using names for buttons that do not start with a lowercase letter, a digit, or an underscore leads to an exception. + * Using names for buttons that do not start with a letter, a digit, or an underscore leads to an exception. * Using names for buttons that do not contain only letters, digits, underscores, hyphens, and colons leads to an exception. * Using the `date_format`, `date_widget`, and `time_widget` options of the `DateTimeType` when the `widget` option is diff --git a/src/Symfony/Component/Form/ButtonBuilder.php b/src/Symfony/Component/Form/ButtonBuilder.php index bf8e147838de1..ca6bf78dc9cb1 100644 --- a/src/Symfony/Component/Form/ButtonBuilder.php +++ b/src/Symfony/Component/Form/ButtonBuilder.php @@ -61,7 +61,7 @@ public function __construct(?string $name, array $options = []) $this->name = $name; $this->options = $options; - if (preg_match('/^([^a-z0-9_].*)?(.*[^a-zA-Z0-9_\-:].*)?$/D', $name, $matches)) { + if (preg_match('/^([^a-zA-Z0-9_].*)?(.*[^a-zA-Z0-9_\-:].*)?$/D', $name, $matches)) { if (isset($matches[1])) { @trigger_error(sprintf('Using names for buttons that do not start with a lowercase letter, a digit, or an underscore is deprecated since Symfony 4.3 and will throw an exception in 5.0 ("%s" given).', $name), E_USER_DEPRECATED); } diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index cf7b8cd8cc2d8..e41c46e907a89 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -6,7 +6,7 @@ CHANGELOG * added a `symbol` option to the `PercentType` that allows to disable or customize the output of the percent character * Using the `format` option of `DateType` and `DateTimeType` when the `html5` option is enabled is deprecated. - * Using names for buttons that do not start with a lowercase letter, a digit, or an underscore is deprecated and will lead to an + * Using names for buttons that do not start with a letter, a digit, or an underscore is deprecated and will lead to an exception in 5.0. * Using names for buttons that do not contain only letters, digits, underscores, hyphens, and colons is deprecated and will lead to an exception in 5.0. diff --git a/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php b/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php index 966b2927e9adb..7bd78896d1947 100644 --- a/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php +++ b/src/Symfony/Component/Form/Tests/ButtonBuilderTest.php @@ -47,14 +47,6 @@ public function testNameContainingIllegalCharacters() $this->assertInstanceOf('\Symfony\Component\Form\ButtonBuilder', new ButtonBuilder('button[]')); } - /** - * @group legacy - */ - public function testNameStartingWithIllegalCharacters() - { - $this->assertInstanceOf('\Symfony\Component\Form\ButtonBuilder', new ButtonBuilder('Button')); - } - public function getInvalidNames() { return [ From 60b0dae17434ed294c95b330567c3aba2bda5830 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Tue, 19 Nov 2019 11:37:15 +0100 Subject: [PATCH 11/16] [DependencyInjection] Fix dumping multiple deprecated aliases --- .../DependencyInjection/Dumper/PhpDumper.php | 2 +- .../Tests/Dumper/PhpDumperTest.php | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 48267b0d033df..5e2f7d2dd4378 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1226,7 +1226,7 @@ private function addDeprecatedAliases(): string $methodNameAlias = $this->generateMethodName($alias); $idExported = $this->export($id); $messageExported = $this->export($definition->getDeprecationMessage($alias)); - $code = <<docStar} * Gets the $public '$alias' alias. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index b78fcb32e4363..d0fb5ab8c6aa1 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1283,6 +1283,30 @@ public function testWither() $wither = $container->get('wither'); $this->assertInstanceOf(Foo::class, $wither->foo); } + + /** + * @group legacy + * @expectedDeprecation The "deprecated1" service alias is deprecated. You should stop using it, as it will be removed in the future. + * @expectedDeprecation The "deprecated2" service alias is deprecated. You should stop using it, as it will be removed in the future. + */ + public function testMultipleDeprecatedAliasesWorking() + { + $container = new ContainerBuilder(); + $container->setDefinition('bar', new Definition('stdClass'))->setPublic(true); + $container->setAlias('deprecated1', 'bar')->setPublic(true)->setDeprecated('%alias_id% is deprecated'); + $container->setAlias('deprecated2', 'bar')->setPublic(true)->setDeprecated('%alias_id% is deprecated'); + $container->compile(); + + $dumper = new PhpDumper($container); + $dump = $dumper->dump(['class' => $class = __FUNCTION__]); + + eval('?>'.$dump); + $container = new $class(); + + $this->assertInstanceOf(\stdClass::class, $container->get('bar')); + $this->assertInstanceOf(\stdClass::class, $container->get('deprecated1')); + $this->assertInstanceOf(\stdClass::class, $container->get('deprecated2')); + } } class Rot13EnvVarProcessor implements EnvVarProcessorInterface From 8d84ac34a5c1f650c337924e260dcf397f816111 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 18 Nov 2019 08:44:14 +0100 Subject: [PATCH 12/16] Remove wrong @group legacy annotations --- .../Tests/DependencyInjection/ConfigurationTest.php | 2 -- .../Tests/DependencyInjection/WebProfilerExtensionTest.php | 2 -- src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php | 3 --- src/Symfony/Component/Routing/Loader/ObjectLoader.php | 2 +- .../Component/Routing/Tests/Loader/ObjectLoaderTest.php | 5 +---- .../Provider/DaoAuthenticationProviderTest.php | 3 --- .../Provider/UserAuthenticationProviderTest.php | 3 --- .../Security/Http/Tests/Firewall/ExceptionListenerTest.php | 3 --- .../Security/Http/Tests/Firewall/LogoutListenerTest.php | 3 --- .../Http/Tests/RememberMe/AbstractRememberMeServicesTest.php | 3 --- src/Symfony/Component/Workflow/Tests/WorkflowTest.php | 3 --- 11 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php index 06aa85aee360a..a0bc7f43c0668 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -60,8 +60,6 @@ public function getDebugModes() } /** - * @group legacy - * * @dataProvider getInterceptRedirectsConfiguration */ public function testConfigTreeUsingInterceptRedirects(bool $interceptRedirects, array $expectedResult) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php index b94ef8045b684..6c6fc7f0b470d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/WebProfilerExtensionTest.php @@ -142,8 +142,6 @@ public function getToolbarConfig() } /** - * @group legacy - * * @dataProvider getInterceptRedirectsToolbarConfig */ public function testToolbarConfigUsingInterceptRedirects( diff --git a/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php b/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php index 46dcee216267d..be03734dc4261 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Bundle/BundleTest.php @@ -28,9 +28,6 @@ public function testGetContainerExtension() ); } - /** - * @group legacy - */ public function testGetContainerExtensionWithInvalidClass() { $this->expectException('LogicException'); diff --git a/src/Symfony/Component/Routing/Loader/ObjectLoader.php b/src/Symfony/Component/Routing/Loader/ObjectLoader.php index e7d9efa1eb325..c391ad6648aa8 100644 --- a/src/Symfony/Component/Routing/Loader/ObjectLoader.php +++ b/src/Symfony/Component/Routing/Loader/ObjectLoader.php @@ -52,7 +52,7 @@ public function load($resource, $type = null) $loaderObject = $this->getObject($parts[0]); if (!\is_object($loaderObject)) { - throw new \LogicException(sprintf('%s:getObject() must return an object: %s returned', \get_class($this), \gettype($loaderObject))); + throw new \TypeError(sprintf('%s:getObject() must return an object: %s returned', \get_class($this), \gettype($loaderObject))); } if (!\is_callable([$loaderObject, $method])) { diff --git a/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php index cec1fa422cb22..2a7f21bd16c03 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/ObjectLoaderTest.php @@ -62,12 +62,9 @@ public function getBadResourceStrings() ]; } - /** - * @group legacy - */ public function testExceptionOnNoObjectReturned() { - $this->expectException('LogicException'); + $this->expectException(\TypeError::class); $loader = new TestObjectLoader(); $loader->loaderMap = ['my_service' => 'NOT_AN_OBJECT']; $loader->load('my_service::method'); diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php index 342db15095bdc..0981b13c8f013 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php @@ -22,9 +22,6 @@ class DaoAuthenticationProviderTest extends TestCase { - /** - * @group legacy - */ public function testRetrieveUserWhenProviderDoesNotReturnAnUserInterface() { $this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationServiceException'); diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php index 5a42b3290f6dd..8ec92d5014da9 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php @@ -62,9 +62,6 @@ public function testAuthenticateWhenUsernameIsNotFoundAndHideIsTrue() $provider->authenticate($this->getSupportedToken()); } - /** - * @group legacy - */ public function testAuthenticateWhenProviderDoesNotReturnAnUserInterface() { $this->expectException('Symfony\Component\Security\Core\Exception\AuthenticationServiceException'); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php index fb1db914286fb..2715c9404d5b6 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php @@ -72,9 +72,6 @@ public function getAuthenticationExceptionProvider() ]; } - /** - * @group legacy - */ public function testExceptionWhenEntryPointReturnsBadValue() { $event = $this->createEvent(new AuthenticationException()); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php index 5eed09392802e..3d51a26196a76 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/LogoutListenerTest.php @@ -123,9 +123,6 @@ public function testHandleMatchedPathWithoutSuccessHandlerAndCsrfValidation() $listener($event); } - /** - * @group legacy - */ public function testSuccessHandlerReturnsNonResponse() { $this->expectException('RuntimeException'); diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php index 8dc2042f12c09..c476e65403c2e 100644 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php +++ b/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php @@ -39,9 +39,6 @@ public function testAutoLoginReturnsNullWhenNoCookie() $this->assertNull($service->autoLogin(new Request())); } - /** - * @group legacy - */ public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnUserInterface() { $this->expectException('RuntimeException'); diff --git a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php index 84d02a970d5d3..54b26421f7451 100644 --- a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php +++ b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php @@ -20,9 +20,6 @@ class WorkflowTest extends TestCase { use WorkflowBuilderTrait; - /** - * @group legacy - */ public function testGetMarkingWithInvalidStoreReturn() { $this->expectException('Symfony\Component\Workflow\Exception\LogicException'); From d15f77f33e5bf9cdbd91d2325c30d5327b28901f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 20 Nov 2019 13:50:43 +0100 Subject: [PATCH 13/16] [Form] group constraints when calling the validator --- .../Validator/Constraints/FormValidator.php | 8 +++++++- .../Validator/Constraints/FormValidatorTest.php | 12 +++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 01488217c8ea6..747273f88f078 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -76,6 +76,8 @@ public function validate($form, Constraint $formConstraint) } } } else { + $groupedConstraints = []; + foreach ($constraints as $constraint) { // For the "Valid" constraint, validate the data in all groups if ($constraint instanceof Valid) { @@ -88,7 +90,7 @@ public function validate($form, Constraint $formConstraint) // matching group foreach ($groups as $group) { if (\in_array($group, $constraint->groups)) { - $validator->atPath('data')->validate($form->getData(), $constraint, $group); + $groupedConstraints[$group][] = $constraint; // Prevent duplicate validation if (!$constraint instanceof Composite) { @@ -97,6 +99,10 @@ public function validate($form, Constraint $formConstraint) } } } + + foreach ($groupedConstraints as $group => $constraint) { + $validator->atPath('data')->validate($form->getData(), $constraint, $group); + } } } elseif (!$form->isSynchronized()) { $childrenSynchronized = true; diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php index 36965c114db73..46733786a86c1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -26,6 +26,7 @@ use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\GroupSequence; +use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Valid; @@ -77,10 +78,11 @@ public function testValidateConstraints() $object = new \stdClass(); $constraint1 = new NotNull(['groups' => ['group1', 'group2']]); $constraint2 = new NotBlank(['groups' => 'group2']); + $constraint3 = new Length(['groups' => 'group2', 'min' => 3]); $options = [ 'validation_groups' => ['group1', 'group2'], - 'constraints' => [$constraint1, $constraint2], + 'constraints' => [$constraint1, $constraint2, $constraint3], ]; $form = $this->getCompoundForm($object, $options); $form->submit([]); @@ -89,8 +91,8 @@ public function testValidateConstraints() $this->expectValidateAt(0, 'data', $object, ['group1', 'group2']); // Then custom constraints - $this->expectValidateValueAt(1, 'data', $object, $constraint1, 'group1'); - $this->expectValidateValueAt(2, 'data', $object, $constraint2, 'group2'); + $this->expectValidateValueAt(1, 'data', $object, [$constraint1], 'group1'); + $this->expectValidateValueAt(2, 'data', $object, [$constraint2, $constraint3], 'group2'); $this->validator->validate($form, new Form()); @@ -172,8 +174,8 @@ public function testValidateConstraintsOptionEvenIfNoValidConstraint() $parent->add($form); $parent->submit([]); - $this->expectValidateValueAt(0, 'data', $object, $constraint1, 'group1'); - $this->expectValidateValueAt(1, 'data', $object, $constraint2, 'group2'); + $this->expectValidateValueAt(0, 'data', $object, [$constraint1], 'group1'); + $this->expectValidateValueAt(1, 'data', $object, [$constraint2], 'group2'); $this->validator->validate($form, new Form()); From 698cc6bb3beb746d1ca45527d40776964f193171 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 20 Nov 2019 14:44:34 +0100 Subject: [PATCH 14/16] [Routing] fix tests --- .../Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php index b068a93828e91..cc0aa5d50711e 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/ObjectRouteLoaderTest.php @@ -92,7 +92,7 @@ public function getBadResourceStrings() public function testExceptionOnNoObjectReturned() { - $this->expectException('LogicException'); + $this->expectException(\TypeError::class); $loader = new TestObjectRouteLoader(); $loader->loaderMap = ['my_service' => 'NOT_AN_OBJECT']; $loader->load('my_service::method'); From 90cb32a044777b8499ab12e4d10d2e00d3eea024 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 21 Nov 2019 08:07:51 +0100 Subject: [PATCH 15/16] Update CHANGELOG for 4.4.0 --- CHANGELOG-4.4.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md index 0f975d9e83dd5..64e77d4a4d718 100644 --- a/CHANGELOG-4.4.md +++ b/CHANGELOG-4.4.md @@ -7,6 +7,13 @@ in 4.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.4.0...v4.4.1 +* 4.4.0 (2019-11-21) + + * bug #34464 [Form] group constraints when calling the validator (nicolas-grekas) + * bug #34451 [DependencyInjection] Fix dumping multiple deprecated aliases (shyim) + * bug #34448 [Form] allow button names to start with uppercase letter (xabbuh) + * bug #34428 [Security] Fix best encoder not wired using migrate_from (chalasr) + * 4.4.0-RC1 (2019-11-17) * bug #34419 [Cache] Disable igbinary on PHP >= 7.4 (nicolas-grekas) From 65ec3b47e8d05eebc7300ac3d28c04f451472b67 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 21 Nov 2019 08:08:15 +0100 Subject: [PATCH 16/16] Update VERSION for 4.4.0 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 47f0b49b58d8d..d965080ae45e9 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - const VERSION = '4.4.0-DEV'; + const VERSION = '4.4.0'; const VERSION_ID = 40400; const MAJOR_VERSION = 4; const MINOR_VERSION = 4; const RELEASE_VERSION = 0; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2022'; const END_OF_LIFE = '11/2023';