如果条件匹配则应用约束
Apply constraint if conditions match
我有一个 Symfony 表单。在这个表格中,我有两个字段:
"House number" 和 "Po Box"。它们的定义如下:
$builder->add('houseNumber', TextType::class, [
'label' => 'Huisnummer',
'attr' => [
'maxlength' => 8,
],
'constraints' => [
new NotBlank([
'groups' => $options['constraint_groups']
]),
new Regex([
'pattern' => '/^[0-9]+$/',
'message' => 'Vul alleen het huisnummer in cijfers in.'
]),
new Length([
'groups' => $options['constraint_groups'],
'max' => 8
])
]
])->add('poBox', TextType::class, [
'label' => 'Postbus',
'attr' => [
'maxlength' => 10,
],
'constraints' => [
new Length([
'groups' => $options['constraint_groups'],
'max' => 10
])
]
]);
有没有办法让我在有 PoBox 的情况下不需要门牌号,反之亦然?
谢谢。
您可以创建自定义验证约束
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
* @Target({"CLASS", "ANNOTATION"})
*/
class HouseNumber extends Constraint
{
public $message = 'Some message';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
验证者
namespace App\Validator\Constraints;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class HouseNumberValidator extends ConstraintValidator
{
public function validate($obj, Constraint $constraint)
{
if (!$constraint instanceof HouseNUmber) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\HouseNUmber');
}
$error = null;
if (!$this->isValid($obj)) {
$error = $constraint->message;
}
if (!empty($error)) {
$this->context->buildViolation($error)
->atPath('houseNumber')
->addViolation();
}
}
private function isValid($obj)
{
if (!$obj instanceof SomeClass) {
throw new UnexpectedTypeException($obj, SomeClass::class);
}
if (!empty($obj->getPoBox())) {
return true;
}
return !empty($obj->getHouseNumber());
}
}
然后在 class 中的 $houseNumber 字段中添加注释
use App\Validator\Constraints as AppAssert;
/**
* @AppAssert\HouseNumber
*/
class SomeClass
{
private $houseNumber;
...
}
我认为实现您想要的效果的最佳方法是创建自定义 class 约束验证器 (https://symfony.com/doc/current/validation/custom_constraint.html#class-constraint-validator)。
我不知道你是否可以在表单上添加这个约束,或者你是否必须将你的表单与实体相关联。
我有一个 Symfony 表单。在这个表格中,我有两个字段:
"House number" 和 "Po Box"。它们的定义如下:
$builder->add('houseNumber', TextType::class, [
'label' => 'Huisnummer',
'attr' => [
'maxlength' => 8,
],
'constraints' => [
new NotBlank([
'groups' => $options['constraint_groups']
]),
new Regex([
'pattern' => '/^[0-9]+$/',
'message' => 'Vul alleen het huisnummer in cijfers in.'
]),
new Length([
'groups' => $options['constraint_groups'],
'max' => 8
])
]
])->add('poBox', TextType::class, [
'label' => 'Postbus',
'attr' => [
'maxlength' => 10,
],
'constraints' => [
new Length([
'groups' => $options['constraint_groups'],
'max' => 10
])
]
]);
有没有办法让我在有 PoBox 的情况下不需要门牌号,反之亦然?
谢谢。
您可以创建自定义验证约束
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
* @Target({"CLASS", "ANNOTATION"})
*/
class HouseNumber extends Constraint
{
public $message = 'Some message';
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}
验证者
namespace App\Validator\Constraints;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class HouseNumberValidator extends ConstraintValidator
{
public function validate($obj, Constraint $constraint)
{
if (!$constraint instanceof HouseNUmber) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\HouseNUmber');
}
$error = null;
if (!$this->isValid($obj)) {
$error = $constraint->message;
}
if (!empty($error)) {
$this->context->buildViolation($error)
->atPath('houseNumber')
->addViolation();
}
}
private function isValid($obj)
{
if (!$obj instanceof SomeClass) {
throw new UnexpectedTypeException($obj, SomeClass::class);
}
if (!empty($obj->getPoBox())) {
return true;
}
return !empty($obj->getHouseNumber());
}
}
然后在 class 中的 $houseNumber 字段中添加注释
use App\Validator\Constraints as AppAssert;
/**
* @AppAssert\HouseNumber
*/
class SomeClass
{
private $houseNumber;
...
}
我认为实现您想要的效果的最佳方法是创建自定义 class 约束验证器 (https://symfony.com/doc/current/validation/custom_constraint.html#class-constraint-validator)。
我不知道你是否可以在表单上添加这个约束,或者你是否必须将你的表单与实体相关联。