Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony validator throws exception on invalid Collection

The symfony validator throws an exception when I attempt to validate a scalar using a Collection constraint. I would expect it to return a violation instead.

Example code:

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Collection;

$validator = Validation::createValidator();

$input = 'testtesttest';
$constraints = [
    new Collection([
        'fields' => [
            'one' => new Length(array('min' => 10))
        ]
    ])
];

$violationList = $validator->validate($input, $constraints);

throws

PHP Fatal error:  Uncaught Symfony\Component\Validator\Exception\UnexpectedTypeException: Expected argument of type "array or Traversable and ArrayAccess", "string" given in vendor/symfony/validator/Constraints/CollectionValidator.php:37

Am I doing something wrong here?

For other Constraint classes (e.g. NotBlank, Type) the validator adds to the violation list when it encounters something invalid. To have it throw an exception instead in the case of a Collection seems bizarre to me. Am I doing something obviously wrong?

like image 754
Cormac Parle Avatar asked Mar 18 '26 21:03

Cormac Parle


1 Answers

Sorry for responding a year after but I was stuck with the same issue.

The solution for me was to create a custom Validation Constraint.

Firstly you have to create a custom constraint: CustomCollection which will contain the following code (note that my class is extending the Collection constraint and not the default Constraint class):

<?php

namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraints\Collection;

class CustomCollection extends Collection
{
    public $message = 'You must provide an array.';
}

Then you have to implement your custom constraint's logic (in this case validate that your value is a valid array) :

<?php

namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\CollectionValidator;

class CustomCollectionValidator extends CollectionValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!\is_array($value)) {
            $this->context->buildViolation($constraint->message)
                ->addViolation();
            return;
        }
        parent::validate($value, $constraint);
    }
}

Now if I take your code as example, you have to change the constraint from Collection to CustomCollection in order to get a violation :

$input = 'testtesttest';
$constraints = [
    new CustomCollection([
        'fields' => [
            'one' => new Length(array('min' => 10))
        ]
    ])
];

$violationList = $validator->validate($input, $constraints);
like image 55
Nico Avatar answered Mar 21 '26 12:03

Nico



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!