Symfony Assert\Expression compare entity property with today's date

Viewed 2890

I'd like to add an Assert\Expression to a property of my entity. There should be an error message popping up, when the selected "Effective date" (this.getEffective()) is in the past or today. I just can't figure out, how to compare that date with todays date.

    /**
 * @var boolean
 * @ORM\Column(type="boolean", nullable=true)
 * @Assert\Expression(
 *     "this.getEffective() > today",
 *     message="The effective date must be in the future!")
 */
private $status_stealth;

I tried the same with now or datetime.now() and I've google around a lot, but I haven't found anything where somebody actually compared another value with the current date within an Assert Expression.

Ideas?

3 Answers

By default, the expression syntax supports only one function, constant(). In turn, the expression validator comes with one or two variables (a validation value and a context object). You can pass a value to a validation method of the entity.

/**
 * @Assert\Expression(expression="this.isStatusValid(value)")
 */
private $status;

public function isStatusValid($status) {
    $currentDate = new \DateTimeImmutable();
    return in_array($status, [1, 2, 3]) && $this->targetDate > $currentDate;
}

If you get some errors, just debug.

public function isStatusValid($status) {
    $currentDate = new \DateTimeImmutable();
    var_dump($this->targetDate);
    var_dump($currentDate);
    die();
    return in_array($status, [1, 2, 3]) && $this->targetDate > $currentDate;
}

Documentation links: Expression Constraint, Expression Syntax.

You can define a new method in your entity which will return today's date time and in your expression do your comparison

/**
 * @var boolean
 * @ORM\Column(type="boolean", nullable=true)
 * @Assert\Expression(
 *     "this.getEffective() > this.getCurrentDate()",
 *     message="The effective date must be in the future!")
 */
private $status_stealth;

public function getCurrentDate(){
    return new \DateTime();
}

If you want, you can use the symfony's expression:

  $builder->add(
            'start',
            DateTimeType::class,
            [
                'label' => 'Campaign Starts At',
                'data' => $entity->getStart(),
                'required' => true,
                'disabled' => $disabled,
                'widget'  => 'single_text',
                'constraints' => [
                    new Assert\GreaterThan(['value' => 'today'])
                ]
            ]
        );
Related