Search code examples
validationsymfonycallbackassert

add Symfony Assert in a Callback


I, i have to add an Assert to an atribute when other atribute is equal than something. Like this:

/**
* @Assert\Callback(methods={"isChildMinor",)
*/
class PatientData
{
/**
 * @Assert\Date()
 */
public $birthday;

public $role;

public function isChildMinor(ExecutionContext $context)
{
    if ($this->role == 3 && check @assert\isMinor() to $birtday) {
    =>add violation
    }
}

so, i want check if the patient is minor (with assert or somethings else) if the role is equal than 3. How do this?


Solution

  • There are several ways to do, what you want.

    1) You could make it right in the form. Like that:

    use Symfony\Component\Validator\Constraints as Assert;
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
      $yourEntity = $builder->getData();
      //here you start the field, you want to validate
      $fieldOptions = [
         'label'     => 'Field Name',
          'required' => true,
      ];
      if ($yourEntity->getYourProperty != 'bla-bla-bla') {
        $fieldOptions[] = 'constraints' => [
           new Assert\NotBlank([
              'message' => 'This is unforgivable! Fill the field with "bla-bla-bla" right now!',
           ]),
        ],
      }
      $builder->add('myField', TextType::class, $fieldOptions);
    

    2) Other way - is to make your custom validation callback in your Entity and play with direct asserts there. It's possible, I think.

    3) But the optimal way, from my point of view - is to use several asserts with validation groups. You need to specify Assert\isMinor(groups={"myCustomGroup"}) on birthday field. And then, in your form:

    public function configureOptions(OptionsResolver $resolver)
    {
      $resolver->setDefaults([
         'validation_groups' => function (FormInterface $form) {
            $yourEntity = $form->getData();
            if ($yourEntity->role !== 3) {
                return ['Default', 'myCustomGroup'];
            }
            return ['Default'];
         },
    

    Hope this'll be helpful for you.