【问题标题】:Symfony Check if at least one of two fields isn't empty on form validation of CollectionTypeSymfony 在 CollectionType 的表单验证中检查两个字段中的至少一个是否不为空
【发布时间】:2020-04-07 17:30:57
【问题描述】:

在上一个问题 (Symfony Check if at least one of two fields isn't empty on form validation) 中,我曾向使用回调的表单验证寻求帮助。 @hous 给出的答案是正确的,但它不适用于 CollectionType 中的元素,这是我提出新问题的原因。

根据之前的回答,我做了以下事情:

这是我的“妈妈”表格:

class BookingVisitorType extends AbstractType
{
    private $router;
    private $translator;

    public function __construct()
    {
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('visitors', CollectionType::class, [
                'entry_type' => VisitorType::class,
                'label' => 'entity.booking.visitors',
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'by_reference' => false,
                'entry_options' => [
                    'label' => false,
                    'delete-url' => $options['visitor-delete-url']
                ],
                'constraints' =>[
                    new Count([
                        'min' => 1,
                        'minMessage' => 'validator.visitor.at-least-one-visitor',
                        'max' => $options['numberOfPlaces'],
                        'maxMessage' => 'validator.visitor.cannot-have-more-visitor-than-spaces',
                        'exactMessage' => 'validator.visitor.exact-message'
                    ])
                ]
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Booking::class,
            'numberOfPlaces' => 1,
            'visitor-delete-url' => ''
        ]);
    }
}

这是我的“儿子”表格:

class VisitorType extends AbstractType
{
    private $phone;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('firstName', TextType::class, [
                'label' => 'entity.visitor.first-name',
                'constraints' => [
                    new NotBlank(),
                    new Length([
                        'min' => 2,
                        'max' => 255
                    ]),
                    new Regex([
                        'pattern' => "/[\pL\s\-]*/",
                        'message' => 'validator.visitor.not-valide-first-name'
                    ])
                ]
            ])
            ->add('phone', TextType::class, [
                'label' => 'entity.visitor.phone-number',
                'required' => false,
                'constraints' => [
                    new Regex([
                        'pattern' => "/[0-9\s\.\+]*/",
                        'message' => 'validator.visitor.not-valide-phone-number'
                    ]),
                    new Callback(function($phone, ExecutionContextInterface $context){
                        $this->phone = $phone;
                    }),
                ]
            ])
            ->add('email', TextType::class, [
                'label' => 'entity.visitor.email',
                'required' => false,
                'constraints' => [
                    new Email(),
                    new Callback(function($email, ExecutionContextInterface $context){
                        if ($this->phone == null && $email == null) {
                            $context->buildViolation('validator.visitor.email-or-phone-required')->addViolation();
                        }
                    }),
                ]
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Visitor::class,
            'error_bubbling' => false,
            'delete-url' => '',
        ]);
    }
}

我的“预订”(缩短)课程:

/**
 * @ORM\Entity(repositoryClass="App\Repository\BookingRepository")
 */
class Booking
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Visitor", mappedBy="booking", orphanRemoval=true, cascade={"persist"})
     * @Assert\Valid
     */
    private $visitors;
}

最后是我的“访客”(缩短)课程:

/**
 * @ORM\Entity(repositoryClass="App\Repository\VisitorRepository")
 */
class Visitor
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=45, nullable=true)
     */
    private $phone;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $email;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Booking", inversedBy="visitors")
     * @ORM\JoinColumn(nullable=false)
     */
    private $booking;

    /**
    * @Assert\Callback
    */
    public function validateAtLeastEmailOrPhone(ExecutionContextInterface $context, $payload)
    {
        if ($this->getPhone() === null && $this->getEmail() === null) {
            $context->buildViolation('validator.visitor.email-or-phone-required-for-all')->addViolation();
        }
    }
}

我已经能够通过向我使用电话值的回调约束定义的访问者类型表单添加一个属性来解决该问题,然后使用电子邮件字段上的回调约束对其进行检查,但它似乎没有非常“好的做法”。

如果我只尝试调用回调约束,我会收到以下错误消息:“警告:get_class() 期望参数 1 是对象,给定字符串”

非常感谢任何帮助!

【问题讨论】:

    标签: forms constraints symfony4


    【解决方案1】:

    您可以创建自己的Constraint,而不是回调函数。那么 Check 就可以重用了。

    我一直在使用它来检查注册密码是否​​符合自定义规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多