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

How to do conditional form validation which is based on user submitted data in symfony2?

这是我的设置实体表单,

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是从parent设置对象继承的。

如果父项为 NULL,我希望 'key' 和 'settingCategory' 为必填字段(非空白),但如果设置了父项,则 'key' 和 'settingCategory' 不是必填字段。

如何在 symfony 中执行此操作?

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');
        },
    ));
}

我建议你使用 callback validator

例如,在您的实体中 class:

<?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 所述构建自己的自定义验证器。

让我知道您需要更多信息。

希望对您有所帮助