2

如果在表单中选择了某个选项,我目前无法关闭一些验证约束。该选项与模型无关,不使用该data_class选项设置。

我的表格包含两个嵌入式地址表格,与一个发票地址和一个发货地址完全相同。如果选择了替代选项,我想通过验证使发货地址表格成为必需的。如果没有选择其他选项,则发货地址表格不需要验证,需要单独放置。

客户结账表格

class CustomerCheckoutForm extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('id', 'hidden')
        ->add('firstName', 'text')
        ->add('nameAdditions', 'text')
        ->add('lastName', 'text')
        ->add('gender', 'choice', array('expanded' => true, 'choices' => array('m' => 'M', 'f' => 'F')))
        ->add('birthDate', 'date', array(
            'required' => true,
            'input' => 'string',
            'widget' => 'choice',
            'years' => range(DATE_CURRENT_YEAR - 80, DATE_CURRENT_YEAR - 18),
            'empty_value' => array('year' => 'Year', 'month' => 'Month', 'day' => 'Day')
        ))
        ->add('invoiceAddress', new AddressForm($options['countryMapper']), array(
            'label' => false,
            'required' => true,
        ))
        ->add('alternative_shipment_address', 'choice', array(
            'expanded' => true,
            'choices' => array(0 => 'Delivery on the current address', 1 => 'Alternative shipping address'),
            'mapped' => false,
            'required' => true,
            'label' => 'Delivery address',
            'data' => 0,
        ))
        ->add('shipmentAddress', new AddressForm($options['countryMapper']), array(
            'label' => false,
            'required' => false,
        ))
        ->add('Continue', 'submit');

    $this->registerListeners($builder);
}

private function registerListeners(FormBuilderInterface $builder)
{
    $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
        $customer = $event->getData();
        $form = $event->getForm();

        if (!$customer || $customer->getId() === null) {
            $form->add('password', 'password');
        }
    });
}

/**
 * {@inheritdoc}
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'EHV\SharedBundle\Model\Customer',
        'countryMapper' => null,
        'validation_groups' => array(
            'Default',
            'checkout',
        ),
    ));
}

public function getName()
{
    return 'customerCheckout';
}

}

地址表

class AddressForm extends AbstractType
{

private $countryMapper;

public function __construct(CountryMapper $countryMapper)
{
    $this->countryMapper = $countryMapper;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new CountryToIdTransformer($this->countryMapper);
    $countries = $this->countryMapper->getAll();
    $data[''] = 'Make a choice...';

    /** @var Country $country */
    foreach ($countries as $country) {
        $data[$country->getId()] = $country->getName();
    }

    $builder
        ->add('id', 'hidden')
        ->add('streetName', 'text')
        ->add('streetNumber', 'text')
        ->add('streetNumberAddition', 'text')
        ->add('postalCode', 'text')
        ->add('city', 'text')
        ->add(
            $builder->create('country', 'choice', array('choices' => $data))
                ->addModelTransformer($transformer)
        );
}

/**
 * {@inheritdoc}
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'EHV\SharedBundle\Model\Address',
    ));
}

public function getName()
{
    return 'address';
}

}

两种模型都通过函数设置了自己的约束:

public static function loadValidatorMetadata(ClassMetaData $metadata) {}
4

2 回答 2

1

结帐回调约束http://symfony.com/doc/current/reference/constraints/Callback.html

如果需要,您可以读取地址的值并增加错误。

于 2014-10-22T14:29:41.957 回答
0

我设法将 aForm event listenerConstraint CallbackHpatoio 的回答一起使用,详情如下。

客户结账表格

    $builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event) {
        $form = $event->getForm();
        $customer = $event->getData();

        if ($form->get('alternative_shipment_address')->getData() === 0) {
            $customer->setShipmentAddress(null);
        }
    });

客户约束

    $callback = function($customer) use ($metadata) {
        $metadata->addPropertyConstraint('invoiceAddress', new Valid());

        /** @var Customer $customer */
        if ($customer->getShipmentAddress() !== null) {
            $metadata->addPropertyConstraint('shipmentAddress', new Valid());
        }
    };

    $metadata->addConstraint(new Callback($callback));

感谢Hpatoio指出了正确的方向。

于 2014-10-24T07:55:42.557 回答