У меня есть форма со многими полями и группами проверки, эти поля также содержат некоторые преобразователи данных представления.
Мне нужно подавить форму проверки частично (Группы на основе представленных данных):
use AppBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => function (FormInterface $form) {
$data = $form->getData();
if (Client::TYPE_PERSON == $data->getType()) {
return array('person');
}
return array('company');
},
));
}
Когда вы это сделаете, форма все равно будет выполнять базовые проверки целостности (Отключение проверки) и ошибки проверки, исходящие от трансформаторов, которые они выбрасывают до сих пор (Создание Трансформера).
Использовать POST_SUBMIT
событие и предотвратить ValidationListener от вызова (Подавление проверки формы):
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$event->stopPropagation();
}, 900); // Always set a higher priority than ValidationListener
// ...
}
Это не решение для меня, так как случайно отключить что-то большее, чем просто проверка формы.
Вопрос в том: Как отключить одну ошибку проверки трансформатора «динамически»?
Пример:
У меня есть поле формы RepeatedType
принадлежность к person
группа проверки и содержит преобразователь представления (RepeatedType) этот преобразователь выдает исключение, когда значения в массиве у них не совпадают (ValueToDuplicatesTransformer).
Таким образом, даже когда группа проверки company
, форма показывает ошибки, принадлежащие RepeatedType
поле идет от трансформатора им.
Вопрос здесь: Как отключить ValueToDuplicatesTransformer
ошибки, когда группа проверки не person
?
Поскольку buildForm
пропускает код, связанный с добавлением полей, я предполагаю:
data_class
напрямую, но установите значения в вашем контроллереrepeated
тип имеет required => true
как вариант и есть, чтобы подтвердить пароль $data
который передается в formbuilder содержит значение для repeated
поле.Проблема в основном в том, что проверка запускается. Если есть какие-либо данные, то тип всегда выполняет базовые проверки (повторяющееся поле должно иметь одно и то же значение дважды).
Чтобы решить эту проблему, не передавайте значение $data
во-первых, и убедитесь, required => false
для повторного поля. Ваша форма будет выполнять только проверку группы после этого, как вы уже объяснили.
Может быть, самое надежное решение даже отличается, и было бы лучше сделать два FormTypes
вместо использования groups
, Это устранит большую часть сложности, которую вы описываете в своем вопросе.
Вы не можете действительно деактивировать ошибки от DataTransformer, эти ошибки добавляются FormValidator и это поведение не настраивается. Это вполне логично, поскольку ошибки преобразования приводят к тому, что данные модели находятся в поврежденном состоянии.
В этом случае я бы использовал поле 2 вместо повторяющегося поля со вторым полем с mapped => false
и прослушиватель событий, который добавляет ошибку вручную, когда это необходимо.
Может быть, я ошибаюсь, но группа проверки не является правильным инструментом для решения проблемы вообще. Зависимость правил валидации, которую вы хотите решить, основана на данных, в то время как группа валидации не об этом, а о том, что одни и те же данные проверяются по-разному в зависимости от контекста.
Если вы хотите применить некоторые правила только для человека (или, наоборот, только для компании), я бы предпочел реализовать пользовательскую проверку в Client Entity
namespace AppBundle\Entity;
class Client {
....
/**
* @Assert\IsTrue(message="Person should have a valid Title")
*/
public function isPersonTitleValid()
{
return $this->type != Client::TYPE_PERSON || $this->isTitleValid();
}
public function isTitleValid()
{
// Here implement your validation applicable only for person;
}