I'm looking through the Symfony2 Validation Reference but I'm not finding what I need.
我正在浏览Symfony2验证参考,但我找不到我需要的东西。
I have a class Employment with a StartDate and EndDate. I would like to add an \@Assert() where it verifies that StartDate is always BEFORE EndDate. Is there a standard way of comparing class attributes as a Validation Constraint or should I create a custom validation constraint?
我有一个带有StartDate和EndDate的课程。我想添加一个\ @Assert(),它验证StartDate始终是BEFORE EndDate。是否存在将类属性作为验证约束进行比较的标准方法,还是应该创建自定义验证约束?
class Employment {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Expose()
*/
protected $id;
/**
* @ORM\Column(type="datetime")
* @Expose()
* @Assert\DateTime()
*/
protected $startDate;
/**
* @ORM\Column(type="datetime", nullable=TRUE)
* @Expose()
* @Assert\DateTime()
*/
protected $endDate;
...
}
3 个解决方案
#1
17
You could write a custom DateRangeValidator.
您可以编写自定义DateRangeValidator。
class DateRange extends Constraint {
public $message = "daterange.violation.crossing";
public $emptyStartDate = "daterange.violation.startDate";
public $emptyEndDate = "daterange.violation.endDate";
public $hasEndDate = true;
public function getTargets() {
return self::CLASS_CONSTRAINT;
}
public function validatedBy() {
return 'daterange_validator';
}
}
class DateRangeValidator extends ConstraintValidator
{
public function isValid($entity, Constraint $constraint)
{
$hasEndDate = true;
if ($constraint->hasEndDate !== null) {
$hasEndDate = $constraint->hasEndDate;
}
if ($entity->getStartDate() !== null) {
if ($hasEndDate) {
if ($entity->getEndDate() !== null) {
if ($entity->getStartDate() > $entity->getEndDate()) {
$this->setMessage($constraint->message);
return false;
}
return true;
} else {
$this->setMessage($constraint->emptyEndDate);
return false;
}
} else {
if ($entity->getEndDate() !== null) {
if ($entity->getStartDate() > $entity->getEndDate()) {
$this->setMessage($constraint->message);
return false;
}
}
return true;
}
} else {
$this->setMessage($constraint->emptyStartDate);
return false;
}
}
register it as a service:
将其注册为服务:
parameters:
register.daterange.validator.class: XXX\FormExtensionsBundle\Validator\Constraints\DateRangeValidator
services:
daterange.validator:
class: %register.daterange.validator.class%
tags:
- { name: validator.constraint_validator, alias: daterange_validator }
And use it in your Entity:
并在您的实体中使用它:
use XXX\FormExtensionsBundle\Validator\Constraints as FormAssert;
/**
*
* @FormAssert\DateRange()
*/
class Contact extends Entity
{
private $startDate;
private $endDate;
}
Eventhough it seems a bit much for a simple thing like that, but experience shows, that one needs a date range validator more often than just once.
尽管看起来像这样的简单事情似乎有点多,但经验表明,人们需要一个日期范围验证器而不是一次。
#2
30
You could add a validation getter to the entity - Symfony2 Validation Getters
您可以向实体添加验证getter - Symfony2 Validation Getters
In your validation
在您的验证中
Acme\YourBundle\Entity\Employment:
getters:
datesValid:
- "True": { message: "The start date must be before the end date" }
And then in your entity
然后在你的实体
public function isDatesValid()
{
return ($this->startDate < $this->endDate);
}
#3
14
There is Yet Another Solution: Validation by using Expression Language:
还有另一种解决方案:使用表达式语言进行验证:
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Column(type="date", nullable=true)
* @Assert\Date()
*/
private $startDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Assert\Date()
* @Assert\Expression(
* "this.getStartDate() < this.getEndDate()",
* message="The end date must be after the start date"
* )
*/
private $endDate;
You can add this constraint to $startDate
if you want.
如果需要,可以将此约束添加到$ startDate。
#1
17
You could write a custom DateRangeValidator.
您可以编写自定义DateRangeValidator。
class DateRange extends Constraint {
public $message = "daterange.violation.crossing";
public $emptyStartDate = "daterange.violation.startDate";
public $emptyEndDate = "daterange.violation.endDate";
public $hasEndDate = true;
public function getTargets() {
return self::CLASS_CONSTRAINT;
}
public function validatedBy() {
return 'daterange_validator';
}
}
class DateRangeValidator extends ConstraintValidator
{
public function isValid($entity, Constraint $constraint)
{
$hasEndDate = true;
if ($constraint->hasEndDate !== null) {
$hasEndDate = $constraint->hasEndDate;
}
if ($entity->getStartDate() !== null) {
if ($hasEndDate) {
if ($entity->getEndDate() !== null) {
if ($entity->getStartDate() > $entity->getEndDate()) {
$this->setMessage($constraint->message);
return false;
}
return true;
} else {
$this->setMessage($constraint->emptyEndDate);
return false;
}
} else {
if ($entity->getEndDate() !== null) {
if ($entity->getStartDate() > $entity->getEndDate()) {
$this->setMessage($constraint->message);
return false;
}
}
return true;
}
} else {
$this->setMessage($constraint->emptyStartDate);
return false;
}
}
register it as a service:
将其注册为服务:
parameters:
register.daterange.validator.class: XXX\FormExtensionsBundle\Validator\Constraints\DateRangeValidator
services:
daterange.validator:
class: %register.daterange.validator.class%
tags:
- { name: validator.constraint_validator, alias: daterange_validator }
And use it in your Entity:
并在您的实体中使用它:
use XXX\FormExtensionsBundle\Validator\Constraints as FormAssert;
/**
*
* @FormAssert\DateRange()
*/
class Contact extends Entity
{
private $startDate;
private $endDate;
}
Eventhough it seems a bit much for a simple thing like that, but experience shows, that one needs a date range validator more often than just once.
尽管看起来像这样的简单事情似乎有点多,但经验表明,人们需要一个日期范围验证器而不是一次。
#2
30
You could add a validation getter to the entity - Symfony2 Validation Getters
您可以向实体添加验证getter - Symfony2 Validation Getters
In your validation
在您的验证中
Acme\YourBundle\Entity\Employment:
getters:
datesValid:
- "True": { message: "The start date must be before the end date" }
And then in your entity
然后在你的实体
public function isDatesValid()
{
return ($this->startDate < $this->endDate);
}
#3
14
There is Yet Another Solution: Validation by using Expression Language:
还有另一种解决方案:使用表达式语言进行验证:
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Column(type="date", nullable=true)
* @Assert\Date()
*/
private $startDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Assert\Date()
* @Assert\Expression(
* "this.getStartDate() < this.getEndDate()",
* message="The end date must be after the start date"
* )
*/
private $endDate;
You can add this constraint to $startDate
if you want.
如果需要,可以将此约束添加到$ startDate。