在我的Symfony 2(2.4.2)应用程序中,有一个由3个字段组成的表单类型。
我希望验证如下:如果field A
和field B
为空,field C
不应为空。这意味着至少有一个字段应该接收一些数据。
目前,我检查控制器中收到的数据。有更推荐的方法吗?
答案 0 :(得分:13)
除了编写自定义验证器之外,还有更简单的解决方案。最简单的可能是表达式约束:
class MyEntity
{
private $fieldA;
private $fieldB;
/**
* @Assert\Expression(
* expression="this.fieldA != '' || this.fieldB != '' || value != ''",
* message="Either field A or field B or field C must be set"
* )
*/
private $fieldC;
}
您还可以向类中添加验证方法,并使用Callback约束对其进行注释:
/**
* @Assert\Callback
*/
public function validateFields(ExecutionContextInterface $context)
{
if ('' === $this->fieldA && '' === $this->fieldB && '' === $this->fieldC) {
$context->addViolation('At least one of the fields must be filled');
}
}
该方法将在课程验证期间执行。
答案 1 :(得分:3)
这可能是Custom Validation Constraint的用例。我自己没有使用它,但基本上你创建了一个Constraint
和一个Validator
。然后,在Constraint
。
config/validation.yml
Your\Bundle\Entity\YourEntity:
constraints:
- Your\BundleValidator\Constraints\YourConstraint: ~
实际验证由您的Validator
完成。您可以告诉Symfony将整个实体传递给您的validate
方法以访问多个字段:
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
您的validate
:
public function validate($entity, Constraint $constraint)
{
// Do whatever validation you need
// You can specify an error message inside your Constraint
if (/* $entity->getFieldA(), ->getFieldB(), ->getFieldC() ... */) {
$this->context->addViolationAt(
'foo',
$constraint->message,
array(),
null
);
}
}
答案 2 :(得分:0)
您可以使用Group Sequence Providers执行此操作,例如:
use Symfony\Component\Validator\GroupSequenceProviderInterface;
/**
* @Assert\GroupSequenceProvider
*/
class MyObject implements GroupSequenceProviderInterface
{
/**
* @Assert\NotBlank(groups={"OptionA"})
*/
private $fieldA;
/**
* @Assert\NotBlank(groups={"OptionA"})
*/
private $fieldB;
/**
* @Assert\NotBlank(groups={"OptionB"})
*/
private $fieldC;
public function getGroupSequence()
{
$groups = array('MyObject');
if ($this->fieldA == null && $this->fieldB == null) {
$groups[] = 'OptionB';
} else {
$groups[] = 'OptionA';
}
return $groups;
}
}
没有测试过,但我认为它会起作用