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..
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.
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