I have code that looks more or less like this:
It’s not my actual code, but just to show the concept of what I’m trying to do:
I have a form where each individual field is required and then some checks are run on the values of multiple fields in combination.
class testForm extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault(
'constraints',
[new Callback(
['callback' => function (
$payload,
ExecutionContextInterface $context
)
{
$data = $context->getObject()->getData();
if (strcasecmp($data['field1'], $data['field2']))
{
$context
->buildViolation('fields must be equal')
->atPath('[field1]')
->addViolation();
}
}
]
)]
);
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('field1', TextType::class, ['constraints' => [new NotBlank]])
->add('field2', TextType::class, ['constraints' => [new NotBlank]]);
}
}
The problem I’m having with this code is that it will throw a notice when you submit with empty fields (null is not allowed as parameters for string functions like strcasecmp() since PHP 8.0).
AFAICT this is because the parent validation runs before the child validation, so it only checks if the fields have values after the upper level validation has run.
What I am looking for is a way to reverse this, i.e. run the child validation before the parent validation is called. Looking at the Symfony documentation, there’s a Valid constraint that seems to do exactly that, but it only seems to work with entities (my form doesn’t use an entity, but a simple DTO).
So I remain wondering about a way to either make Valid work without entities, or some other way to remedy the constraints of doing this.