У меня есть некоторые проблемы с обработкой проверки формы Symfony. Я хотел бы проверить форму, привязанную к сущности на основе ее данных. Существует довольно много информации о том, как динамически изменять поля с помощью FormEvents. То, что мне не хватает в этом разделе, - это управление/изменение проверки.
Мой упрощенный вариант использования:
- Пользователь может добавить событие в календарь.
- Проверка проверяет, есть ли уже событие.
- Если есть столкновение, проверка приведет к ошибке.
- Пользователь должен теперь игнорировать эту ошибку/предупреждение.
Валидация реализуется как Validator
с Constraint::CLASS_CONSTRAINT
в качестве цели (поскольку она учитывает некоторые другие вещи).
Я попытался:
- Взломайте группы проверки, но не смогли найти доступ к валидаторам сущности.
- Взломайте
FormEvents
и добавьте дополнительное поле, например "Предупреждение о предупреждении даты". - Взломайте кнопку отправки, чтобы изменить ее на что-то вроде "Force submit".
... но так и не нашел рабочего решения. Даже более простые хаки с единственным средством проверки подлинности на основе свойств не сработали.: (
Есть ли способ Symfony для динамического управления проверкой?
Изменить: мой код выглядит следующим образом:
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';
}
}
Изменить 2: Попробуйте с помощью FormEvents
... Я также пробовал все разные события.
$form = $formFactory->createBuilder()
->add('title', 'text')
->add('date', 'date')
->addEventListener(FormEvents::WHICHONE?, function(FormEvent $event) {
$form = $event->getForm();
// WHAT TO DO HERE?
$form->getErrors(); // Is always empty as all events run before validation?
// I need something like
if (!$dateIsValid) {
$form->setValidationGroup('ignoreWarning');
}
});
Изменить 3: Правильно объявлены ограничения. Это не проблема:
services:
validator.acme.date:
class: AcmeBundle\Validator\Constraints\DateValidator
arguments: ["@acme.other_service"]
tags:
- { name: validator.constraint_validator, alias: acme.validator.appointment.date }