Forms 具有相同实体且验证符号不同的2个子窗体2

Forms 具有相同实体且验证符号不同的2个子窗体2,forms,validation,symfony,Forms,Validation,Symfony,在我的Symfony2应用程序中,我有一个表单订阅,其中有两个子表单使用相同的实体地址。 我正在寻找一种解决方案,仅当复选框未选中时才验证第二个表单。由于子表单属于同一实体,因此验证约束是相同的。Assert\Valid实体不能接受groups参数,因此我无法使用此解决方案 SubscriptionType.php public function buildForm(FormBuilderInterface $builder, array $options) { $builder

在我的Symfony2应用程序中,我有一个表单订阅,其中有两个子表单使用相同的实体地址。 我正在寻找一种解决方案,仅当复选框未选中时才验证第二个表单。由于子表单属于同一实体,因此验证约束是相同的。Assert\Valid实体不能接受groups参数,因此我无法使用此解决方案

SubscriptionType.php

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('billingAddress', new AddressType())
        ->add('shippingSame', 'checkbox', array(
                'mapped' => false,
                'data' => true,
        ))
        ->add('shippingAddress', new AddressType())
    ;       
}
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

// before the 2.7 version this method is called setDefaultOptions
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function (FormInterface $form) {
            $data = $form->getData();

            if (true == $data->shippingSame) {
                return array('validate_only_billing_address');
            }

            return array('validate_shipping_billing_address');
        },
    ));
}
address.php实体

class Address
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="firstname", type="string", length=255, nullable=false)
     * @Assert\NotBlank()
     */
    private $firstname;

    /**
     * @var string
     *
     * @ORM\Column(name="line1", type="string", length=255, nullable=false)
     * @Assert\NotBlank()
     */
    private $line1;
}
Suscription.php实体

class Subscription
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Shop\Address")
     * @ORM\JoinColumn(nullable=false)
     */
    private $billingAddress;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Shop\Address")
     * @ORM\JoinColumn(nullable=false)
     */
    private $shippingAddress;
}
因此,我只想在未选中“未映射”复选框时验证第二个地址


感谢您的帮助!

处理未映射字段的唯一方法是直接访问表单数据,这会破坏验证的目的。要使用symfony的Validator组件,您必须将复选框映射。只需将此字段添加到实体中,您不必将其映射到DB

/**
 * @var bool
 */
private $shippingSame;

/**
 * @return bool
 */
public function isShippingSame()
{
    return $this->shippingSame;
}

/**
 * @param bool $shippingSame
 */
public function setShippingSame($shippingSame)
{
    $this->shippingSame = $shippingSame;
}
然后您可以在以下位置轻松访问它:

你可以使用表格

您需要一些高级逻辑来确定验证组(基于提交的数据),您可以将validation_groups选项设置为数组回调,如下所示:

SubscriptionType.php

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('billingAddress', new AddressType())
        ->add('shippingSame', 'checkbox', array(
                'mapped' => false,
                'data' => true,
        ))
        ->add('shippingAddress', new AddressType())
    ;       
}
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

// before the 2.7 version this method is called setDefaultOptions
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function (FormInterface $form) {
            $data = $form->getData();

            if (true == $data->shippingSame) {
                return array('validate_only_billing_address');
            }

            return array('validate_shipping_billing_address');
        },
    ));
}
并在实体中添加正确的验证组注释

希望这有帮助。如果你需要更多的建议,请告诉我

$resolver->setDefaults(array(
    'validation_groups' => function (FormInterface $form) {

        if (true == $form->get('shippingSame')->getData()) {
            return array('validate_only_billing_address');
        }

        return array('validate_shipping_billing_address');
    },
));
我只更改了get()属性。 可能只是版本差异(老实说,我没有调查) 实际上,我正在运行最后一个v2.7.1


希望这可以帮助某人

感谢您的解决方案,但由于两个子表单的实体相同,验证组将相同(因为在实体类中定义了注释),所以我想我们不能使用组\验证。根据文档,Hi@Nbalive16,我经常使用此功能。顺便说一句,回调方法也是一种解决方案。是的,我们可以根据数据更改组,但组是通过注释定义到实体类文件中的。作为我的实体(以及我的字段)对于2个子窗体也是一样的,无法定义和使用2个不同的组。无论如何,非常感谢您的帮助;)