gpt4 book ai didi

forms - [Symfony][Form] 仅当属性发生变化时才向属性添加验证器/约束

转载 作者:行者123 更新时间:2023-12-03 18:19:33 25 4
gpt4 key购买 nike

我有以下场景:我正在验证约会,并且有一个自定义验证器,它告诉用户他选择的日期是否有效。如果日期已被另一个实体阻止,则无效。这在添加新实体时完美无缺。

现在,我想仅在日期本身已更改时触发编辑时的日期验证。因此,仅更改约会的标题不应验证日期。

我的实体类:

use Doctrine\ORM\Mapping as ORM;
use Acme\Bundle\Validator\Constraints as AcmeAssert;

/**
* Appointment
*
* @ORM\Entity
* @AcmeAssert\DateIsValid
*/
class Appointment
{
/**
* @ORM\Column(name="title", type="string", length=255)
*
* @var string
*/
protected $title;

/**
* @ORM\Column(name="date", type="date")
*
* @var \DateTime
*/
protected $date;
}

验证器类(用作服务):
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the date of an appointment.
*/
class DateIsValidValidator extends ConstraintValidator
{
/**
* {@inheritdoc}
*/
public function validate($appointment, Constraint $constraint)
{
if (null === $date = $appointment->getDate()) {
return;
}

/* Do some magic to validate date */
if (!$valid) {
$this->context->addViolationAt('date', $constraint->message);
}
}
}

相应的 Constraint 类设置为针对实体类。
use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*/
class DateIsValid extends Constraint
{
public $message = 'The date is not valid!';

/**
* {@inheritdoc}
*/
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}

/**
* {@inheritdoc}
*/
public function validatedBy()
{
return 'acme.validator.appointment.date';
}
}

现在我找不到依赖日期更改的干净方法。我可以简单地在我的实体中跟踪旧日期,但如果我想实现更复杂的约束,这感觉不是一个合适的解决方案。 :[

干杯

最佳答案

从 symfony 2.3 开始,您可以使用 Form Events来解决这个问题。通过在创建表单时存储(和克隆)原始实体,我将更改检查代码添加到我的 FormType。

然后添加一个 POST_SUBMIT 事件监听器来检查字段是否已更改。监听器可以向您的字段添加验证错误。

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormError;
use Acme\Bundle\Entity\Appointment;

class AppointmentType extends AbstractType
{
private $originalAppointment;

public function __construct(Appointment $original)
{
// save the original entity
$this->originalAppointment = clone $original;
}

// ...

public function buildForm(FormBuilderInterface $builder, array $options)
{
// define your fields

$builder->addEventListener(FormEvents::POST_SUBMIT, [$this, 'dateCheckListener']);
}

public function dateCheckListener(FormEvent $event)
{
$appointment = $event->getData();
$form = $event->getForm();

// if no appointments exist, we can skip the check
if (empty($appointment) || empty($this->originalAppointment)) {
return;
}

if ($appointment->getDate() !== $this->originalAppointment->getDate()) {

// the dates changed, you can call your validator here

if ('dates are not valid') {
$form->get('date')->addError(new FormError('We have a problem.'));
}
}
}
}

在您的 Controller 中,您可以使用原始约会创建此 formType:
$appointment = $this->getYourAppointmentSomehow();

$form = $this->createForm(new AppointmentType($appointment), $appointment);

关于forms - [Symfony][Form] 仅当属性发生变化时才向属性添加验证器/约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23516323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com