I have the following code:
class User { /** * @AssertType(type="string") * @AssertNotBlank() * @AssertEmail() * @AssertLength(max=255) */ public $email; }
This object is filled from an API call. When validation takes place and property is filled with array value instead of string then NotBlank, Email, and Length validations continuing to work and I get “UnexpectedTypeException”.
I want validation system just to add one error about wrong value type and stop there.
I’ve made custom constraint validator
class ChainConstraintValidator extends ConstraintValidator { /** * {@inheritdoc} */ public function validate($value, Constraint $constraint) { if (!$constraint instanceof ChainConstraint) { throw new UnexpectedTypeException($constraint, __NAMESPACE__.'All'); } $context = $this->context; $prevCount = $context->getViolations()->count(); $validator = $context->getValidator()->inContext($context); foreach ($constraint->constraints as $constraintStep) { $errors = $validator->validate($value, $constraintStep); if ($errors->getViolations()->count() > $prevCount) { break; } } } }
It works and I used it like this:
@ChainConstraint( @AssertType(type="string"), @AssertNotBlank(), @AssertEmail(), @AssertLength(max=255) )
I have a lot of such classes in my project. Is there any more beautiful and requiring less code a way to achieve this?
Advertisement
Answer
What about this :
$var = []; $constraints = [ new Type(['type'=>'string', 'groups'=> 'first-check']), new NotBlank(['groups'=> 'second-check']), new Email(['groups'=> 'second-check']), new Length(['min'=>2, 'groups'=> 'second-check'])] ; $groups = ['first-check', 'second-check']; $groupSequence = new GroupSequence($groups); $error = $validator->validate($var, $constraints, $groupSequence); if(count($error) > 0) { dd($error); // Contains 1 ConstraintViolation (Type) }