Reputation: 254886
Given this input:
[
'key' => 'value',
]
How to validate to ensure that:
key
attribute existsI expected this constraint to work
$constraint = new Collection([
'key' => new Required([
new Type('array'),
new Collection([
'value' => new Required([
new NotBlank(),
]),
]),
]),
]);
but it throws an exception:
Symfony\Component\Validator\Exception\UnexpectedTypeException: Expected argument of type "array or Traversable and ArrayAccess", "string" given
What am I missing?
PS: it's symfony v2.7.1
PPS: just to clarify: I know one can use a callback. If I wanted to re-implement the validation manually from scratch - I wouldn't have used symfony at the very first place. So the question is particularly about combining the existing constraints and not about using a callback constraint..
Upvotes: 8
Views: 2099
Reputation: 20193
I had the exact same problem two nights ago.
The conclusion at the very end was that Symfony2
validation has no "fast-fail" validation. That is, even if your Type()
constraint would fail it would proceed with other constraints and thus fail with UnexpectedTypeException
exception.
However, I was able to find a way to tackle that:
$constraint = new Collection([
'key' => new Required([
new Type(['type' => 'array']),
new Collection([
// Need to wrap fields into this
// in order to provide "groups"
'fields' => [
'value' => new Required([
new NotBlank(),
]),
],
'groups' => 'phase2' // <-- THIS IS CRITICAL
]),
]),
]);
// In your controller, service, etc...
$V = $this->get('validator');
// Checks everything by `Collection` marked with special group
$violations = $V->validate($data, $constraint);
if ( $violations->count()){
// Do something
}
// Checks *only* "phase2" group constraints
$violations = $V->validate($data, $constraint, 'phase2');
if ( $violations->count()){
// Do something
}
Hope that this helps a bit. Personally, I find it annoying that we need to do this. Some sort of "fast-fail" flag within validator
service would be much helpful.
Upvotes: 5
Reputation: 517
You're saying the Collection
constraint should just fail instead of throwing an exception because 'value'
is a string
and not an array
.
There is a recently logged Symfony bug for this: https://github.com/symfony/symfony/issues/14943
Upvotes: 2
Reputation: 10126
Use Callback
constraint(docs) where you can implement your custom validation logic.
The other way is to create custom constraint and validator classes. (docs)
Upvotes: 1