Отключите проверку для типа формы, если в Symfony установлен флажок

Я пытаюсь создать форму адреса с адресом оплаты и доставки. Когда флажок на адресе доставки установлен, я хочу пропустить проверку формы на этом адресе.

Я создал тип формы ниже с опцией переключения, которая будет отображаться и иметь дело с флажком, однако форма все еще проверяется, даже если отмечен.

Symfony имеет документация о том, как реализовать такую ​​форму, и хотя у меня почти такой же код, проверка не отключается при проверке. Я не использую группы проверки, поэтому я просто отключаю группу по умолчанию, чтобы отключить проверку сущности.

AddressType построение формы для Address класс (который имеет ограничения аннотации на некоторые поля, такие как NotBlank а также Callback).

class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($options["toggle"]) {
$builder->add("toggle", CheckboxType::class, [
"mapped" => false,
"required" => false,
"label" => $options["toggle"]
]);
}

$builder
->add("name", TextType::class, [
"required" => !$options["toggle"]
])
->add("address", TextType::class, [
"required" => !$options["toggle"]
])
->add("zipcode", TextType::class, [
"label" => "Postcode",
"required" => !$options["toggle"]
])
->add("city", TextType::class, [
"required" => !$options["toggle"]
])
->add("countryCode", ChoiceType::class, [
"choices" => Address::COUNTRY_CODES
]);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"toggle" => false,
"data_class" => Address::class,
"validation_groups" => function(FormInterface $form) {
if ($form->has("toggle") && $form->get("toggle")->getData() === true) {
return [];
}

return ["Default"];
}
]);

$resolver->setAllowedTypes("toggle", ["bool", "string"]);
}
}

Я использую тип как это:

$addressForm = $this
->createFormBuilder([
"paymentAddress" => $paymentAddress,
"shippingAddress" => $shippingAddress
])
->add("paymentAddress", AddressType::class, [
"label" => false
])
->add("shippingAddress", AddressType::class, [
"label" => false,
"toggle" => "Use payment address"])
->add("submit", SubmitType::class, [
])
->getForm();

Я изучал это в течение нескольких часов, но я не могу понять, почему проверка не отключена, и я не желаю создавать форму из-за этой маленькой детали.

Почему проверка для AddressType не отключается закрытием в configureOptions? Если это не так, как это работает, что было бы лучшим решением для частичного отключения проверки аккуратно?

РЕДАКТИРОВАТЬ: даже если настройки "validation_groups" => false в значениях по умолчанию, в дочерних элементах, созданных в компоновщике, или при использовании формы проверка будет по-прежнему выполняться. Это не связано с закрытием. Каждый онлайн-ресурс, включая собственный ресурс Symfony, утверждает, что он должен работать, хотя …

4

Решение

[…] поэтому я просто отключаю группу по умолчанию, чтобы отключить проверку сущности.

При условии, что Address свойства & ограничения выглядят так:

/**
* @Assert\NotBlank()
*/
private $name;

// etc.

«Валидатор» предполагает, что эти свойства будут оцениваться с Default группа, потому что он всегда считает пустым validation_groups (например. return [];) как ['Default'] (следовательно, проверка не отключается при проверке):

https://symfony.com/doc/current/validation/groups.html:
Если группы не указаны, все ограничения, принадлежащие группе Default будет применяться.

Решение для частичного отключения проверки правильности

Должно быть много способов достичь этого, но я покажу вам два из них:

  1. Если нет data_class устанавливается в корневую форму, то Form группа доступна только для проверки этого уровня:

    $addressForm = $this
    ->createFormBuilder([...], [
    'validation_groups' => 'Form', // <--- set
    ])
    

    Далее в configureOptions метод, набор Address группа по умолчанию и Form группа, если «переключатель» отмечен, также добавляет Valid() ограничение для каскадной проверки:

    public function configureOptions(OptionsResolver $resolver)
    {
    $resolver->setDefaults([
    // ...
    "validation_groups" => function(FormInterface $form) {
    if ($form->has("toggle") && $form->get("toggle")->getData() === true) {
    return ['Form']; // <--- set
    }
    
    return ['Address']; // <--- set
    },
    'constraints' => [new Assert\Valid()], // <--- set
    ]);
    }
    

    Это означает, что при отправке с выключенным: Form а также Address группы применяются к адресным полям, иначе только Form группа применяется.

  2. (Другой способ) В Address класс добавляет группу «Required» ко всем ограничениям, это позволяет избежать проверки этих свойств с помощью Default группа:

    /**
    * @Assert\NotBlank(groups={"Required"}) // <--- set
    */
    private $name;
    
    // etc.
    

    Далее в configureOptions набор методов Required в качестве группы по умолчанию и Default если переключатель отмечен:

    public function configureOptions(OptionsResolver $resolver)
    {
    $resolver->setDefaults([
    // ...
    "validation_groups" => function(FormInterface $form) {
    if ($form->has("toggle") && $form->get("toggle")->getData() === true) {
    return ['Default']; // <--- set
    }
    
    return ['Required']; // <--- set
    },
    'constraints' => [new Assert\Valid()], // <--- set
    ]);
    }
    

    В этом случае при отправке с выключенным: Default а также Required группы применяются к адресным полям, иначе только Default группа, пропуская при этом обязательные поля.

Вложенные формы, содержащие объекты, отключенные от корневого объекта, можно проверить, установив для параметра ограничений значение new Valid(),

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector