forms - Symfony 检查表单验证时两个字段中的至少一个是否不为空
问题描述
我已经在脑海中扭转了很长一段时间,但仍然无法找到解决问题的方法。使用 Symfony 4 表单和约束我无法设置检查以说明在提交包含子表单的表单时,两个字段中的至少一个不能为空。
我有一个 Booking 实体,其中包含一个具有 phoneNumber 属性和 email 属性的 Visitor 实体。我希望能够创建一个具有“访问者”CollectionType 的 Booking(允许我从 BookingType 表单添加访问者)。
我的 BookingType 表格(有点简化):
class BookingType extends AbstractType
{
private $router;
private $translator;
public function __construct(UrlGeneratorInterface $router, TranslatorInterface $translator)
{
$this->router = $router;
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('bookableTimeSlot', EntityType::class, [
'label' => 'entity.booking.bookable-time-slot',
'class' => BookableTimeSlot::class,
'choice_label' => function ($bookableTimeSlot) {
return $bookableTimeSlot->getStartDateTime()->format('d.m.Y h\hi');
}
])
->add('visitors', CollectionType::class, [
'entry_type' => VisitorType::class,
'label' => 'entity.booking.visitors',
'allow_add' => true,
'by_reference' => false,
'entry_options' => ['label' => false]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Booking::class,
'user' => User::class,
]);
}
}
我的访客实体(有点简化):
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* @ORM\Entity(repositoryClass="App\Repository\VisitorRepository")
*/
class Visitor
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $firstName;
/**
* @ORM\Column(type="string", length=255)
*/
private $lastName;
/**
* @ORM\Column(type="string", length=45, nullable=true)
*/
private $phone;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Booking", inversedBy="visitors")
* @ORM\JoinColumn(nullable=false)
*/
private $booking;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $email;
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(string $phone): self
{
$this->phone = $phone;
return $this;
}
public function getBooking(): ?Booking
{
return $this->booking;
}
public function setBooking(?Booking $booking): self
{
$this->booking = $booking;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
}
最后是我的 VisitorType 表格(有点简化):
class VisitorType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName', TextType::class, [
'label' => 'entity.visitor.first-name',
])
->add('lastName', TextType::class, [
'label' => 'entity.visitor.last-name',
])
->add('phone', TextType::class, [
'label' => 'entity.visitor.phone-number',
'required' => false,
])
->add('email', TextType::class, [
'label' => 'entity.visitor.email',
'required' => false,
'constraints' => [
new Email()
]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Visitor::class,
]);
}
}
我尝试向电子邮件和电话字段添加一个表达式约束,如下所示:
new Expression([
'expression' => 'this.getPhone() == null && this.getEmail() == null'
])
还尝试直接向实体添加约束,但对我来说似乎没有任何效果。
任何帮助将不胜感激。
更新我没有指定这一点,但我的问题来自这样一个事实,即我想从另一个将 VisitorType 添加为 CollectionType 的表单验证 VisitorType 表单。
解决方案
尝试回调
/**
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context, $payload)
{
if (null === $this->getEmail() && null === $this->getPhone())
$context->buildViolation('Your message here.')
->atPath('email')
->addViolation();
// you can add onther "if" if you like
}
推荐阅读
- php - 我的 LogIn PHP 表单不起作用。我相信我的 $hash = $row['password']; 是问题,但我不太确定
- typescript-compiler-api - Typescript编译器,如何按名称获取导出的符号?
- reactjs - 从 react-router-dom url 中删除哈希
- c - C中的(int)-1和(-1)有什么区别?
- jquery - 添加/删除 Cocoon 嵌套字段
- dask - 将 150 万张图像加载到 dask 集群中的最快方法
- python - 在类中使用 len() *inside* 的正确方法是什么?
- pip - `anaconda3/bin` 和 `anaconda3/lib/python3.7/` 下的包有什么区别?
- php - Postgres COPY ... FROM PROGRAM 失败。权限没问题
- javascript - 无需上传即可检索文件数据(Express、Multer)