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?
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With