如何根据symfony2中用户提交的数据进行条件表单验证?

时间:2015-05-06 06:53:41

标签: php forms symfony symfony-forms

这是我的设置实体表单,

class SettingType extends AbstractType
{

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('key')
            ->add('values', 'collection', array(
                'allow_add' => true,
                'allow_delete' => true,
            ))
            ->add('parent')
            ->add('settingCategory')
            ->add('user')
            ->add('settingOption')
        ;


        $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {

            $setting = $event->getData();

            if ($parent = $setting->getParent()) {
                $setting->setKey($parent->getKey());
                $setting->setSettingCategory($parent->getSettingCategory());
                $event->setData($setting);
            }
        });
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\SettingBundle\Entity\Setting',
            'csrf_protection' => false
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'setting';
    }
}

我使用REST POST请求提交表单数据。例如对于默认应用程序设置,

{
    "setting" : 
    {
        "key": "setting1", 
        "values": ["setting1va1", "setting1va2"],
        "settingCategory": 1
    }
}

现在要覆盖此设置,以便用户选择不同的值

{
    "setting" : 
    {
        "values": ["setting1va1"],
        "user":44319,
        "parent": 1
    }
}

因此,您可以在表单中看到,如果设置了parent,则key和settingCategory将从父设置对象继承。

我想要'key'和'settingCategory'(NotBlank)如果parent是NULL但是如果设置了parent,那么'key'和'settingCategory'不是必需字段。

如何在symfony中执行此操作?

2 个答案:

答案 0 :(得分:3)

我建议您使用callback validator

例如,在您的实体类中:

<?php

use Symfony\Component\Validator\Constraints as Assert;

/**
 * @Assert\Callback(methods={"validateParent"})
 */
class Setting {



    public function validateParent(ExecutionContextInterface $context)
    {
        if (
                $this->getParent() // NOT NULL
                &&
                ( // ONE OF THIS IS BLANK
                    ($parent->getSettingCategory() && trim($parent->getSettingCategory()==''))
                        ||
                    ($parent->getKey() && trim($parent->getKey()==''))
                )
            )
        {
            $context->addViolation('mandatory params');
        }
    }
}

否则,您可以按照here所述构建自己的自定义验证程序。

请告诉我您需要更多信息。

希望这个帮助

答案 1 :(得分:0)

docs 提供您需要的所有东西,包括代码。在您的类型中,您可以执行以下操作:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function(FormInterface $form) {
            $data = $form->getData();
            if (Client::TYPE_PERSON == $data->getType()) {
                return array('person');
            }

            return array('company');
        },
    ));
}