Symfony2的形式验证组,而不用实体(Symfony2 form validator group

2019-08-04 16:10发布

我使用的Symfony2表单组件来构建和验证表单。 现在我需要基于单个字段的值设置验证组,不幸的是它似乎在那里每一个例子是基于实体 - 这林不使用有以下几个原因。

例如:如果任务是空的,所有的约束验证应该被删除,但如果不是,它应该使用验证器的默认设置(或验证组)。

换句话说,我想要做到的,是让子窗体可选的,但是如果依然被填充的关键领域进行验证。

可能有人可以给我一个例子,如何配置呢?

<?php
namespace CoreBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints as Assert;
use CoreBundle\Form\Type\ItemGroupOption;

class ItemGroup extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title', 'text', array(
            'label' => 'Titel',
            'attr' => array('class' => 'span10 option_rename'),
            'required' => false
        ));
        $builder->add('max_selections', 'integer', array(
            'label' => 'Max tilvalg',
            'constraints' => array(new Assert\Type('int', array('groups' => array('TitleProvided')))),
            'attr' => array('data-default' => 0)
        ));
        $builder->add('allow_multiple', 'choice', array(
            'label' => 'Tillad flere valg',
            'constraints' => array(new Assert\Choice(array(0,1))),
            'choices'  => array(0 => 'Nej', 1 => 'Ja')
        ));
        $builder->add('enable_price', 'choice', array(
            'label' => 'Benyt pris',
            'constraints' => array(new Assert\Choice(array(0,1))),
            'choices'  => array(0 => 'Nej', 1 => 'Ja'),
            'attr' => array('class' => 'option_price')
        ));
        $builder->add('required', 'choice', array(
            'label' => 'Valg påkrævet',
            'constraints' => array(new Assert\Choice(array(0,1))),
            'choices'  => array(0 => 'Nej', 1 => 'Ja')
        ));
        $builder->add('options', 'collection', array(
            'type' => new ItemGroupOption(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false
            )
        );
        $builder->add('sort', 'hidden');
    }

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

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        global $app;

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

                // Get submitted data
                $data = $form->getData();

                if (count($app['validator']->validateValue($data['title'], new Assert\NotBlank())) == 0) {
                    return array('TitleProvided');
                } else {
                    return false;
                }
            },
        ));
    }
}

Answer 1:

如果使用的是2.1,你可能想看看“的基础上提交的数据组” 。

更新

例如使用演示联系页面/demo/contact默认AcmeDemoBundle提供的Symfony标准版:

表单类型与条件的验证组:

 namespace Acme\DemoBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\Validator\Constraints as Assert; class ContactType extends AbstractType { // Inject the validator so we can use it in the closure /** * @var Validator */ private $validator; /** * @param Validator $validator */ public function __construct(Validator $validator) { $this->validator = $validator; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('email', 'email'); $builder->add('message', 'textarea', array( // Added a constraint that will be applied if an email is provided 'constraints' => new Assert\NotBlank(array('groups' => array('EmailProvided'))), )); } public function setDefaultOptions(OptionsResolverInterface $resolver) { // This is needed as the closure doesn't have access to $this $validator = $this->validator; $resolver->setDefaults(array( 'validation_groups' => function(FormInterface $form) use ($validator) { // Get submitted data $data = $form->getData(); $email = $data['email']; // If email field is filled it will not be blank // Then we add a validation group so we can also check message field if (count($validator->validateValue($email, new Assert\NotBlank())) == 0) { return array('EmailProvided'); } }, )); } public function getName() { return 'contact'; } } 

不要忘了注入validator表单类型的服务:

<?php

namespace Acme\DemoBundle\Controller;

//...

class DemoController extends Controller
{
    // ...

    public function contactAction()
    {
        $form = $this->get('form.factory')->create(new ContactType($this->get('validator')));

        // ...
    }
}

正如你所看到的确认message只有在现场将被触发email字段被填充。

使用一个diff工具捕捉的差异。



文章来源: Symfony2 form validator groups without entities