Validation 如何仅在模型类中使用symfony注释验证选中复选框时强制设置文本字段

Validation 如何仅在模型类中使用symfony注释验证选中复选框时强制设置文本字段,validation,symfony,Validation,Symfony,这可能是一个非常简单的问题,但我在这里已经用完了增值税字段只有在用户选中了isVatable复选框时才是必填字段,否则可以忽略该字段。如何在模型类而不是实体中使用组验证(注释)来实现这一点 我检查了一下,但老实说,我没有动脑 模板 class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options = []) {

这可能是一个非常简单的问题,但我在这里已经用完了<代码>增值税字段只有在用户选中了
isVatable
复选框时才是必填字段,否则可以忽略该字段。如何在模型类而不是实体中使用组验证(注释)来实现这一点

我检查了一下,但老实说,我没有动脑

模板

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options = [])
    {
        $builder
            ->setMethod($options['method'])
            ->setAction($options['action'])
            ->add('vat', 'text')
            ->add('isVatable', 'checkbox')
        ;
    }

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

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(
            ['data_class' => 'My\FrontendBundle\Model\UserModel']
        );
    }
}
模型类

class UserModel
{
    /**
     * @Assert\NotBlank(message="Vat is required only when checkbox is checked.")
     */
    protected $vat;

    /**
     * @var bool
     */
    protected $isVatable = false;
}

可能在
…\Validator\Constraints
中有类似的内容:

VAT.php

use Symfony\Component\Validator\Constraint;

    class VAT extends Constraint

    {
        public $message = 'VAT is compulsory for applicable items';
        public $vat;
        public $isVatable;
    }
VATConstraint.php

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\PropertyAccess\PropertyAccess;

class VATValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        $accessor = PropertyAccess::createPropertyAccessor();
        $data = $accessor->getValue($this->context->getRoot(), 'data');

        $vat = $data['vat'];
        $isVatable = $data['isVatable'];
        if ($isVatable && empty($vat)) {

            $this->context->addViolation($constraint->message, array('%string%' => $value));

            return false;
        }

        return true;
    }
}
用户模型实体:

use YourBundle\Validator\Constraints as MyAssert;

class UserModel
{
    /**
     * @MyAssert\NotBlank(message="Vat is required only when checkbox is checked.")
     */
    protected $vat;
...
}
我发现,对于这种验证场景,方法上的约束通常对我很有效。您可以向方法和属性添加一些验证约束,这非常强大

基本思想是,您可以创建一个方法,给它这个注释-如果该方法返回
true
验证通过;如果返回
false
则失败

类用户模型
{
/**
*@var字符串
*/
受保护的美元增值税;
/**
*@var bool
*/
受保护的$isVatable=false;
/**
*@Assert\True(message=“请输入增值税编号”)
*/
公共函数IsVatSetWhenIsVatTableChecked()
{
//如果未选中此属性,则不会执行此操作
//要执行任何验证,请返回true
如果(!$this->isVatable){
返回true;
}
//如果$this->vat不为空,则返回true
//您可能需要添加一些额外的
//此处进行验证以确保
返回!为空($this->vat);
}
}
此外,您可以使用FormType对象中的
error\u mapping
选项将错误消息映射到特定的表单字段,如下所述:

希望这有帮助:)

您应该使用

首先创建约束类和验证类:

<?php
// AppBundle/Validator/Constraints/NotBlankIfTaxEnabled.php

namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class NotBlankIfTaxEnabled extends Constraint
{
    public $message = 'If isVat is enabled you have to enter a value in the Vat field.';

    public function getTargets()
    {
        return self::CLASS_CONSTRAINT;
    }
}

你知道吗,我以前尝试过,但失败了,因为我将
@Assert
附加到了模型的
$vat
属性。很明显,这是我测试中的问题,因为您的测试根本没有,而且运行得非常好,所以感谢您和+1在方法上使用
@True
的好例子!我喜欢它+1:)我以前用过它们,但不幸的是,对于这个非常简单的过程来说,它有点过头了。不过,感谢您的回答和努力。当然,这是可能的。谢谢你的回复,我很感激。我接受了另一个答案,因为它正是我想要的。无论如何,谢谢你的回答。
<?php
// AppBundle/Validator/Constraints/NotBlankIfTaxEnabledValidator.php

namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class NotBlankIfTaxEnabledValidator extends ConstraintValidator
{
    public function validate($customer, Constraint $constraint)
    {
        if($customer->getIsVatable() && strlen($customer->getVat()) == 0)
        {
            $this->context->buildViolation($constraint->message)
                ->addViolation();
        }
    } 
}
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use AppBundle\Validator\Constraints as AppAssert;

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

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string", length=64)
     *
     */
    private $vat;

    /**
     * @var boolean
     *
     * @ORM\Column(name="taxEnabled", type="boolean")
     */
    private $isVatable;
<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CustomerType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('vat', NULL, array('required' => FALSE))
            ->add('isVatable', NULL, array('required' => FALSE))
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Customer'
        ));
    }

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