From 351964749676cf0216e6718c4280b856278289ea Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 31 May 2020 07:24:17 +0200 Subject: [PATCH 01/19] bumped Symfony version to 3.4.42 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 00382a95c1e9b..a0eb026f60fa9 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.41'; - const VERSION_ID = 30441; + const VERSION = '3.4.42-DEV'; + const VERSION_ID = 30442; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 41; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 42; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From bd6a06a8b302f57b8ae84c349582331ff8b84e54 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 4 Jun 2020 11:02:21 +0200 Subject: [PATCH 02/19] [PhpUnitBridge] fix undefined var on version 3.4 --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index f0c7c4085aba4..3c68def22710e 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -107,9 +107,9 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ } if (1 === \count($info['versions'])) { - $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi -s dev phpunit/phpunit $PHPUNIT_VERSION_DIR \"$PHPUNIT_VERSION.*\""); + $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi -s dev phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); } else { - $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi phpunit/phpunit $PHPUNIT_VERSION_DIR \"$PHPUNIT_VERSION.*\""); + $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); } @copy("phpunit-$PHPUNIT_VERSION/phpunit.xsd", 'phpunit.xsd'); From 7df5298ddfbf2eeb10e4b25e93967bca8bbc1afc Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 3 Jun 2020 15:32:40 +0200 Subject: [PATCH 03/19] properly cascade validation to child forms --- .../Validator/Constraints/FormValidator.php | 7 +-- .../Constraints/FormValidatorTest.php | 60 ++++++++++++++++++- 2 files changed, 61 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 6a8923ecbf0a5..6811dceb9832a 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -72,7 +72,6 @@ public function validate($form, Constraint $formConstraint) if ($groups instanceof GroupSequence) { // Validate the data, the form AND nested fields in sequence $violationsCount = $this->context->getViolations()->count(); - $fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s'; foreach ($groups->groups as $group) { if ($validateDataGraph) { @@ -91,7 +90,7 @@ public function validate($form, Constraint $formConstraint) // in different steps without breaking early enough $this->resolvedGroups[$field] = (array) $group; $fieldFormConstraint = new Form(); - $validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint); + $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint); } } @@ -100,8 +99,6 @@ public function validate($form, Constraint $formConstraint) } } } else { - $fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s'; - if ($validateDataGraph) { $validator->atPath('data')->validate($data, null, $groups); } @@ -132,7 +129,7 @@ public function validate($form, Constraint $formConstraint) if ($field->isSubmitted()) { $this->resolvedGroups[$field] = $groups; $fieldFormConstraint = new Form(); - $validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint); + $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint); } } } 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 3d7111f85f3c1..927dd64f52071 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -18,6 +18,7 @@ use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; use Symfony\Component\Form\Extension\Validator\Constraints\Form; use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator; +use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\FormFactoryBuilder; use Symfony\Component\Form\FormFactoryInterface; @@ -51,7 +52,9 @@ class FormValidatorTest extends ConstraintValidatorTestCase protected function setUp() { $this->dispatcher = new EventDispatcher(); - $this->factory = (new FormFactoryBuilder())->getFormFactory(); + $this->factory = (new FormFactoryBuilder()) + ->addExtension(new ValidatorExtension(Validation::createValidator())) + ->getFormFactory(); parent::setUp(); @@ -791,6 +794,61 @@ public function testCompositeConstraintValidatedInSequence() $this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath()); } + public function testCascadeValidationToChildFormsUsingPropertyPaths() + { + $form = $this->getCompoundForm([], [ + 'validation_groups' => ['group1', 'group2'], + ]) + ->add('field1', null, [ + 'constraints' => [new NotBlank(['groups' => 'group1'])], + 'property_path' => '[foo]', + ]) + ->add('field2', null, [ + 'constraints' => [new NotBlank(['groups' => 'group2'])], + 'property_path' => '[bar]', + ]) + ; + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + + $this->assertCount(2, $context->getViolations()); + $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); + $this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath()); + $this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage()); + $this->assertSame('children[field2].data', $context->getViolations()[1]->getPropertyPath()); + } + + public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence() + { + $form = $this->getCompoundForm([], [ + 'validation_groups' => new GroupSequence(['group1', 'group2']), + ]) + ->add('field1', null, [ + 'constraints' => [new NotBlank(['groups' => 'group1'])], + 'property_path' => '[foo]', + ]) + ; + + $form->submit([ + 'field1' => '', + ]); + + $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + + $this->assertCount(1, $context->getViolations()); + $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); + $this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath()); + } + protected function createValidator() { return new FormValidator(); From d3f9b7f833fd245ca23ae5d78de6c83a7419f62d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 4 Jun 2020 12:27:56 +0200 Subject: [PATCH 04/19] [PhpUnitBridge] Fix undefined index when output of "composer show" cannot be parsed --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index 3c68def22710e..8951dbdea1b52 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -106,6 +106,11 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ } } + $info += [ + 'versions' => [], + 'requires' => ['php' => '*'], + ]; + if (1 === \count($info['versions'])) { $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi -s dev phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); } else { From dfb4614541963a4544646ca38b88a0b80d805b01 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Sat, 23 May 2020 00:39:09 +0200 Subject: [PATCH 05/19] Update AbstractController.php Removing `string` type-hint of $message at addFlash() Closes https://github.com/symfony/symfony/issues/28991 and https://github.com/symfony/symfony/issues/34645 Reasons: * `addFlash()` is just a convenience shortcut for `FlashBagInterface::add()` which doesn't have the type hint: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php#L28 . So removing it here improves consistency. * https://github.com/symfony/symfony/issues/28991#issuecomment-436755949 is a valid use case for having an object as `$message`. * Twig doesn't have any rendering helpers for the `message`, see https://symfony.com/doc/current/controller.html#flash-messages . And since users have to take care of displaying the `message` themselves, there's no reason to force a string upon them. --- .../Bundle/FrameworkBundle/Controller/ControllerTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php index 9d5640750af84..8858ca66c437b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php @@ -187,7 +187,7 @@ protected function file($file, $fileName = null, $disposition = ResponseHeaderBa * Adds a flash message to the current session for type. * * @param string $type The type - * @param string $message The message + * @param mixed $message The message * * @throws \LogicException * From 9f3b43ab4257fe0dac5725813d0276bec566ab06 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 4 Jun 2020 17:35:46 +0200 Subject: [PATCH 06/19] [PhpUnitBridge] fix syntax on PHP 5.3 --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index 8951dbdea1b52..eae4cc3125147 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -106,10 +106,10 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ } } - $info += [ - 'versions' => [], - 'requires' => ['php' => '*'], - ]; + $info += array( + 'versions' => array(), + 'requires' => array('php' => '*'), + ); if (1 === \count($info['versions'])) { $passthruOrFail("$COMPOSER create-project --ignore-platform-reqs --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi -s dev phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); From 6ee6b2e1b804e86ab20735ea7f7e01a5038c47cc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 8 Jun 2020 17:48:27 +0200 Subject: [PATCH 07/19] [travis] add nightly to allowed failures --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index fd9aa095c9c30..3d5253f077b03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,9 @@ matrix: - php: nightly services: [memcached] fast_finish: true + allow_failures: + - php: nightly + services: [memcached] cache: directories: From 0b9519975dae206a48858ea204c35736765224fd Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Tue, 9 Jun 2020 10:25:18 +0200 Subject: [PATCH 08/19] [WebProfilerBundle] Set NullLogger for functional tests --- .../Tests/Functional/WebProfilerBundleKernel.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php index 5470ca7dc6858..a79504a8fe090 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php @@ -2,6 +2,7 @@ namespace Symfony\Bundle\WebProfilerBundle\Tests\Functional; +use Psr\Log\NullLogger; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\TwigBundle\TwigBundle; @@ -73,6 +74,11 @@ public function getLogDir() return sys_get_temp_dir().'/log-'.spl_object_hash($this); } + protected function build(ContainerBuilder $container) + { + $container->register('logger', NullLogger::class); + } + public function homepageController() { return new Response('Homepage Controller.'); From 316efef8b8478020828932a3f5980db6b4b92711 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 9 Jun 2020 13:11:23 +0200 Subject: [PATCH 09/19] fix forward compatibility with Doctrine DBAL 3 --- .../Cache/Tests/Traits/PdoPruneableTrait.php | 6 ++++-- src/Symfony/Component/Cache/Traits/PdoTrait.php | 14 ++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php b/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php index c5ba9c66d6942..ac25578b0b01a 100644 --- a/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php +++ b/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Cache\Tests\Traits; +use Doctrine\DBAL\Result; + trait PdoPruneableTrait { protected function isPruned($cache, $name) @@ -27,8 +29,8 @@ protected function isPruned($cache, $name) /** @var \Doctrine\DBAL\Statement|\PDOStatement $select */ $select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id'); $select->bindValue(':id', sprintf('%%%s', $name)); - $select->execute(); + $result = $select->execute(); - return 1 !== (int) (method_exists($select, 'fetchOne') ? $select->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN)); + return 1 !== (int) ($result instanceof Result ? $result->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN)); } } diff --git a/src/Symfony/Component/Cache/Traits/PdoTrait.php b/src/Symfony/Component/Cache/Traits/PdoTrait.php index 6a9f3c46aea45..b00cd930aa95c 100644 --- a/src/Symfony/Component/Cache/Traits/PdoTrait.php +++ b/src/Symfony/Component/Cache/Traits/PdoTrait.php @@ -14,6 +14,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Driver\ServerInfoAwareConnection; +use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Schema; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -175,15 +176,16 @@ protected function doFetch(array $ids) foreach ($ids as $id) { $stmt->bindValue(++$i, $id); } - $stmt->execute(); + $result = $stmt->execute(); - if (method_exists($stmt, 'iterateNumeric')) { - $stmt = $stmt->iterateNumeric(); + if ($result instanceof Result) { + $result = $result->iterateNumeric(); } else { $stmt->setFetchMode(\PDO::FETCH_NUM); + $result = $stmt; } - foreach ($stmt as $row) { + foreach ($result as $row) { if (null === $row[1]) { $expired[] = $row[0]; } else { @@ -213,9 +215,9 @@ protected function doHave($id) $stmt->bindValue(':id', $id); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); - $stmt->execute(); + $result = $stmt->execute(); - return (bool) $stmt->fetchColumn(); + return (bool) ($result instanceof Result ? $result->fetchOne() : $stmt->fetchColumn()); } /** From 0f7630892923c9a532177608ca835af89d6ce7ab Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 9 Jun 2020 13:48:38 +0200 Subject: [PATCH 10/19] [Cache] fix compat with doctrine/dbal v3 --- src/Symfony/Component/Cache/Traits/PdoTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/PdoTrait.php b/src/Symfony/Component/Cache/Traits/PdoTrait.php index b00cd930aa95c..b8bd2255ac054 100644 --- a/src/Symfony/Component/Cache/Traits/PdoTrait.php +++ b/src/Symfony/Component/Cache/Traits/PdoTrait.php @@ -337,9 +337,9 @@ protected function doSave(array $values, $lifetime) } foreach ($serialized as $id => $data) { - $stmt->execute(); + $result = $stmt->execute(); - if (null === $driver && !$stmt->rowCount()) { + if (null === $driver && !($result instanceof Result ? $result : $stmt)->rowCount()) { try { $insertStmt->execute(); } catch (DBALException $e) { From ef6fc092605770ad81fa60c7cff5cf1d62a17257 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 9 Jun 2020 14:06:18 +0200 Subject: [PATCH 11/19] [Cache] fix parse error on PHP 5.5 --- src/Symfony/Component/Cache/Traits/PdoTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Traits/PdoTrait.php b/src/Symfony/Component/Cache/Traits/PdoTrait.php index b8bd2255ac054..fd6101d351bf7 100644 --- a/src/Symfony/Component/Cache/Traits/PdoTrait.php +++ b/src/Symfony/Component/Cache/Traits/PdoTrait.php @@ -339,7 +339,7 @@ protected function doSave(array $values, $lifetime) foreach ($serialized as $id => $data) { $result = $stmt->execute(); - if (null === $driver && !($result instanceof Result ? $result : $stmt)->rowCount()) { + if (null === $driver && !($result instanceof Result ? $result->rowCount() : $stmt->rowCount())) { try { $insertStmt->execute(); } catch (DBALException $e) { From 909931d9a44b3afba23e5e9f808f4655a04056e4 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 9 Jun 2020 16:06:03 +0200 Subject: [PATCH 12/19] Correctly use doctrine/dbal v3+ --- .../Doctrine/Security/RememberMe/DoctrineTokenProvider.php | 3 ++- .../Component/Cache/Tests/Traits/PdoPruneableTrait.php | 2 +- src/Symfony/Component/Cache/Traits/PdoTrait.php | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php index 4bbc9f3fcdfb4..c6e4ab3a308ba 100644 --- a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php @@ -12,6 +12,7 @@ namespace Symfony\Bridge\Doctrine\Security\RememberMe; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Driver\Result; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; @@ -63,7 +64,7 @@ public function loadTokenBySeries($series) $paramValues = ['series' => $series]; $paramTypes = ['series' => \PDO::PARAM_STR]; $stmt = $this->conn->executeQuery($sql, $paramValues, $paramTypes); - $row = method_exists($stmt, 'fetchAssociative') ? $stmt->fetchAssociative() : $stmt->fetch(\PDO::FETCH_ASSOC); + $row = $stmt instanceof Result ? $stmt->fetchAssociative() : $stmt->fetch(\PDO::FETCH_ASSOC); if ($row) { return new PersistentToken($row['class'], $row['username'], $series, $row['value'], new \DateTime($row['last_used'])); diff --git a/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php b/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php index ac25578b0b01a..113a2c28eb8ee 100644 --- a/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php +++ b/src/Symfony/Component/Cache/Tests/Traits/PdoPruneableTrait.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Cache\Tests\Traits; -use Doctrine\DBAL\Result; +use Doctrine\DBAL\Driver\Result; trait PdoPruneableTrait { diff --git a/src/Symfony/Component/Cache/Traits/PdoTrait.php b/src/Symfony/Component/Cache/Traits/PdoTrait.php index fd6101d351bf7..1aa87cd3f1a11 100644 --- a/src/Symfony/Component/Cache/Traits/PdoTrait.php +++ b/src/Symfony/Component/Cache/Traits/PdoTrait.php @@ -11,10 +11,11 @@ namespace Symfony\Component\Cache\Traits; +use Doctrine\DBAL\Abstraction\Result; use Doctrine\DBAL\Connection; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver\Result as DriverResult; use Doctrine\DBAL\Driver\ServerInfoAwareConnection; -use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Schema; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -217,7 +218,7 @@ protected function doHave($id) $stmt->bindValue(':time', time(), \PDO::PARAM_INT); $result = $stmt->execute(); - return (bool) ($result instanceof Result ? $result->fetchOne() : $stmt->fetchColumn()); + return (bool) ($result instanceof DriverResult ? $result->fetchOne() : $stmt->fetchColumn()); } /** @@ -339,7 +340,7 @@ protected function doSave(array $values, $lifetime) foreach ($serialized as $id => $data) { $result = $stmt->execute(); - if (null === $driver && !($result instanceof Result ? $result->rowCount() : $stmt->rowCount())) { + if (null === $driver && !($result instanceof DriverResult ? $result->rowCount() : $stmt->rowCount())) { try { $insertStmt->execute(); } catch (DBALException $e) { From f062e08f4d77ba1980a568bbb5df6a35378b858f Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 4 Jun 2020 15:06:18 +0200 Subject: [PATCH 13/19] rework form validator tests --- .../FormValidatorFunctionalTest.php | 315 ++++++++++++++++++ .../Constraints/FormValidatorTest.php | 146 -------- .../Validator/ValidatorExtensionTest.php | 158 --------- 3 files changed, 315 insertions(+), 304 deletions(-) create mode 100644 src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php new file mode 100644 index 0000000000000..1cf1199f71732 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php @@ -0,0 +1,315 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\Extension\Validator\ValidatorExtension; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormFactoryBuilder; +use Symfony\Component\Form\Test\ForwardCompatTestTrait; +use Symfony\Component\OptionsResolver\OptionsResolver; +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\Mapping\ClassMetadata; +use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory; +use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; +use Symfony\Component\Validator\Validation; + +class FormValidatorFunctionalTest extends TestCase +{ + use ForwardCompatTestTrait; + + private $validator; + private $formFactory; + + private function doSetUp() + { + $this->validator = Validation::createValidatorBuilder() + ->setMetadataFactory(new LazyLoadingMetadataFactory(new StaticMethodLoader())) + ->getValidator(); + $this->formFactory = (new FormFactoryBuilder()) + ->addExtension(new ValidatorExtension($this->validator)) + ->getFormFactory(); + } + + public function testDataConstraintsInvalidateFormEvenIfFieldIsNotSubmitted() + { + $form = $this->formFactory->create(FooType::class); + $form->submit(['baz' => 'foobar'], false); + + $this->assertTrue($form->isSubmitted()); + $this->assertFalse($form->isValid()); + $this->assertFalse($form->get('bar')->isSubmitted()); + $this->assertCount(1, $form->get('bar')->getErrors()); + } + + public function testFieldConstraintsDoNotInvalidateFormIfFieldIsNotSubmitted() + { + $form = $this->formFactory->create(FooType::class); + $form->submit(['bar' => 'foobar'], false); + + $this->assertTrue($form->isSubmitted()); + $this->assertTrue($form->isValid()); + } + + public function testFieldConstraintsInvalidateFormIfFieldIsSubmitted() + { + $form = $this->formFactory->create(FooType::class); + $form->submit(['bar' => 'foobar', 'baz' => ''], false); + + $this->assertTrue($form->isSubmitted()); + $this->assertFalse($form->isValid()); + $this->assertTrue($form->get('bar')->isSubmitted()); + $this->assertTrue($form->get('bar')->isValid()); + $this->assertTrue($form->get('baz')->isSubmitted()); + $this->assertFalse($form->get('baz')->isValid()); + } + + public function testNonCompositeConstraintValidatedOnce() + { + $form = $this->formFactory->create(TextType::class, null, [ + 'constraints' => [new NotBlank(['groups' => ['foo', 'bar']])], + 'validation_groups' => ['foo', 'bar'], + ]); + $form->submit(''); + + $violations = $this->validator->validate($form); + + $this->assertCount(1, $violations); + $this->assertSame('This value should not be blank.', $violations[0]->getMessage()); + $this->assertSame('data', $violations[0]->getPropertyPath()); + } + + public function testCompositeConstraintValidatedInEachGroup() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'constraints' => [ + new Collection([ + 'field1' => new NotBlank([ + 'groups' => ['field1'], + ]), + 'field2' => new NotBlank([ + 'groups' => ['field2'], + ]), + ]), + ], + 'validation_groups' => ['field1', 'field2'], + ]); + $form->add('field1'); + $form->add('field2'); + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $violations = $this->validator->validate($form); + + $this->assertCount(2, $violations); + $this->assertSame('This value should not be blank.', $violations[0]->getMessage()); + $this->assertSame('data[field1]', $violations[0]->getPropertyPath()); + $this->assertSame('This value should not be blank.', $violations[1]->getMessage()); + $this->assertSame('data[field2]', $violations[1]->getPropertyPath()); + } + + public function testCompositeConstraintValidatedInSequence() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'constraints' => [ + new Collection([ + 'field1' => new NotBlank([ + 'groups' => ['field1'], + ]), + 'field2' => new NotBlank([ + 'groups' => ['field2'], + ]), + ]), + ], + 'validation_groups' => new GroupSequence(['field1', 'field2']), + ]); + $form->add('field1'); + $form->add('field2'); + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $violations = $this->validator->validate($form); + + $this->assertCount(1, $violations); + $this->assertSame('This value should not be blank.', $violations[0]->getMessage()); + $this->assertSame('data[field1]', $violations[0]->getPropertyPath()); + } + + public function testFieldsValidateInSequence() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'validation_groups' => new GroupSequence(['group1', 'group2']), + ]) + ->add('foo', TextType::class, [ + 'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])], + ]) + ->add('bar', TextType::class, [ + 'constraints' => [new NotBlank(['groups' => ['group2']])], + ]) + ; + + $form->submit(['foo' => 'invalid', 'bar' => null]); + + $errors = $form->getErrors(true); + + $this->assertCount(1, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + } + + public function testFieldsValidateInSequenceWithNestedGroupsArray() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'validation_groups' => new GroupSequence([['group1', 'group2'], 'group3']), + ]) + ->add('foo', TextType::class, [ + 'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])], + ]) + ->add('bar', TextType::class, [ + 'constraints' => [new Length(['min' => 10, 'groups' => ['group2']])], + ]) + ->add('baz', TextType::class, [ + 'constraints' => [new NotBlank(['groups' => ['group3']])], + ]) + ; + + $form->submit(['foo' => 'invalid', 'bar' => 'invalid', 'baz' => null]); + + $errors = $form->getErrors(true); + + $this->assertCount(2, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + $this->assertInstanceOf(Length::class, $errors[1]->getCause()->getConstraint()); + } + + public function testConstraintsInDifferentGroupsOnSingleField() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'validation_groups' => new GroupSequence(['group1', 'group2']), + ]) + ->add('foo', TextType::class, [ + 'constraints' => [ + new NotBlank([ + 'groups' => ['group1'], + ]), + new Length([ + 'groups' => ['group2'], + 'max' => 3, + ]), + ], + ]); + $form->submit([ + 'foo' => 'test@example.com', + ]); + + $errors = $form->getErrors(true); + + $this->assertFalse($form->isValid()); + $this->assertCount(1, $errors); + $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); + } + + public function testCascadeValidationToChildFormsUsingPropertyPaths() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'validation_groups' => ['group1', 'group2'], + ]) + ->add('field1', null, [ + 'constraints' => [new NotBlank(['groups' => 'group1'])], + 'property_path' => '[foo]', + ]) + ->add('field2', null, [ + 'constraints' => [new NotBlank(['groups' => 'group2'])], + 'property_path' => '[bar]', + ]) + ; + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $violations = $this->validator->validate($form); + + $this->assertCount(2, $violations); + $this->assertSame('This value should not be blank.', $violations[0]->getMessage()); + $this->assertSame('children[field1].data', $violations[0]->getPropertyPath()); + $this->assertSame('This value should not be blank.', $violations[1]->getMessage()); + $this->assertSame('children[field2].data', $violations[1]->getPropertyPath()); + } + + public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'validation_groups' => new GroupSequence(['group1', 'group2']), + ]) + ->add('field1', null, [ + 'constraints' => [new NotBlank(['groups' => 'group1'])], + 'property_path' => '[foo]', + ]) + ->add('field2', null, [ + 'constraints' => [new NotBlank(['groups' => 'group2'])], + 'property_path' => '[bar]', + ]) + ; + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $violations = $this->validator->validate($form); + + $this->assertCount(1, $violations); + $this->assertSame('This value should not be blank.', $violations[0]->getMessage()); + $this->assertSame('children[field1].data', $violations[0]->getPropertyPath()); + } +} + +class Foo +{ + public $bar; + public $baz; + + public static function loadValidatorMetadata(ClassMetadata $metadata) + { + $metadata->addPropertyConstraint('bar', new NotBlank()); + } +} + +class FooType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('bar') + ->add('baz', null, [ + 'constraints' => [new NotBlank()], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('data_class', Foo::class); + } +} 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 927dd64f52071..f789fbe1e408d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -25,7 +25,6 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\SubmitButtonBuilder; use Symfony\Component\Translation\IdentityTranslator; -use Symfony\Component\Validator\Constraints\Collection; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; @@ -704,151 +703,6 @@ public function testCauseForNotAllowedExtraFieldsIsTheFormConstraint() $this->assertSame($constraint, $context->getViolations()->get(0)->getConstraint()); } - public function testNonCompositeConstraintValidatedOnce() - { - $form = $this - ->getBuilder('form', null, [ - 'constraints' => [new NotBlank(['groups' => ['foo', 'bar']])], - 'validation_groups' => ['foo', 'bar'], - ]) - ->setCompound(false) - ->getForm(); - $form->submit(''); - - $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); - $this->assertSame('data', $context->getViolations()[0]->getPropertyPath()); - } - - public function testCompositeConstraintValidatedInEachGroup() - { - $form = $this->getBuilder('form', null, [ - 'constraints' => [ - new Collection([ - 'field1' => new NotBlank([ - 'groups' => ['field1'], - ]), - 'field2' => new NotBlank([ - 'groups' => ['field2'], - ]), - ]), - ], - 'validation_groups' => ['field1', 'field2'], - ]) - ->setData([]) - ->setCompound(true) - ->setDataMapper(new PropertyPathMapper()) - ->getForm(); - $form->add($this->getForm('field1')); - $form->add($this->getForm('field2')); - $form->submit([ - 'field1' => '', - 'field2' => '', - ]); - - $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(2, $context->getViolations()); - $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); - $this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath()); - $this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage()); - $this->assertSame('data[field2]', $context->getViolations()[1]->getPropertyPath()); - } - - public function testCompositeConstraintValidatedInSequence() - { - $form = $this->getCompoundForm([], [ - 'constraints' => [ - new Collection([ - 'field1' => new NotBlank([ - 'groups' => ['field1'], - ]), - 'field2' => new NotBlank([ - 'groups' => ['field2'], - ]), - ]), - ], - 'validation_groups' => new GroupSequence(['field1', 'field2']), - ]) - ->add($this->getForm('field1')) - ->add($this->getForm('field2')) - ; - - $form->submit([ - 'field1' => '', - 'field2' => '', - ]); - - $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); - $this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath()); - } - - public function testCascadeValidationToChildFormsUsingPropertyPaths() - { - $form = $this->getCompoundForm([], [ - 'validation_groups' => ['group1', 'group2'], - ]) - ->add('field1', null, [ - 'constraints' => [new NotBlank(['groups' => 'group1'])], - 'property_path' => '[foo]', - ]) - ->add('field2', null, [ - 'constraints' => [new NotBlank(['groups' => 'group2'])], - 'property_path' => '[bar]', - ]) - ; - - $form->submit([ - 'field1' => '', - 'field2' => '', - ]); - - $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(2, $context->getViolations()); - $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); - $this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath()); - $this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage()); - $this->assertSame('children[field2].data', $context->getViolations()[1]->getPropertyPath()); - } - - public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence() - { - $form = $this->getCompoundForm([], [ - 'validation_groups' => new GroupSequence(['group1', 'group2']), - ]) - ->add('field1', null, [ - 'constraints' => [new NotBlank(['groups' => 'group1'])], - 'property_path' => '[foo]', - ]) - ; - - $form->submit([ - 'field1' => '', - ]); - - $context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator()); - $this->validator->initialize($context); - $this->validator->validate($form, new Form()); - - $this->assertCount(1, $context->getViolations()); - $this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage()); - $this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath()); - } - protected function createValidator() { return new FormValidator(); diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php index 9793bd78e69e7..4a12acf4126b4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php @@ -12,23 +12,12 @@ namespace Symfony\Component\Form\Tests\Extension\Validator; use PHPUnit\Framework\TestCase; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Validator\Constraints\Form as FormConstraint; use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser; use Symfony\Component\Form\Form; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormFactoryBuilder; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints\GroupSequence; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Mapping\CascadingStrategy; use Symfony\Component\Validator\Mapping\ClassMetadata; -use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory; -use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; use Symfony\Component\Validator\Mapping\TraversalStrategy; use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory; use Symfony\Component\Validator\Validation; @@ -57,151 +46,4 @@ public function test2Dot5ValidationApi() $this->assertSame(TraversalStrategy::NONE, $metadata->traversalStrategy); $this->assertCount(0, $metadata->getPropertyMetadata('children')); } - - public function testDataConstraintsInvalidateFormEvenIfFieldIsNotSubmitted() - { - $form = $this->createForm(FooType::class); - $form->submit(['baz' => 'foobar'], false); - - $this->assertTrue($form->isSubmitted()); - $this->assertFalse($form->isValid()); - $this->assertFalse($form->get('bar')->isSubmitted()); - $this->assertCount(1, $form->get('bar')->getErrors()); - } - - public function testFieldConstraintsDoNotInvalidateFormIfFieldIsNotSubmitted() - { - $form = $this->createForm(FooType::class); - $form->submit(['bar' => 'foobar'], false); - - $this->assertTrue($form->isSubmitted()); - $this->assertTrue($form->isValid()); - } - - public function testFieldConstraintsInvalidateFormIfFieldIsSubmitted() - { - $form = $this->createForm(FooType::class); - $form->submit(['bar' => 'foobar', 'baz' => ''], false); - - $this->assertTrue($form->isSubmitted()); - $this->assertFalse($form->isValid()); - $this->assertTrue($form->get('bar')->isSubmitted()); - $this->assertTrue($form->get('bar')->isValid()); - $this->assertTrue($form->get('baz')->isSubmitted()); - $this->assertFalse($form->get('baz')->isValid()); - } - - public function testFieldsValidateInSequence() - { - $form = $this->createForm(FormType::class, null, [ - 'validation_groups' => new GroupSequence(['group1', 'group2']), - ]) - ->add('foo', TextType::class, [ - 'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])], - ]) - ->add('bar', TextType::class, [ - 'constraints' => [new NotBlank(['groups' => ['group2']])], - ]) - ; - - $form->submit(['foo' => 'invalid', 'bar' => null]); - - $errors = $form->getErrors(true); - - $this->assertCount(1, $errors); - $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); - } - - public function testFieldsValidateInSequenceWithNestedGroupsArray() - { - $form = $this->createForm(FormType::class, null, [ - 'validation_groups' => new GroupSequence([['group1', 'group2'], 'group3']), - ]) - ->add('foo', TextType::class, [ - 'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])], - ]) - ->add('bar', TextType::class, [ - 'constraints' => [new Length(['min' => 10, 'groups' => ['group2']])], - ]) - ->add('baz', TextType::class, [ - 'constraints' => [new NotBlank(['groups' => ['group3']])], - ]) - ; - - $form->submit(['foo' => 'invalid', 'bar' => 'invalid', 'baz' => null]); - - $errors = $form->getErrors(true); - - $this->assertCount(2, $errors); - $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); - $this->assertInstanceOf(Length::class, $errors[1]->getCause()->getConstraint()); - } - - public function testConstraintsInDifferentGroupsOnSingleField() - { - $form = $this->createForm(FormType::class, null, [ - 'validation_groups' => new GroupSequence(['group1', 'group2']), - ]) - ->add('foo', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'groups' => ['group1'], - ]), - new Length([ - 'groups' => ['group2'], - 'max' => 3, - ]), - ], - ]); - $form->submit([ - 'foo' => 'test@example.com', - ]); - - $errors = $form->getErrors(true); - - $this->assertFalse($form->isValid()); - $this->assertCount(1, $errors); - $this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint()); - } - - private function createForm($type, $data = null, array $options = []) - { - $validator = Validation::createValidatorBuilder() - ->setMetadataFactory(new LazyLoadingMetadataFactory(new StaticMethodLoader())) - ->getValidator(); - $formFactoryBuilder = new FormFactoryBuilder(); - $formFactoryBuilder->addExtension(new ValidatorExtension($validator)); - $formFactory = $formFactoryBuilder->getFormFactory(); - - return $formFactory->create($type, $data, $options); - } -} - -class Foo -{ - public $bar; - public $baz; - - public static function loadValidatorMetadata(ClassMetadata $metadata) - { - $metadata->addPropertyConstraint('bar', new NotBlank()); - } -} - -class FooType extends AbstractType -{ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('bar') - ->add('baz', null, [ - 'constraints' => [new NotBlank()], - ]) - ; - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefault('data_class', Foo::class); - } } From 176e769e5f7422a510c95aac9c2d26aff2692331 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Wed, 10 Jun 2020 08:28:31 +0000 Subject: [PATCH 14/19] [HttpKernel] Fix regression where Store does not return response body correctly --- .../Component/HttpKernel/HttpCache/Store.php | 41 ++++++++++++------- .../HttpKernel/Tests/HttpCache/StoreTest.php | 33 +++++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Store.php b/src/Symfony/Component/HttpKernel/HttpCache/Store.php index fd04a7b23d1d3..72793f582df85 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Store.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Store.php @@ -152,8 +152,8 @@ public function lookup(Request $request) } $headers = $match[1]; - if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) { - return $this->restoreResponse($headers, $body); + if (file_exists($path = $this->getPath($headers['x-content-digest'][0]))) { + return $this->restoreResponse($headers, $path); } // TODO the metaStore referenced an entity that doesn't exist in @@ -177,15 +177,28 @@ public function write(Request $request, Response $response) $key = $this->getCacheKey($request); $storedEnv = $this->persistRequest($request); - $digest = $this->generateContentDigest($response); - $response->headers->set('X-Content-Digest', $digest); + if ($response->headers->has('X-Body-File')) { + // Assume the response came from disk, but at least perform some safeguard checks + if (!$response->headers->has('X-Content-Digest')) { + throw new \RuntimeException('A restored response must have the X-Content-Digest header.'); + } - if (!$this->save($digest, $response->getContent(), false)) { - throw new \RuntimeException('Unable to store the entity.'); - } + $digest = $response->headers->get('X-Content-Digest'); + if ($this->getPath($digest) !== $response->headers->get('X-Body-File')) { + throw new \RuntimeException('X-Body-File and X-Content-Digest do not match.'); + } + // Everything seems ok, omit writing content to disk + } else { + $digest = $this->generateContentDigest($response); + $response->headers->set('X-Content-Digest', $digest); - if (!$response->headers->has('Transfer-Encoding')) { - $response->headers->set('Content-Length', \strlen($response->getContent())); + if (!$this->save($digest, $response->getContent(), false)) { + throw new \RuntimeException('Unable to store the entity.'); + } + + if (!$response->headers->has('Transfer-Encoding')) { + $response->headers->set('Content-Length', \strlen($response->getContent())); + } } // read existing cache entries, remove non-varying, and add this one to the list @@ -477,19 +490,19 @@ private function persistResponse(Response $response) * Restores a Response from the HTTP headers and body. * * @param array $headers An array of HTTP headers for the Response - * @param string $body The Response body + * @param string $path Path to the Response body * * @return Response */ - private function restoreResponse($headers, $body = null) + private function restoreResponse($headers, $path = null) { $status = $headers['X-Status'][0]; unset($headers['X-Status']); - if (null !== $body) { - $headers['X-Body-File'] = [$body]; + if (null !== $path) { + $headers['X-Body-File'] = [$path]; } - return new Response($body, $status, $headers); + return new Response($path, $status, $headers); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php index 07c41542697e3..6754be45a13aa 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php @@ -118,6 +118,39 @@ public function testWritesResponseEvenIfXContentDigestIsPresent() $this->assertNotNull($response); } + public function testWritingARestoredResponseDoesNotCorruptCache() + { + /* + * This covers the regression reported in https://github.com/symfony/symfony/issues/37174. + * + * A restored response does *not* load the body, but only keep the file path in a special X-Body-File + * header. For reasons (?), the file path was also used as the restored response body. + * It would be up to others (HttpCache...?) to hohor this header and actually load the response content + * from there. + * + * When a restored response was stored again, the Store itself would ignore the header. In the first + * step, this would compute a new Content Digest based on the file path in the restored response body; + * this is covered by "Checkpoint 1" below. But, since the X-Body-File header was left untouched (Checkpoint 2), downstream + * code (HttpCache...) would not immediately notice. + * + * Only upon performing the lookup for a second time, we'd get a Response where the (wrong) Content Digest + * is also reflected in the X-Body-File header, this time also producing wrong content when the downstream + * evaluates it. + */ + $this->store->write($this->request, $this->response); + $digest = $this->response->headers->get('X-Content-Digest'); + $path = $this->getStorePath($digest); + + $response = $this->store->lookup($this->request); + $this->store->write($this->request, $response); + $this->assertEquals($digest, $response->headers->get('X-Content-Digest')); // Checkpoint 1 + $this->assertEquals($path, $response->headers->get('X-Body-File')); // Checkpoint 2 + + $response = $this->store->lookup($this->request); + $this->assertEquals($digest, $response->headers->get('X-Content-Digest')); + $this->assertEquals($path, $response->headers->get('X-Body-File')); + } + public function testFindsAStoredEntryWithLookup() { $this->storeSimpleEntry(); From 816b6ea6f195cf808932c6def5d70a674165021b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 11 Jun 2020 15:00:25 +0200 Subject: [PATCH 15/19] Fix typo --- src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php index 6754be45a13aa..eee8970b968c6 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/StoreTest.php @@ -125,7 +125,7 @@ public function testWritingARestoredResponseDoesNotCorruptCache() * * A restored response does *not* load the body, but only keep the file path in a special X-Body-File * header. For reasons (?), the file path was also used as the restored response body. - * It would be up to others (HttpCache...?) to hohor this header and actually load the response content + * It would be up to others (HttpCache...?) to honor this header and actually load the response content * from there. * * When a restored response was stored again, the Store itself would ignore the header. In the first From 38135de549c78c09cac00c0ee5a6494a8a8805f8 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 4 Jun 2020 21:54:20 +0200 Subject: [PATCH 16/19] switch the context when validating nested forms --- .../Validator/Constraints/FormValidator.php | 2 + .../FormValidatorFunctionalTest.php | 46 +++++++++++++++++++ src/Symfony/Component/Form/composer.json | 3 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 6811dceb9832a..4447b2e54aa88 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -90,6 +90,7 @@ public function validate($form, Constraint $formConstraint) // in different steps without breaking early enough $this->resolvedGroups[$field] = (array) $group; $fieldFormConstraint = new Form(); + $this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath()); $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint); } } @@ -129,6 +130,7 @@ public function validate($form, Constraint $formConstraint) if ($field->isSubmitted()) { $this->resolvedGroups[$field] = $groups; $fieldFormConstraint = new Form(); + $this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath()); $validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint); } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php index 1cf1199f71732..b51b34bb32ab0 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php @@ -21,6 +21,7 @@ use Symfony\Component\Form\Test\ForwardCompatTestTrait; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\Collection; +use Symfony\Component\Validator\Constraints\Expression; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; @@ -283,6 +284,51 @@ public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSe $this->assertSame('This value should not be blank.', $violations[0]->getMessage()); $this->assertSame('children[field1].data', $violations[0]->getPropertyPath()); } + + public function testContextIsPopulatedWithFormBeingValidated() + { + $form = $this->formFactory->create(FormType::class) + ->add('field1', null, [ + 'constraints' => [new Expression([ + 'expression' => '!this.getParent().get("field2").getData()', + ])], + ]) + ->add('field2') + ; + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $violations = $this->validator->validate($form); + + $this->assertCount(0, $violations); + } + + public function testContextIsPopulatedWithFormBeingValidatedUsingGroupSequence() + { + $form = $this->formFactory->create(FormType::class, null, [ + 'validation_groups' => new GroupSequence(['group1']), + ]) + ->add('field1', null, [ + 'constraints' => [new Expression([ + 'expression' => '!this.getParent().get("field2").getData()', + 'groups' => ['group1'], + ])], + ]) + ->add('field2') + ; + + $form->submit([ + 'field1' => '', + 'field2' => '', + ]); + + $violations = $this->validator->validate($form); + + $this->assertCount(0, $violations); + } } class Foo diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index 161994a672609..c69ac107bd8c7 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -26,9 +26,10 @@ }, "require-dev": { "doctrine/collections": "~1.0", - "symfony/validator": "^3.2.5|~4.0", + "symfony/validator": "^3.4.3|^4.0.3", "symfony/dependency-injection": "~3.3|~4.0", "symfony/config": "~2.7|~3.0|~4.0", + "symfony/expression-language": "~3.4|~4.0", "symfony/http-foundation": "~2.8|~3.0|~4.0", "symfony/http-kernel": "^3.3.5|~4.0", "symfony/security-csrf": "^2.8.31|^3.3.13|~4.0", From ab5ac9a02dd6e6526dfc569f646a2ca08d16fe10 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 12:56:53 +0200 Subject: [PATCH 17/19] updated CHANGELOG for 3.4.42 --- CHANGELOG-3.4.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index dfd39c33e34d0..a2da20414f835 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,16 @@ in 3.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/v3.4.0...v3.4.1 +* 3.4.42 (2020-06-12) + + * bug #37103 [Form] switch the context when validating nested forms (xabbuh) + * bug #37182 [HttpKernel] Fix regression where Store does not return response body correctly (mpdude) + * bug #36913 [FrameworkBundle] fix type annotation on ControllerTrait::addFlash() (ThomasLandauer) + * bug #37169 [Cache] fix forward compatibility with Doctrine DBAL 3 (xabbuh) + * bug #37085 [Form] properly cascade validation to child forms (xabbuh) + * bug #37095 [PhpUnitBridge] Fix undefined index when output of "composer show" cannot be parsed (nicolas-grekas) + * bug #37092 [PhpUnitBridge] fix undefined var on version 3.4 (nicolas-grekas) + * 3.4.41 (2020-05-31) * bug #36894 [Validator] never directly validate Existence (Required/Optional) constraints (xabbuh) From 4a02bde238fa0d4b18512452ace4a12315886326 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 12:57:05 +0200 Subject: [PATCH 18/19] update CONTRIBUTORS for 3.4.42 --- CONTRIBUTORS.md | 53 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index baf025cfe0487..cd95879aaaa07 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -65,18 +65,18 @@ Symfony is the result of the work of many people who made the code better - Kevin Bond (kbond) - Saša Stamenković (umpirsky) - Peter Rehm (rpet) + - Gábor Egyed (1ed) - Gabriel Ostrolucký (gadelat) - Henrik Bjørnskov (henrikbjorn) - - Gábor Egyed (1ed) - Miha Vrhovnik - David Maicher (dmaicher) + - Titouan Galopin (tgalopin) - Diego Saint Esteben (dii3g0) - Jan Schädlich (jschaedl) - - Titouan Galopin (tgalopin) - Konstantin Kudryashov (everzet) + - Vladimir Reznichenko (kalessil) - Bilal Amarni (bamarni) - Mathieu Piot (mpiot) - - Vladimir Reznichenko (kalessil) - Florin Patan (florinpatan) - Jáchym Toušek (enumag) - Andrej Hudec (pulzarraider) @@ -91,12 +91,12 @@ Symfony is the result of the work of many people who made the code better - Henrik Westphal (snc) - Dariusz Górecki (canni) - David Buchmann (dbu) + - Jérôme Tamarelle (gromnan) - Graham Campbell (graham) - Dariusz Ruminski - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) - - Jérôme Tamarelle (gromnan) - Daniel Holmes (dholmes) - Toni Uebernickel (havvg) - Fran Moreno (franmomu) @@ -106,11 +106,11 @@ Symfony is the result of the work of many people who made the code better - Antoine Hérault (herzult) - Paráda József (paradajozsef) - Arnaud Le Blanc (arnaud-lb) + - Sebastiaan Stok (sstok) - Maxime STEINHAUSSER - Baptiste Clavié (talus) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) - - Sebastiaan Stok (sstok) - Chris Wilkinson (thewilkybarkid) - Brice BERNARD (brikou) - marc.weistroff @@ -170,6 +170,7 @@ Symfony is the result of the work of many people who made the code better - Philipp Wahala (hifi) - Rafael Dohms (rdohms) - jwdeitch + - Ahmed TAILOULOUTE (ahmedtai) - Mikael Pajunen - Arman Hosseini (arman) - Niels Keurentjes (curry684) @@ -177,7 +178,6 @@ Symfony is the result of the work of many people who made the code better - Richard van Laak (rvanlaak) - Richard Shank (iampersistent) - Thomas Rabaix (rande) - - Ahmed TAILOULOUTE (ahmedtai) - Vincent Touzet (vincenttouzet) - jeremyFreeAgent (jeremyfreeagent) - Rouven Weßling (realityking) @@ -198,6 +198,7 @@ Symfony is the result of the work of many people who made the code better - GDIBass - Samuel NELA (snela) - Saif (╯°□°)╯ (azjezz) + - Gary PEGEOT (gary-p) - James Halsall (jaitsu) - Matthieu Napoli (mnapoli) - Florent Mata (fmata) @@ -220,7 +221,6 @@ Symfony is the result of the work of many people who made the code better - DQNEO - Andre Rømcke (andrerom) - mcfedr (mcfedr) - - Gary PEGEOT (gary-p) - Ruben Gonzalez (rubenrua) - Benjamin Dulau (dbenjamin) - Jan Rosier (rosier) @@ -244,6 +244,7 @@ Symfony is the result of the work of many people who made the code better - Matthieu Bontemps (mbontemps) - apetitpa - Pierre Minnieur (pminnieur) + - David Prévot - fivestar - Dominique Bongiraud - Jeremy Livingston (jeremylivingston) @@ -277,7 +278,6 @@ Symfony is the result of the work of many people who made the code better - Ruud Kamphuis (ruudk) - Pavel Batanov (scaytrase) - Mantis Development - - David Prévot - Loïc Faugeron - Hidde Wieringa (hiddewie) - dFayet @@ -371,6 +371,7 @@ Symfony is the result of the work of many people who made the code better - Chris Smith (cs278) - Thomas Bisignani (toma) - Florian Klein (docteurklein) + - Benjamin Leveque (benji07) - Manuel Kiessling (manuelkiessling) - Atsuhiro KUBO (iteman) - rudy onfroy (ronfroy) @@ -407,6 +408,7 @@ Symfony is the result of the work of many people who made the code better - Dariusz Rumiński - Berny Cantos (xphere81) - Thierry Thuon (lepiaf) + - Guilhem N (guilhemn) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) - Philippe Segatori @@ -432,6 +434,7 @@ Symfony is the result of the work of many people who made the code better - Tomasz Kowalczyk (thunderer) - Artur Eshenbrener - Timo Bakx (timobakx) + - Harm van Tilborg (hvt) - Thomas Perez (scullwm) - Felix Labrecque - Yaroslav Kiliba @@ -471,7 +474,6 @@ Symfony is the result of the work of many people who made the code better - Michele Locati - Pavel Volokitin (pvolok) - Valentine Boineau (valentineboineau) - - Benjamin Leveque (benji07) - Arthur de Moulins (4rthem) - Matthias Althaus (althaus) - Nicolas Dewez (nicolas_dewez) @@ -516,10 +518,11 @@ Symfony is the result of the work of many people who made the code better - Steffen Roßkamp - Alexandru Furculita (afurculita) - Valentin Jonovs (valentins-jonovs) - - Guilhem N (guilhemn) + - Sebastien Morel (plopix) - Jeanmonod David (jeanmonod) - Christopher Davis (chrisguitarguy) - Webnet team (webnet) + - Joe Bennett (kralos) - Farhad Safarov - Jan Schumann - Niklas Fiekas @@ -556,6 +559,7 @@ Symfony is the result of the work of many people who made the code better - Ariel Ferrandini (aferrandini) - Dirk Pahl (dirkaholic) - cedric lombardot (cedriclombardot) + - Arkadius Stefanski (arkadius) - Tim Goudriaan (codedmonkey) - Jonas Flodén (flojon) - Tobias Weichart @@ -621,6 +625,7 @@ Symfony is the result of the work of many people who made the code better - Maks Slesarenko - Filip Procházka (fprochazka) - mmoreram + - Jeroen Thora (bolle) - Markus Lanthaler (lanthaler) - Remi Collet - Vicent Soria Durá (vicentgodella) @@ -688,6 +693,7 @@ Symfony is the result of the work of many people who made the code better - Pavel Campr (pcampr) - Andrii Dembitskyi - Johnny Robeson (johnny) + - Thomas Landauer (thomas-landauer) - Guilliam Xavier - Disquedur - Michiel Boeckaert (milio) @@ -701,13 +707,11 @@ Symfony is the result of the work of many people who made the code better - Piotr Stankowski - Baptiste Leduc (bleduc) - Julien Maulny - - Sebastien Morel (plopix) - Jean-Christophe Cuvelier [Artack] - Julien Montel (julienmgel) - Simon DELICATA - Artem Henvald (artemgenvald) - Dmitry Simushev - - Joe Bennett (kralos) - alcaeus - Thomas Talbot (ioni) - Fred Cox @@ -722,10 +726,12 @@ Symfony is the result of the work of many people who made the code better - Marvin Butkereit - Renan - Ricky Su (ricky) + - Marcin Szepczynski (czepol) - Kyle Evans (kevans91) - Charles-Henri Bruyand - Max Rath (drak3) - Stéphane Escandell (sescandell) + - Baptiste Leduc (korbeil) - Konstantin S. M. Möllers (ksmmoellers) - James Johnston - Noémi Salaün (noemi-salaun) @@ -776,7 +782,6 @@ Symfony is the result of the work of many people who made the code better - maxime.steinhausser - adev - Stefan Warman - - Arkadius Stefanski (arkadius) - Tristan Maindron (tmaindron) - Behnoush Norouzali (behnoush) - Wesley Lancel @@ -949,12 +954,10 @@ Symfony is the result of the work of many people who made the code better - Jayson Xu (superjavason) - Hubert Lenoir (hubert_lenoir) - fago - - Harm van Tilborg - Jan Prieser - GDIBass - Antoine Lamirault - Adrien Lucas (adrienlucas) - - Jeroen Thora (bolle) - Zhuravlev Alexander (scif) - Stefano Degenkamp (steef) - James Michael DuPont @@ -1038,7 +1041,6 @@ Symfony is the result of the work of many people who made the code better - Don Pinkster - Maksim Muruev - Emil Einarsson - - Thomas Landauer - 243083df - Thibault Duplessis - Rimas Kudelis @@ -1060,6 +1062,7 @@ Symfony is the result of the work of many people who made the code better - Hugo Alliaume (kocal) - Marcos Gómez Vilches (markitosgv) - Matthew Davis (mdavis1982) + - Paulo Ribeiro (paulo) - Markus S. (staabm) - Benjamin Morel - Maks @@ -1118,7 +1121,6 @@ Symfony is the result of the work of many people who made the code better - xaav - Mahmoud Mostafa (mahmoud) - Antonio Jose Cerezo (ajcerezo) - - Baptiste Leduc (korbeil) - Ahmed Abdou - Daniel Iwaniec - Thomas Ferney @@ -1157,6 +1159,8 @@ Symfony is the result of the work of many people who made the code better - zairig imad (zairigimad) - Anton Babenko (antonbabenko) - Irmantas Šiupšinskas (irmantas) + - Benoit Mallo + - Lescot Edouard (idetox) - Danilo Silva - Giuseppe Campanelli - Arnaud PETITPAS (apetitpa) @@ -1226,11 +1230,13 @@ Symfony is the result of the work of many people who made the code better - gr1ev0us - mlazovla - Alejandro Diaz Torres + - quentin neyrat (qneyrat) - Max Beutel - Jan Vernieuwe (vernija) - Antanas Arvasevicius - Pierre Dudoret - Thomas + - j.schmitt - Maximilian Berghoff (electricmaxxx) - nacho - Piotr Antosik (antek88) @@ -1326,7 +1332,9 @@ Symfony is the result of the work of many people who made the code better - Carlos Ortega Huetos - rpg600 - Péter Buri (burci) + - John VanDeWeghe - kaiwa + - Claude Khedhiri (ck-developer) - Charles Sanquer (csanquer) - Albert Ganiev (helios-ag) - Neil Katin @@ -1363,6 +1371,7 @@ Symfony is the result of the work of many people who made the code better - arnaud (arnooo999) - Gilles Doge (gido) - Oscar Esteve (oesteve) + - Sobhan Sharifi (50bhan) - abulford - Philipp Kretzschmar - antograssiot @@ -1412,6 +1421,7 @@ Symfony is the result of the work of many people who made the code better - Marc Torres - Mark Spink - Alberto Aldegheri + - Sagrario Meneses - Dmitri Petmanson - heccjj - Alexandre Melard @@ -1731,7 +1741,9 @@ Symfony is the result of the work of many people who made the code better - Przemysław Piechota (kibao) - Leonid Terentyev (li0n) - Martynas Sudintas (martiis) + - Douglas Hammond (wizhippo) - ryunosuke + - Bruno BOUTAREL - victoria - Francisco Facioni (fran6co) - Stanislav Gamayunov (happyproff) @@ -1864,6 +1876,7 @@ Symfony is the result of the work of many people who made the code better - Pavel.Batanov - avi123 - Pavel Prischepa + - Sami Mussbach - alsar - downace - Aarón Nieves Fernández @@ -1891,6 +1904,7 @@ Symfony is the result of the work of many people who made the code better - Brian Graham (incognito) - Kevin Vergauwen (innocenzo) - Alessio Baglio (ioalessio) + - Jeroen Noten (jeroennoten) - Johannes Müller (johmue) - Jordi Llonch (jordillonch) - Nicholas Ruunu (nicholasruunu) @@ -1911,6 +1925,7 @@ Symfony is the result of the work of many people who made the code better - Alexey Popkov - Gijs Kunze - Artyom Protaskin + - Steven Dubois - Nathanael d. Noblet - helmer - ged15 @@ -1983,6 +1998,7 @@ Symfony is the result of the work of many people who made the code better - Andrew Marcinkevičius (ifdattic) - Ioana Hazsda (ioana-hazsda) - Jan Marek (janmarek) + - Dmitriy Mamontov (mamontovdmitriy) - Mark de Haan (markdehaan) - Dan Patrick (mdpatrick) - naitsirch (naitsirch) @@ -2343,6 +2359,7 @@ Symfony is the result of the work of many people who made the code better - Ben Miller - Peter Gribanov - Matteo Galli + - Loenix - kwiateusz - jspee - Ilya Bulakh @@ -2466,7 +2483,6 @@ Symfony is the result of the work of many people who made the code better - Marco Petersen (ocrampete16) - ollie harridge (ollietb) - Paul Andrieux (paulandrieux) - - Paulo Ribeiro (paulo) - Paweł Szczepanek (pauluz) - Philippe Degeeter (pdegeeter) - Christian López Espínola (penyaskito) @@ -2521,6 +2537,7 @@ Symfony is the result of the work of many people who made the code better - MaPePeR - Andreas Streichardt - Alexandre Segura + - Marco Pfeiffer - Vivien - Pascal Hofmann - david-binda From 4d48338b6c1643c78fa2eb52c298b1914fd99476 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Jun 2020 12:57:07 +0200 Subject: [PATCH 19/19] updated VERSION for 3.4.42 --- 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 a0eb026f60fa9..1f0e29b97cef5 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.42-DEV'; + const VERSION = '3.4.42'; const VERSION_ID = 30442; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 42; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy