Symfony嵌入式表单验证

时间:2017-03-14 13:44:22

标签: php symfony validation symfony-forms symfony-validator

我有几个实体,它们以单一形式使用,从一个抽象类扩展而来。 我为每个实体创建了一个表单类型,然后将它们嵌入到父表单中。

我想基于组执行验证,因此EmailType必须检查" elemento"属性仅在Assert \ NotBlank(默认组)和Assert \ Email(电子邮件组)上,Telefono必须检查Assert \ NotBlank(默认组)和Assert \ Regex(电话组)。

使用我的配置执行两项检查(约束),因此在电子邮件约束和正则表达式上检查电子邮件,因此电话归档是......我哪里错了?

收集电子邮件和电话上的员工实体已配置Assert \ Valid()禁令

这是示例

父表格

<?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']]);

    }

}

然后是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'])

    }

}

电子邮件和Telefono都延伸

<?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 个答案:

答案 0 :(得分:1)

AFAIK您无法在validation_groups表单字段上设置CollectionType(相应的,您可以设置它,但它没有效果),所以整个表单,包括子集集合中的表单总是在整个父表单上设置validation_groups进行验证。

validation_groups的目的是允许为不同目的修改对象属性的约束(例如,创建新的与编辑存在的对象),但不是上面描述的内容。 考虑一下,如果可能的话,直接在Staff对象(或StaffType)中使用您当前的Email和Telephono作为属性,使用validation_groups来解决$ elemento应该是Email elemento一次和Telephono elemento一次。 ..

您的案例的解决方案是将Email和Telephono定义为不同的类(不是从AbstractElementoContact继承),并为每个类定义特定的约束。