Symfony2验证日期时间1应该在日期时间2之前

时间:2022-10-22 16:40:33

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。