我目前正在开发一个用户可以购买礼品卡的网站。我使用CraueFormFlow捆绑包使用三步形式,一切都与步骤有关。我能够验证每个简单的断言(如非空白,电子邮件,重复字段等)但我面临的情况是,用户可以选择0礼品卡并继续下一页。
用户可以使用两个单独选择他们想要购买的礼品卡数量:一个用于25美元礼品卡,一个用于50美元礼品卡。所以我不能只是把一个验证器说“不允许值0”。验证器必须防止用户在数量(25 $和50 $)中留下数量“0”。
有谁知道如何进行自定义验证以查找两个字段中的值?
提前致谢!
答案 0 :(得分:37)
你有很多解决方案。
最简单的方法是在模型类中添加Callback constraint。
另一种方法是创建自定义约束及其关联的验证器。你有一个cookbook explaining how to create a custom validation constrain。 这是做到这一点的最佳方法。
由于您的约束不适用于属性而是适用于类,您必须指定它覆盖约束类的->getTargets()
方法:
class MyConstraint extends Constraint
{
// ...
public function getTargets()
{
return Constraint::CLASS_CONSTRAINT;
}
}
因此,作为$value
方法的->isValid()
参数传递的值将包含整个类的值,而不仅仅是单个属性的值。
答案 1 :(得分:12)
如果没有附加到表单的数据类,则可以在以下表单中实现依赖约束:
$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,
)
);
答案 2 :(得分:7)
这就是我在验证限制中完成此操作的方法,检查信用卡有效期是否有到期月份和年份属性。
在这个类中,我检查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;
}
当然,您必须在getTargets方法中授权类和属性约束,形成主约束文件。
/**
* Get class constraints and properties
*
* @return array
*/
public function getTargets()
{
return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
}
此处的进一步说明和完整教程:http://creativcoders.wordpress.com/2014/07/19/symfony2-two-fields-comparison-with-custom-validation-constraints/
答案 3 :(得分:3)
使用正则表达式以防止零
在您的Entity类中记下以下覆盖功能,并指定您需要验证的属性。
以下示例用于验证密码,此处在密码字段中,我只允许数字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'的正确表达式。
快乐编码
答案 4 :(得分:3)
我建议使用Expression constraint。此约束可以应用于表单字段或(最好)应用于实体:
/**
* @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;