Forms 基于两个字段的Symfony2表单验证

Forms 基于两个字段的Symfony2表单验证,forms,validation,symfony,Forms,Validation,Symfony,我目前正在开发一个网站,用户可以在其中购买礼品卡。我使用的是三个步骤的形式,使用的是CraueFormFlow包,一切都与步骤有关。我能够验证每个简单的断言(如非空白、电子邮件、重复字段等),但我面临的情况是,用户可以选择0张礼品卡并进入下一页 用户可以使用两种不同的方式选择他们想要购买的礼品卡数量:一种是25美元的礼品卡,另一种是50美元的礼品卡。所以,我不能只放一个验证器说“值0是不允许的”。验证器必须防止用户在两个金额(25美元和50美元)中都保留数量“0” 有人知道如何在两个字段中查找值

我目前正在开发一个网站,用户可以在其中购买礼品卡。我使用的是三个步骤的形式,使用的是CraueFormFlow包,一切都与步骤有关。我能够验证每个简单的断言(如非空白、电子邮件、重复字段等),但我面临的情况是,用户可以选择0张礼品卡并进入下一页

用户可以使用两种不同的方式选择他们想要购买的礼品卡数量:一种是25美元的礼品卡,另一种是50美元的礼品卡。所以,我不能只放一个验证器说“值0是不允许的”。验证器必须防止用户在两个金额(25美元和50美元)中都保留数量“0”

有人知道如何在两个字段中查找值进行自定义验证吗


提前谢谢

您有很多解决方案

最简单的方法是向模型类中添加

另一种方法是创建自定义约束及其关联的验证器。你有一个好主意。 这是最好的方法

由于约束不应用于属性而是应用于类,因此必须指定它,以覆盖约束类的
->getTargets()
方法:

class MyConstraint extends Constraint
{
    // ...

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

因此,作为
->isValid()
方法的
$value
参数传递的值将包含整个类的值,而不仅仅是单个属性的值

使用正则表达式以防止为零

在实体类中写下下面的覆盖函数,并指定需要验证的属性

下面的示例用于验证pincode,在pincode字段中,我只允许数字0-9组合最多10位

“^\d+$”这是我用来阻止其他字符的正则表达式

要重写此函数,必须包含以下类

use Symfony\Component\Validator\Mapping\ClassMetadata;// for overriding function loadValidatorMetadata()

use Symfony\Component\Validator\Constraints\NotBlank;// for notblank constrain

use Symfony\Component\Validator\Constraints\Email;//for email constrain

use Symfony\Component\Validator\Constraints\MinLength;// for minimum length

use Symfony\Component\Validator\Constraints\MaxLength; // for maximum length

use Symfony\Component\Validator\Constraints\Choice; // for choice fields

use Symfony\Component\Validator\Constraints\Regex; // for regular expression



public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('pincode', new NotBlank(array('message' => 'Does not blank')));
        $metadata->addPropertyConstraint('pincode', new Regex(array('pattern'=>'/^\d+$/','message' => 'must be number')));
        $metadata->addPropertyConstraint('pincode', new MaxLength(array('limit'=>'6','message' => 'must maximum 6 digits')));
        $metadata->addPropertyConstraint('pincode', new MinLength(array('limit'=>'6','message' => 'must minimum 6 digits')));


    }
不要忘记这一切

包含在实体类中

你必须验证。因此,在您的情况下,请使用不允许“0”的适当正则表达式


快乐编码

当您的表单没有附加数据类时,您可以在如下表单中实现依赖约束:

    $startRangeCallback = function ($object, ExecutionContextInterface $context) use ($form)
    {
        $data = $form->getData();
        $rangeEnd = $data['range_end'];
        if($object && $rangeEnd){
            if ($object->getTimestamp() > $rangeEnd->getTimestamp()) {
                $context->addViolation('Start date should be before end date!', array(), null);
            }
        }

    };

    $form->add('range_start', 'bootstrap_datepicker', array(
            'format' => 'dd-MM-yyyy',
            'required' => false,
            'attr' => array('class' => "col-xs-2"),
            'calendar_weeks' => true,
            'clear_btn' => true,
            'constraints' => array(
                new Callback(array($startRangeCallback)),
            )
        )
    );

    $form->add('range_end', 'bootstrap_datepicker', array(
            'format' => 'dd-MM-yyyy',
            'required' => false,
            'attr' => array('class' => "col-xs-2"),
            'calendar_weeks' => true,
            'clear_btn' => true,

        )
    );

我在验证约束中就是这样做的,用到期月份和到期年份属性检查信用卡的有效性

在这个类中,我检查expirationYear属性的值,并将其与从contextObject获取的expirationMonth属性的值进行比较

/**
 * Method to validate
 * 
 * @param string                                  $value      Property value    
 * @param \Symfony\Component\Validator\Constraint $constraint All properties
 * 
 * @return boolean
 */
public function validate($value, Constraint $constraint)
{
    $date               = getdate();
    $year               = (string) $date['year'];
    $month              = (string) $date['mon'];

    $yearLastDigits     = substr($year, 2);
    $monthLastDigits    = $month;
    $otherFieldValue    = $this->context->getRoot()->get('expirationMonth')->getData();

    if (!empty($otherFieldValue) && ($value <= $yearLastDigits) && 
            ($otherFieldValue <= $monthLastDigits)) {
        $this->context->addViolation(
            $constraint->message,
            array('%string%' => $value)
        );            
        return false;            
    }

    return true;
}
这里有更多的解释和完整的教程:

我建议使用。此约束可应用于表单字段或(最好)实体:

   /**
     * @var int
     * @Assert\Type(type="integer")
     */
    private $amountGiftCards25;

    /**
     * @var int
     * @Assert\Type(type="integer")
     * @Assert\Expression(expression="this.getAmountGiftCards25() > 0 or value > 0", message="Please choose amount of gift cards.")
     */
    private $amountGiftCards50;

你能解释一下如何实现回调约束吗?我正在查看Symfony2文档,我不太知道如何访问我想在[…]isValid()函数中检查的值。如果没有数据类(使用数组时),它似乎不起作用。如果我也需要访问entityManger怎么办?
   /**
     * @var int
     * @Assert\Type(type="integer")
     */
    private $amountGiftCards25;

    /**
     * @var int
     * @Assert\Type(type="integer")
     * @Assert\Expression(expression="this.getAmountGiftCards25() > 0 or value > 0", message="Please choose amount of gift cards.")
     */
    private $amountGiftCards50;