1
votes

I have several Entities, that are used in a single form, that extends from an abstract class. I have created a form type for each entity and then they were embedded in a parent form.

I would like to perform validation based on groups, so the EmailType must check the "elemento" property only on Assert\NotBlank (Default group) and Assert\Email (email group), and Telefono must check Assert\NotBlank (Default group) and Assert\Regex (phone group).

With my configuration both checks (constraints) are performed, so email are checked on Email constraint AND Regex, and so the phone filed is... Where am i wrong?

Staff Entity on Collection emails and phones have configured the Assert\Valid() contraint

This is the example

Parent Form

<?php
namespace App\Form\Staff;

class StaffType extends AbstractType {

     public function configureOptions(OptionsResolver $resolver) {
           $resolver->setDefaults(['data_class' => \Cowbell\Entity\Staff\Staff::class,
                     'validation_groups' => ['Default', 'email', 'phone']]);
}
    /**
     * 
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {


        // ... Other field of Staff Entity

        ->add('emails', CollectionType::class, ['label' => 'admin.emails',
                'entry_type' => \App\Form\Contatto\CBEmailType::class,
                'entry_options' => ['label' => false],
                'allow_add' => true,
                'allow_delete' => true,
                'empty_data' => null,
                'translation_domain' => 'admin',
                'validation_groups' => ['email']])
            ->add('telefoni', CollectionType::class, ['label' => 'admin.phones',
                'entry_type' => \App\Form\Contatto\CBTelefonoType::class,
                'entry_options' => ['label' => false],
                'allow_add' => true,
                'allow_delete' => true,
                'empty_data' => null,
                'translation_domain' => 'admin',
                'validation_groups' => ['phone']]);

    }

}

Then CBEmailType

<?php
namespace App\Form\Contatto;

class CBEmailType extends AbstractType{

    /**
     * 
     * @param OptionsResolver $resolver
     */
    public function configureOptions( OptionsResolver $resolver)
    {
        $resolver->setDefaults(['data_class' => \App\Entity\Contatto\Email::class,
        'validation_groups' => ['Default', 'email']]);;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder->add('elemento', EmailType::class, ['label' => 'admin.email',
                  'translation_domain' => 'admin'])

    }

}

CBTelefonoType

<?php
namespace App\Form\Contatto;

class CBTelefonoType extends AbstractType{

    /**
     * 
     * @param OptionsResolver $resolver
     */
    public function configureOptions( OptionsResolver $resolver)
    {
        $resolver->setDefaults(['data_class' => \Cowbell\Entity\Contatto\Telefono::class,
        'validation_groups' => ['Default', 'phone']]);
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder->add('elemento', TextType::class, ['label' => 'admin.phone',
                'translation_domain' => 'admin'])

    }

}

Both, Email and Telefono extend

<?php
namespace App\Entity\Contact;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

abstract class AbstractElementoContact {


    /**
     * 
     * @var string
     *
     * @ORM\Column(name="elemento", type="string", length=100, nullable=false)
     * @Assert\NotBlank()
     * @Assert\Email(strict=true, checkHost=true, checkMX=true, groups={"email"})
     * @Assert\Regex("/[0-9]{6,50}/", groups={"phone"})
     */
    protected $elemento;
1

1 Answers

1
votes

AFAIK you can't set validation_groups on CollectionType form field (resp. you can set it, but it has no effect), so the whole form, including the set of sub-forms in the collection is allways validated with validation_groups set on the whole parent form.

The purpose of validation_groups is to allow constraints modification of object's properties for different purposes (e.g. creating new vs. editing existing), but not for what you described above. Think about, if it would be possible, to use your current Email and Telephono as a property directly in the Staff object (or StaffType respectivelly) with using validation_groups to solve the $elemento should be Email elemento once and Telephono elemento once...

The solution for your case is to define Email and Telephono as different classes (not inherited from AbstractElementoContact) with specific contraint for each of them.