From d333aae1874f451e22cc492432c3edb335a5ed07 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 21 May 2020 21:40:39 +0200 Subject: [PATCH 01/16] never directly validate Existence (Required/Optional) constraints --- .../Tests/Validator/RecursiveValidatorTest.php | 16 ++++++++++++++++ .../Validator/RecursiveContextualValidator.php | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 31871c3f9a..484236241c 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -19,6 +19,8 @@ use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotNull; +use Symfony\Component\Validator\Constraints\Optional; +use Symfony\Component\Validator\Constraints\Required; use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\ExecutionContextFactory; use Symfony\Component\Validator\Mapping\ClassMetadata; @@ -157,4 +159,18 @@ class RecursiveValidatorTest extends AbstractTest $this->assertInstanceOf(NotBlank::class, $violations->get(0)->getConstraint()); $this->assertInstanceOf(Length::class, $violations->get(1)->getConstraint()); } + + public function testRequiredConstraintIsIgnored() + { + $violations = $this->validator->validate([], new Required()); + + $this->assertCount(0, $violations); + } + + public function testOptionalConstraintIsIgnored() + { + $violations = $this->validator->validate([], new Optional()); + + $this->assertCount(0, $violations); + } } diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index a204cd91f6..24206bfc27 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Composite; +use Symfony\Component\Validator\Constraints\Existence; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; @@ -790,6 +791,10 @@ class RecursiveContextualValidator implements ContextualValidatorInterface $context->setGroup($group); foreach ($metadata->findConstraints($group) as $constraint) { + if ($constraint instanceof Existence) { + continue; + } + // Prevent duplicate validation of constraints, in the case // that constraints belong to multiple validated groups if (null !== $cacheKey) { From 3d18c1c18509f9ed21635f8daecaa9d09f6fb3bf Mon Sep 17 00:00:00 2001 From: Martin Hujer Date: Wed, 27 May 2020 11:59:50 +0200 Subject: [PATCH 02/16] [Validator] add missing Czech translations --- .../Resources/translations/validators.cs.xlf | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf index e637d09aa9..ce32f1368d 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.cs.xlf @@ -334,6 +334,54 @@ This value should be valid JSON. Tato hodnota musí být validní JSON. + + This collection should contain only unique elements. + Tato kolekce musí obsahovat pouze unikátní prvky. + + + This value should be positive. + Tato hodnota musí být kladná. + + + This value should be either positive or zero. + Tato hodnota musí být buď kladná nebo nula. + + + This value should be negative. + Tato hodnota musí být záporná. + + + This value should be either negative or zero. + Tato hodnota musí být buď záporná nebo nula. + + + This value is not a valid timezone. + Tato časová zóna neexistuje. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + Zadané heslo bylo součástí úniku dat, takže ho není možné použít. Použijte prosím jiné heslo. + + + This value should be between {{ min }} and {{ max }}. + Hodnota musí být mezi {{ min }} a {{ max }}. + + + This value is not a valid hostname. + Tato hodnota není platný hostname. + + + The number of elements in this collection should be a multiple of {{ compared_value }}. + Počet prvků v této kolekci musí být násobek {{ compared_value }}. + + + This value should satisfy at least one of the following constraints: + Tato hodnota musí splňovat alespoň jedno z následujících omezení: + + + Each element of this collection should satisfy its own set of constraints. + Každý prvek v této kolekci musí splňovat svá vlastní omezení. + From afdda5d764cf002cc8069149b5f4b2033d4324c1 Mon Sep 17 00:00:00 2001 From: Martin Hujer Date: Wed, 27 May 2020 12:01:07 +0200 Subject: [PATCH 03/16] [Form] add missing Czech validators translation --- .../Component/Form/Resources/translations/validators.cs.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.cs.xlf b/src/Symfony/Component/Form/Resources/translations/validators.cs.xlf index 776da49481..44d597db98 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.cs.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.cs.xlf @@ -14,6 +14,10 @@ The CSRF token is invalid. Please try to resubmit the form. CSRF token je neplatný. Zkuste prosím znovu odeslat formulář. + + This value is not a valid HTML5 color. + Tato hodnota není platná HTML5 barva. + From aa50c9287c93b0972dafc533e350fff75c5820a3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 28 May 2020 12:36:45 +0200 Subject: [PATCH 04/16] [ErrorHandler] fix setting $trace to null in FatalError --- src/Symfony/Component/ErrorHandler/Error/FatalError.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/ErrorHandler/Error/FatalError.php b/src/Symfony/Component/ErrorHandler/Error/FatalError.php index 68172d876c..98490b5acc 100644 --- a/src/Symfony/Component/ErrorHandler/Error/FatalError.php +++ b/src/Symfony/Component/ErrorHandler/Error/FatalError.php @@ -72,9 +72,11 @@ class FatalError extends \Error 'line' => $error['line'], 'trace' => $trace, ] as $property => $value) { - $refl = new \ReflectionProperty(\Error::class, $property); - $refl->setAccessible(true); - $refl->setValue($this, $value); + if (null !== $value) { + $refl = new \ReflectionProperty(\Error::class, $property); + $refl->setAccessible(true); + $refl->setValue($this, $value); + } } } From 15d4f7ac041a59272af282a21228621a26311165 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 28 May 2020 14:17:38 +0200 Subject: [PATCH 05/16] [Security/Http] fix merge --- .../Component/Security/Http/Firewall/ExceptionListener.php | 2 +- .../Security/Http/Tests/Firewall/ExceptionListenerTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php index 09ef9564ed..93fe14c4c5 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php @@ -183,7 +183,7 @@ class ExceptionListener private function handleLogoutException(GetResponseForExceptionEvent $event, LogoutException $exception): void { - $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception)); + $event->setThrowable(new AccessDeniedHttpException($exception->getMessage(), $exception)); if (null !== $this->logger) { $this->logger->info('A LogoutException was thrown; wrapping with AccessDeniedHttpException', ['exception' => $exception]); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php index 53204129fe..7328394b48 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php @@ -165,8 +165,8 @@ class ExceptionListenerTest extends TestCase $listener = $this->createExceptionListener(); $listener->onKernelException($event); - $this->assertEquals('Invalid CSRF.', $event->getException()->getMessage()); - $this->assertEquals(403, $event->getException()->getStatusCode()); + $this->assertEquals('Invalid CSRF.', $event->getThrowable()->getMessage()); + $this->assertEquals(403, $event->getThrowable()->getStatusCode()); } public function getAccessDeniedExceptionProvider() From 6f59d605083b619ee41b07add28c5cfd42357ad2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 28 May 2020 15:20:36 +0200 Subject: [PATCH 06/16] [TwigBridge] fix fallback html-to-txt body converter --- src/Symfony/Bridge/Twig/Mime/BodyRenderer.php | 2 +- src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php index e1031b3d56..e082d8313b 100644 --- a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php +++ b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php @@ -74,6 +74,6 @@ final class BodyRenderer implements BodyRendererInterface return $this->converter->convert($html); } - return strip_tags($html); + return strip_tags(preg_replace('{<(head|style)\b.*?}i', '', $html)); } } diff --git a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php index 6eeade3a73..175a8e1978 100644 --- a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php @@ -29,11 +29,12 @@ class BodyRendererTest extends TestCase public function testRenderHtmlOnly(): void { - $email = $this->prepareEmail(null, 'HTML'); + $html = 'headHTML'; + $email = $this->prepareEmail(null, $html); $body = $email->getBody(); $this->assertInstanceOf(AlternativePart::class, $body); $this->assertEquals('HTML', $body->getParts()[0]->bodyToString()); - $this->assertEquals('HTML', $body->getParts()[1]->bodyToString()); + $this->assertEquals(str_replace('=', '=3D', $html), $body->getParts()[1]->bodyToString()); } public function testRenderHtmlOnlyWithTextSet(): void From 03b4e986301cbe0c23fd6a56f4ee18afef31139f Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 29 May 2020 02:02:01 +0200 Subject: [PATCH 07/16] [PropertyAccess] Fix TypeError parsing again. --- .../PropertyAccess/PropertyAccessor.php | 10 +++- .../Tests/PropertyAccessorTest.php | 53 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 3bb5d6dcf7..99aa9a3ebc 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -479,9 +479,15 @@ class PropertyAccessor implements PropertyAccessorInterface try { $result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}(); } catch (\TypeError $e) { + list($trace) = $e->getTrace(); + // handle uninitialized properties in PHP >= 7 - if (preg_match((sprintf('/^Return value of %s::%s\(\) must be of (?:the )?type (\w+), null returned$/', preg_quote(\get_class($object)), $access[self::ACCESS_NAME])), $e->getMessage(), $matches)) { - throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', \get_class($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e); + if (__FILE__ === $trace['file'] + && $access[self::ACCESS_NAME] === $trace['function'] + && $object instanceof $trace['class'] + && preg_match((sprintf('/Return value (?:of .*::\w+\(\) )?must be of (?:the )?type (\w+), null returned$/')), $e->getMessage(), $matches) + ) { + throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', false === strpos(\get_class($object), "@anonymous\0") ? \get_class($object) : (get_parent_class($object) ?: 'class').'@anonymous', $access[self::ACCESS_NAME], $matches[1]), 0, $e); } throw $e; diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index d8331e76ad..e1d87a428c 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -142,6 +142,59 @@ class PropertyAccessorTest extends TestCase $this->propertyAccessor->getValue(new UninitializedPrivateProperty(), 'uninitialized'); } + /** + * @requires PHP 7 + */ + public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousClass() + { + $this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException'); + $this->expectExceptionMessage('The method "class@anonymous::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?'); + + $object = eval('return new class() { + private $uninitialized; + + public function getUninitialized(): array + { + return $this->uninitialized; + } + };'); + + $this->propertyAccessor->getValue($object, 'uninitialized'); + } + + /** + * @requires PHP 7 + */ + public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousStdClass() + { + $this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException'); + $this->expectExceptionMessage('The method "stdClass@anonymous::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?'); + + $object = eval('return new class() extends \stdClass { + private $uninitialized; + + public function getUninitialized(): array + { + return $this->uninitialized; + } + };'); + + $this->propertyAccessor->getValue($object, 'uninitialized'); + } + + /** + * @requires PHP 7 + */ + public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousChildClass() + { + $this->expectException('Symfony\Component\PropertyAccess\Exception\AccessException'); + $this->expectExceptionMessage('The method "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty@anonymous::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?'); + + $object = eval('return new class() extends \Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty {};'); + + $this->propertyAccessor->getValue($object, 'uninitialized'); + } + public function testGetValueThrowsExceptionIfNotArrayAccess() { $this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchIndexException'); From 3ab76e40ff0962c14a86c34a479d169b8e5a1da3 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Thu, 28 May 2020 22:44:39 +0200 Subject: [PATCH 08/16] Add meaningful message when Process is not installed (ProcessHelper) --- src/Symfony/Component/Console/Helper/ProcessHelper.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Console/Helper/ProcessHelper.php b/src/Symfony/Component/Console/Helper/ProcessHelper.php index 666f114a23..951bb854ec 100644 --- a/src/Symfony/Component/Console/Helper/ProcessHelper.php +++ b/src/Symfony/Component/Console/Helper/ProcessHelper.php @@ -37,6 +37,10 @@ class ProcessHelper extends Helper */ public function run(OutputInterface $output, $cmd, $error = null, callable $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) { + if (!class_exists(Process::class)) { + throw new \LogicException('The Process helper requires the "Process" component. Install "symfony/process" to use it.'); + } + if ($output instanceof ConsoleOutputInterface) { $output = $output->getErrorOutput(); } From 1614595424692f0d536892c351a82ac1c4b800eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Egyed?= Date: Fri, 29 May 2020 09:40:36 +0200 Subject: [PATCH 09/16] Update Hungarian translations --- .../Component/Form/Resources/translations/validators.hu.xlf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf b/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf index 374cfaaea3..b53f16d6ae 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf @@ -14,6 +14,10 @@ The CSRF token is invalid. Please try to resubmit the form. Érvénytelen CSRF token. Kérem, próbálja újra elküldeni az űrlapot. + + This value is not a valid HTML5 color. + Ez az érték nem egy érvényes HTML5 szín. + From b819d94d1413e426237f35e6b6eddbc380dbccf9 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 19 May 2020 08:35:15 +0200 Subject: [PATCH 10/16] validate subforms in all validation groups --- .../Validator/Constraints/FormValidator.php | 31 +++++++++++++----- .../Validator/ValidatorExtension.php | 4 +-- .../Form/Resources/config/validation.xml | 6 ++-- .../Constraints/FormValidatorTest.php | 6 ++-- .../Validator/ValidatorExtensionTest.php | 32 +++++++++++++++++-- 5 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 14158f4c1c..6a8923ecbf 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -63,12 +63,16 @@ class FormValidator extends ConstraintValidator /** @var Constraint[] $constraints */ $constraints = $config->getOption('constraints', []); + $hasChildren = $form->count() > 0; + + if ($hasChildren && $form->isRoot()) { + $this->resolvedGroups = new \SplObjectStorage(); + } + 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'; - $hasChildren = $form->count() > 0; - $this->resolvedGroups = $hasChildren ? new \SplObjectStorage() : null; foreach ($groups->groups as $group) { if ($validateDataGraph) { @@ -86,7 +90,8 @@ class FormValidator extends ConstraintValidator // sequence recursively, thus some fields could fail // in different steps without breaking early enough $this->resolvedGroups[$field] = (array) $group; - $validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $formConstraint); + $fieldFormConstraint = new Form(); + $validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint); } } @@ -94,12 +99,9 @@ class FormValidator extends ConstraintValidator break; } } - - if ($hasChildren) { - // destroy storage at the end of the sequence to avoid memory leaks - $this->resolvedGroups = null; - } } else { + $fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s'; + if ($validateDataGraph) { $validator->atPath('data')->validate($data, null, $groups); } @@ -125,6 +127,19 @@ class FormValidator extends ConstraintValidator } } } + + foreach ($form->all() as $field) { + if ($field->isSubmitted()) { + $this->resolvedGroups[$field] = $groups; + $fieldFormConstraint = new Form(); + $validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint); + } + } + } + + if ($hasChildren && $form->isRoot()) { + // destroy storage to avoid memory leaks + $this->resolvedGroups = new \SplObjectStorage(); } } elseif (!$form->isSynchronized()) { $childrenSynchronized = true; diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php index a5e38859c0..ac2d61238f 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php @@ -13,7 +13,7 @@ namespace Symfony\Component\Form\Extension\Validator; use Symfony\Component\Form\AbstractExtension; use Symfony\Component\Form\Extension\Validator\Constraints\Form; -use Symfony\Component\Validator\Constraints\Valid; +use Symfony\Component\Validator\Constraints\Traverse; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -37,7 +37,7 @@ class ValidatorExtension extends AbstractExtension /* @var $metadata ClassMetadata */ $metadata->addConstraint(new Form()); - $metadata->addPropertyConstraint('children', new Valid()); + $metadata->addConstraint(new Traverse(false)); $this->validator = $validator; } diff --git a/src/Symfony/Component/Form/Resources/config/validation.xml b/src/Symfony/Component/Form/Resources/config/validation.xml index b2b935442d..918f101f42 100644 --- a/src/Symfony/Component/Form/Resources/config/validation.xml +++ b/src/Symfony/Component/Form/Resources/config/validation.xml @@ -6,8 +6,8 @@ - - - + + + 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 5181e41225..3d7111f85f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -615,7 +615,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase $this->assertTrue($form->isSubmitted()); $this->assertTrue($form->isSynchronized()); - $this->expectNoValidate(); + + $this->expectValidateValueAt(0, 'children[child]', $form->get('child'), new Form()); $this->validator->validate($form, new Form()); @@ -638,7 +639,8 @@ class FormValidatorTest extends ConstraintValidatorTestCase $this->assertTrue($form->isSubmitted()); $this->assertTrue($form->isSynchronized()); - $this->expectNoValidate(); + + $this->expectValidateValueAt(0, 'children[child]', $form->get('child'), new Form()); $this->validator->validate($form, new Form()); diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php index cb9b93abdb..9793bd78e6 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php @@ -54,9 +54,8 @@ class ValidatorExtensionTest extends TestCase $this->assertInstanceOf(FormConstraint::class, $metadata->getConstraints()[0]); $this->assertSame(CascadingStrategy::NONE, $metadata->cascadingStrategy); - $this->assertSame(TraversalStrategy::IMPLICIT, $metadata->traversalStrategy); - $this->assertSame(CascadingStrategy::CASCADE, $metadata->getPropertyMetadata('children')[0]->cascadingStrategy); - $this->assertSame(TraversalStrategy::IMPLICIT, $metadata->getPropertyMetadata('children')[0]->traversalStrategy); + $this->assertSame(TraversalStrategy::NONE, $metadata->traversalStrategy); + $this->assertCount(0, $metadata->getPropertyMetadata('children')); } public function testDataConstraintsInvalidateFormEvenIfFieldIsNotSubmitted() @@ -138,6 +137,33 @@ class ValidatorExtensionTest extends TestCase $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() From 472883313f32f09a52973479edbbde5532d65141 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 19 May 2020 10:49:18 +0200 Subject: [PATCH 11/16] [Validator] Use Mime component to determine mime type for file validator --- .../Validator/Constraints/FileValidator.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index 52e9379441..31218c2020 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -13,8 +13,10 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\HttpFoundation\File\File as FileObject; use Symfony\Component\HttpFoundation\File\UploadedFile; +use Symfony\Component\Mime\MimeTypes; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Exception\UnexpectedValueException; @@ -170,12 +172,17 @@ class FileValidator extends ConstraintValidator } if ($constraint->mimeTypes) { - if (!$value instanceof FileObject) { - $value = new FileObject($value); + if ($value instanceof FileObject) { + $mime = $value->getMimeType(); + } elseif (class_exists(MimeTypes::class)) { + $mime = MimeTypes::getDefault()->guessMimeType($path); + } elseif (!class_exists(FileObject::class)) { + throw new LogicException('You cannot validate the mime-type of files as the Mime component is not installed. Try running "composer require symfony/mime".'); + } else { + $mime = (new FileObject($value))->getMimeType(); } $mimeTypes = (array) $constraint->mimeTypes; - $mime = $value->getMimeType(); foreach ($mimeTypes as $mimeType) { if ($mimeType === $mime) { From 5d93b61278bff6a3919081fbcc7d10c1928896f2 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 29 May 2020 16:03:43 +0200 Subject: [PATCH 12/16] [Console] Fix QuestionHelper::disableStty() --- .../Console/Helper/QuestionHelper.php | 6 ++-- .../Tests/Helper/QuestionHelperTest.php | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/QuestionHelper.php b/src/Symfony/Component/Console/Helper/QuestionHelper.php index 93e221d36a..80f6048b80 100644 --- a/src/Symfony/Component/Console/Helper/QuestionHelper.php +++ b/src/Symfony/Component/Console/Helper/QuestionHelper.php @@ -32,7 +32,7 @@ class QuestionHelper extends Helper { private $inputStream; private static $shell; - private static $stty; + private static $stty = true; /** * Asks a question to the user. @@ -158,7 +158,7 @@ class QuestionHelper extends Helper $inputStream = $this->inputStream ?: STDIN; $autocomplete = $question->getAutocompleterValues(); - if (null === $autocomplete || !Terminal::hasSttyAvailable()) { + if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) { $ret = false; if ($question->isHidden()) { try { @@ -424,7 +424,7 @@ class QuestionHelper extends Helper return $value; } - if (Terminal::hasSttyAvailable()) { + if (self::$stty && Terminal::hasSttyAvailable()) { $sttyMode = shell_exec('stty -g'); shell_exec('stty -echo'); diff --git a/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php index 4303c020a3..93b762c261 100644 --- a/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Tests\Helper; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\FormatterHelper; use Symfony\Component\Console\Helper\HelperSet; @@ -1013,6 +1014,35 @@ class QuestionHelperTest extends AbstractQuestionHelperTest $this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question)); } + public function testDisableSttby() + { + if (!Terminal::hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('invalid'); + + QuestionHelper::disableStty(); + $dialog = new QuestionHelper(); + $dialog->setHelperSet(new HelperSet([new FormatterHelper()])); + + $question = new ChoiceQuestion('Please select a bundle', [1 => 'AcmeDemoBundle', 4 => 'AsseticBundle']); + $question->setMaxAttempts(1); + + // + // Gives `AcmeDemoBundle` with stty + $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n"); + + try { + $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question); + } finally { + $reflection = new \ReflectionProperty(QuestionHelper::class, 'stty'); + $reflection->setAccessible(true); + $reflection->setValue(null, true); + } + } + public function testTraversableMultiselectAutocomplete() { // From ff7d3f4f01541ec130d8b436cc67547b4e99e181 Mon Sep 17 00:00:00 2001 From: Pedro Casado Date: Fri, 22 May 2020 14:37:09 -0300 Subject: [PATCH 13/16] Fixes sprintf(): Too few arguments in form transformer --- .../Bundle/WebServerBundle/Command/ServerLogCommand.php | 2 +- .../Asset/VersionStrategy/JsonManifestVersionStrategy.php | 2 +- src/Symfony/Component/Filesystem/Filesystem.php | 8 ++++---- src/Symfony/Component/Form/Form.php | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php index 75d94321f4..40be5a50a4 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php @@ -99,7 +99,7 @@ EOF } if (!$socket = stream_socket_server($host, $errno, $errstr)) { - throw new RuntimeException(sprintf('Server start failed on "%s": '.$errstr.' '.$errno, $host)); + throw new RuntimeException(sprintf('Server start failed on "%s": ', $host).$errstr.' '.$errno); } foreach ($this->getLogs($socket) as $clientId => $message) { diff --git a/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php b/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php index d052317678..62f9ff7dbd 100644 --- a/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php +++ b/src/Symfony/Component/Asset/VersionStrategy/JsonManifestVersionStrategy.php @@ -59,7 +59,7 @@ class JsonManifestVersionStrategy implements VersionStrategyInterface $this->manifestData = json_decode(file_get_contents($this->manifestPath), true); if (0 < json_last_error()) { - throw new \RuntimeException(sprintf('Error parsing JSON from asset manifest file "%s": '.json_last_error_msg(), $this->manifestPath)); + throw new \RuntimeException(sprintf('Error parsing JSON from asset manifest file "%s": ', $this->manifestPath).json_last_error_msg()); } } diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index e2812f8e22..0b5297ecf0 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -101,7 +101,7 @@ class Filesystem if (!is_dir($dir)) { // The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one if (self::$lastError) { - throw new IOException(sprintf('Failed to create "%s": '.self::$lastError, $dir), 0, null, $dir); + throw new IOException(sprintf('Failed to create "%s": ', $dir).self::$lastError, 0, null, $dir); } throw new IOException(sprintf('Failed to create "%s".', $dir), 0, null, $dir); } @@ -171,16 +171,16 @@ class Filesystem if (is_link($file)) { // See https://bugs.php.net/52176 if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove symlink "%s": '.self::$lastError, $file)); + throw new IOException(sprintf('Failed to remove symlink "%s": ', $file).self::$lastError); } } elseif (is_dir($file)) { $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)); if (!self::box('rmdir', $file) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove directory "%s": '.self::$lastError, $file)); + throw new IOException(sprintf('Failed to remove directory "%s": ', $file).self::$lastError); } } elseif (!self::box('unlink', $file) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove file "%s": '.self::$lastError, $file)); + throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError); } } } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 93b62a9acf..70874a2f90 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -1031,7 +1031,7 @@ class Form implements \IteratorAggregate, FormInterface $value = $transformer->transform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to transform data for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to transform data for property path "%s": ', $this->getPropertyPath()).$exception->getMessage(), $exception->getCode(), $exception); } return $value; @@ -1055,7 +1055,7 @@ class Form implements \IteratorAggregate, FormInterface $value = $transformers[$i]->reverseTransform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": ', $this->getPropertyPath()).$exception->getMessage(), $exception->getCode(), $exception); } return $value; @@ -1086,7 +1086,7 @@ class Form implements \IteratorAggregate, FormInterface $value = $transformer->transform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to transform value for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to transform value for property path "%s": ', $this->getPropertyPath()).$exception->getMessage(), $exception->getCode(), $exception); } return $value; @@ -1112,7 +1112,7 @@ class Form implements \IteratorAggregate, FormInterface $value = $transformers[$i]->reverseTransform($value); } } catch (TransformationFailedException $exception) { - throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": '.$exception->getMessage(), $this->getPropertyPath()), $exception->getCode(), $exception); + throw new TransformationFailedException(sprintf('Unable to reverse value for property path "%s": ', $this->getPropertyPath()).$exception->getMessage(), $exception->getCode(), $exception); } return $value; From a337ba55474f45c93d77a640268abe79e1bf2d3a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 30 May 2020 20:30:09 +0200 Subject: [PATCH 14/16] [HttpClient] fix issues in tests --- .travis.yml | 1 + .../DataCollector/HttpClientDataCollectorTest.php | 12 +++++++----- .../HttpClient/Tests/HttplugClientTest.php | 2 -- .../Component/HttpClient/Tests/Psr18ClientTest.php | 2 -- .../Contracts/HttpClient/Test/TestHttpServer.php | 13 +++++++------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5d6c2159a6..fc26dc6491 100644 --- a/.travis.yml +++ b/.travis.yml @@ -151,6 +151,7 @@ before_install: INI=~/.phpenv/versions/$PHP/etc/conf.d/travis.ini echo date.timezone = Europe/Paris >> $INI echo memory_limit = -1 >> $INI + echo default_socket_timeout = 10 >> $INI echo session.gc_probability = 0 >> $INI echo opcache.enable_cli = 1 >> $INI echo apc.enable_cli = 1 >> $INI diff --git a/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php b/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php index d173c17250..b578710546 100755 --- a/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php +++ b/src/Symfony/Component/HttpClient/Tests/DataCollector/HttpClientDataCollectorTest.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +namespace Symfony\Component\HttpClient\Tests\DataCollector; + use PHPUnit\Framework\TestCase; use Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector; use Symfony\Component\HttpClient\NativeHttpClient; @@ -19,9 +21,13 @@ use Symfony\Contracts\HttpClient\Test\TestHttpServer; class HttpClientDataCollectorTest extends TestCase { - public function testItCollectsRequestCount() + public static function setUpBeforeClass(): void { TestHttpServer::start(); + } + + public function testItCollectsRequestCount() + { $httpClient1 = $this->httpClientThatHasTracedRequests([ [ 'method' => 'GET', @@ -50,7 +56,6 @@ class HttpClientDataCollectorTest extends TestCase public function testItCollectsErrorCount() { - TestHttpServer::start(); $httpClient1 = $this->httpClientThatHasTracedRequests([ [ 'method' => 'GET', @@ -80,7 +85,6 @@ class HttpClientDataCollectorTest extends TestCase public function testItCollectsErrorCountByClient() { - TestHttpServer::start(); $httpClient1 = $this->httpClientThatHasTracedRequests([ [ 'method' => 'GET', @@ -113,7 +117,6 @@ class HttpClientDataCollectorTest extends TestCase public function testItCollectsTracesByClient() { - TestHttpServer::start(); $httpClient1 = $this->httpClientThatHasTracedRequests([ [ 'method' => 'GET', @@ -146,7 +149,6 @@ class HttpClientDataCollectorTest extends TestCase public function testItIsEmptyAfterReset() { - TestHttpServer::start(); $httpClient1 = $this->httpClientThatHasTracedRequests([ [ 'method' => 'GET', diff --git a/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php b/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php index 66a8cef6e7..6a8cadbbc8 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php @@ -22,8 +22,6 @@ use Symfony\Contracts\HttpClient\Test\TestHttpServer; class HttplugClientTest extends TestCase { - private static $server; - public static function setUpBeforeClass(): void { TestHttpServer::start(); diff --git a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php index 42e627b590..1ef36fc5bd 100644 --- a/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php @@ -21,8 +21,6 @@ use Symfony\Contracts\HttpClient\Test\TestHttpServer; class Psr18ClientTest extends TestCase { - private static $server; - public static function setUpBeforeClass(): void { TestHttpServer::start(); diff --git a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php index 0adb1a52a3..cfc100d80c 100644 --- a/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php +++ b/src/Symfony/Contracts/HttpClient/Test/TestHttpServer.php @@ -19,12 +19,12 @@ use Symfony\Component\Process\Process; */ class TestHttpServer { - private static $started; + private static $process; public static function start() { - if (self::$started) { - return; + if (self::$process) { + self::$process->stop(); } $finder = new PhpExecutableFinder(); @@ -32,9 +32,10 @@ class TestHttpServer $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); $process->start(); - register_shutdown_function([$process, 'stop']); - sleep('\\' === \DIRECTORY_SEPARATOR ? 10 : 1); + do { + usleep(50000); + } while (!@fopen('http://127.0.0.1:8057/', 'r')); - self::$started = true; + self::$process = $process; } } From d8f282edca9f58bfab51d4300683e40c9423db84 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 30 May 2020 20:58:05 +0200 Subject: [PATCH 15/16] Various cleanups --- src/Symfony/Component/Console/Helper/ProcessHelper.php | 2 +- .../Component/DependencyInjection/EnvVarProcessor.php | 2 +- .../Form/Resources/translations/validators.hu.xlf | 2 +- .../Intl/Data/Bundle/Reader/JsonBundleReader.php | 2 +- .../Component/Ldap/Adapter/ExtLdap/EntryManager.php | 8 ++++---- .../Serializer/Normalizer/DateTimeNormalizer.php | 2 +- .../Component/Translation/Loader/XliffFileLoader.php | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/ProcessHelper.php b/src/Symfony/Component/Console/Helper/ProcessHelper.php index 951bb854ec..6cafb1face 100644 --- a/src/Symfony/Component/Console/Helper/ProcessHelper.php +++ b/src/Symfony/Component/Console/Helper/ProcessHelper.php @@ -38,7 +38,7 @@ class ProcessHelper extends Helper public function run(OutputInterface $output, $cmd, $error = null, callable $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) { if (!class_exists(Process::class)) { - throw new \LogicException('The Process helper requires the "Process" component. Install "symfony/process" to use it.'); + throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".'); } if ($output instanceof ConsoleOutputInterface) { diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php index 3410103764..cc9fa3b390 100644 --- a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php +++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php @@ -125,7 +125,7 @@ class EnvVarProcessor implements EnvVarProcessorInterface $env = json_decode($env, true); if (JSON_ERROR_NONE !== json_last_error()) { - throw new RuntimeException(sprintf('Invalid JSON in env var "%s": '.json_last_error_msg(), $name)); + throw new RuntimeException(sprintf('Invalid JSON in env var "%s": ', $name)).json_last_error_msg(); } if (!\is_array($env)) { diff --git a/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf b/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf index b53f16d6ae..bc7f6055e4 100644 --- a/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf +++ b/src/Symfony/Component/Form/Resources/translations/validators.hu.xlf @@ -17,7 +17,7 @@ This value is not a valid HTML5 color. Ez az érték nem egy érvényes HTML5 szín. - + diff --git a/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php b/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php index 555dd377c9..1d0cfbad0d 100644 --- a/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php +++ b/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php @@ -46,7 +46,7 @@ class JsonBundleReader implements BundleReaderInterface $data = json_decode(file_get_contents($fileName), true); if (null === $data) { - throw new RuntimeException(sprintf('The resource bundle "%s" contains invalid JSON: '.json_last_error_msg(), $fileName)); + throw new RuntimeException(sprintf('The resource bundle "%s" contains invalid JSON: ', $fileName).json_last_error_msg()); } return $data; diff --git a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php index 789672e7b2..26f99fc9ca 100644 --- a/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php +++ b/src/Symfony/Component/Ldap/Adapter/ExtLdap/EntryManager.php @@ -38,7 +38,7 @@ class EntryManager implements EntryManagerInterface, RenameEntryInterface $con = $this->getConnectionResource(); if (!@ldap_add($con, $entry->getDn(), $entry->getAttributes())) { - throw new LdapException(sprintf('Could not add entry "%s": '.ldap_error($con), $entry->getDn())); + throw new LdapException(sprintf('Could not add entry "%s": ', $entry->getDn()).ldap_error($con)); } return $this; @@ -52,7 +52,7 @@ class EntryManager implements EntryManagerInterface, RenameEntryInterface $con = $this->getConnectionResource(); if (!@ldap_modify($con, $entry->getDn(), $entry->getAttributes())) { - throw new LdapException(sprintf('Could not update entry "%s": '.ldap_error($con), $entry->getDn())); + throw new LdapException(sprintf('Could not update entry "%s": ', $entry->getDn()).ldap_error($con)); } } @@ -64,7 +64,7 @@ class EntryManager implements EntryManagerInterface, RenameEntryInterface $con = $this->getConnectionResource(); if (!@ldap_delete($con, $entry->getDn())) { - throw new LdapException(sprintf('Could not remove entry "%s": '.ldap_error($con), $entry->getDn())); + throw new LdapException(sprintf('Could not remove entry "%s": ', $entry->getDn()).ldap_error($con)); } } @@ -76,7 +76,7 @@ class EntryManager implements EntryManagerInterface, RenameEntryInterface $con = $this->getConnectionResource(); if (!@ldap_rename($con, $entry->getDn(), $newRdn, null, $removeOldRdn)) { - throw new LdapException(sprintf('Could not rename entry "%s" to "%s": '.ldap_error($con), $entry->getDn(), $newRdn)); + throw new LdapException(sprintf('Could not rename entry "%s" to "%s": ', $entry->getDn(), $newRdn).ldap_error($con)); } } diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index 3217bc38be..fef57d120d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -101,7 +101,7 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface $dateTimeErrors = \DateTime::class === $type ? \DateTime::getLastErrors() : \DateTimeImmutable::getLastErrors(); - throw new NotNormalizableValueException(sprintf('Parsing datetime string "%s" using format "%s" resulted in %d errors:.'."\n".'%s', $data, $dateTimeFormat, $dateTimeErrors['error_count'], implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors'])))); + throw new NotNormalizableValueException(sprintf('Parsing datetime string "%s" using format "%s" resulted in %d errors: ', $data, $dateTimeFormat, $dateTimeErrors['error_count'])."\n".implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors']))); } try { diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index 0a6ff16b17..14a2668c27 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -194,7 +194,7 @@ class XliffFileLoader implements LoaderInterface if (!@$dom->schemaValidateSource($schema)) { libxml_disable_entity_loader($disableEntities); - throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: '.implode("\n", $this->getXmlErrors($internalErrors)), $file)); + throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: ', $file).implode("\n", $this->getXmlErrors($internalErrors))); } libxml_disable_entity_loader($disableEntities); From d6966c3147fd145248095034bfa8f395485e11b7 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Sat, 30 May 2020 21:50:06 +0200 Subject: [PATCH 16/16] Fix abstract method name in PHP doc block --- src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 2a715e35d7..10bddfbc94 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -22,7 +22,7 @@ use Symfony\Component\Routing\RouteCollection; /** * AnnotationClassLoader loads routing information from a PHP class and its methods. * - * You need to define an implementation for the getRouteDefaults() method. Most of the + * You need to define an implementation for the configureRoute() method. Most of the * time, this method should define some PHP callable to be called for the route * (a controller in MVC speak). *