MSchmidt
MSchmidt

Reputation: 35

Symfony Validator does not work with nested AtLeastOneOf Constraint

In following code (condensed from a project) the validation for $constraint2 returns no error, which is not the behaviour I expect (should also return errors):

    use Symfony\Component\Validator\Validation;
    use Symfony\Component\Validator\Constraints\Type;
    use Symfony\Component\Validator\Constraints\AtLeastOneOf;
    
    $config = 1; //Integer
    $constraint1 = new AtLeastOneOf([ new Type('string') ]);
    $constraint2 = new AtLeastOneOf([ new AtLeastOneOf([ new Type('string') ]) ]);
    
    $validator = Validation::createValidator();
    echo "Constraint 1: ".(count($validator->validate($config,$constraint1))).'<br>';
    echo "Constraint 2: ".(count($validator->validate($config,$constraint2))).'<br>';

Output:

Constraint 1: 1
Constraint 2: 0

The problem seems to be the nested AtLeastOneOf validator, but I do not understand why it does validate to no errors.

Upvotes: 1

Views: 137

Answers (1)

Dylan KAS
Dylan KAS

Reputation: 5693

This behavior was indeed not expected, so I looked into it. As of today, it seems that there is an issue with nested AtLeastOneOf constraint as you can see from this issue from symfony/symfony.

You probably do not want to wait for a fix so maybe the only way to fix it now is to

Replace your deeply nested AtLeastOneOf constraint

Let's say your constraint is:

    $constraints = [
        new AtLeastOneOf(
            [
                new Type('string'),
                new Type('datetime'),
                new AtLeastOneOf([ new Type('boolean'), new Type('string') ]),
            ])
    ];

You should be able to replace it with an equivalent constraint:

    $constraints = [
        new AtLeastOneOf(
            [
                new Type('string'),
                new Type('datetime'),
                new Type('boolean'),
                new Type('string'),
            ])
    ];

If two AtLeastOneOf constraint are nested, you should be able to put whatever is in the second one into the first one without changing its behavior.

Upvotes: 2

Related Questions