diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 69fc8a1b3f..219babdb67 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.3 +--- + + * Add `Validation::createIsValidCallable()` that returns true/false instead of throwing exceptions + 5.2.0 ----- diff --git a/src/Symfony/Component/Validator/Tests/ValidationTest.php b/src/Symfony/Component/Validator/Tests/ValidationTest.php index 1a331cf4e3..880294e25b 100644 --- a/src/Symfony/Component/Validator/Tests/ValidationTest.php +++ b/src/Symfony/Component/Validator/Tests/ValidationTest.php @@ -30,7 +30,29 @@ class ValidationTest extends TestCase public function testCreateCallableInvalid() { $validator = Validation::createCallable(new Email()); - $this->expectException(ValidationFailedException::class); - $validator('test'); + try { + $validator('test'); + $this->fail('No ValidationFailedException thrown'); + } catch (ValidationFailedException $e) { + $this->assertEquals('test', $e->getValue()); + + $violations = $e->getViolations(); + $this->assertCount(1, $violations); + $this->assertEquals('This value is not a valid email address.', $violations->get(0)->getMessage()); + } + } + + public function testCreateIsValidCallableValid() + { + $validator = Validation::createIsValidCallable(new Email()); + $this->assertTrue($validator('test@example.com')); + } + + public function testCreateIsValidCallableInvalid() + { + $validator = Validation::createIsValidCallable(new Email()); + $this->assertFalse($validator('test', $violations)); + $this->assertCount(1, $violations); + $this->assertEquals('This value is not a valid email address.', $violations->get(0)->getMessage()); } } diff --git a/src/Symfony/Component/Validator/Validation.php b/src/Symfony/Component/Validator/Validation.php index ca80c0597a..4d08072779 100644 --- a/src/Symfony/Component/Validator/Validation.php +++ b/src/Symfony/Component/Validator/Validation.php @@ -25,8 +25,30 @@ final class Validation * Creates a callable chain of constraints. * * @param Constraint|ValidatorInterface|null $constraintOrValidator + * + * @return callable($value) */ public static function createCallable($constraintOrValidator = null, Constraint ...$constraints): callable + { + $validator = self::createIsValidCallable($constraintOrValidator, ...$constraints); + + return static function ($value) use ($validator) { + if (!$validator($value, $violations)) { + throw new ValidationFailedException($value, $violations); + } + + return $value; + }; + } + + /** + * Creates a callable that returns true/false instead of throwing validation exceptions. + * + * @param Constraint|ValidatorInterface|null $constraintOrValidator + * + * @return callable($value, &$violations = null): bool + */ + public static function createIsValidCallable($constraintOrValidator = null, Constraint ...$constraints): callable { $validator = $constraintOrValidator; @@ -39,13 +61,10 @@ final class Validation $validator = $validator ?? self::createValidator(); - return static function ($value) use ($constraints, $validator) { + return static function ($value, &$violations = null) use ($constraints, $validator) { $violations = $validator->validate($value, $constraints); - if (0 !== $violations->count()) { - throw new ValidationFailedException($value, $violations); - } - return $value; + return 0 === $violations->count(); }; }