Q:

Symfony validator and dates comparison

I'm learning Symfony, and I started a Symfony project (2.8.8 with php 5.6) for a new customer. I have an entity with these fields (php DateTime objects) :
/**
 * @var date
 * @ORM\Column(name="startDate", type="date")
 * @Assert\NotNull()
 * @Assert\Date()
 */
private $startDate;

/**
 * @var date
 * @ORM\Column(name="endDate", type="date")
 * @Assert\NotNull()
 * @Assert\Date()
 */
private $endDate ;

I want to validate that start date is earlier than end date. So I wrote a validator in my entity :
/**
 * @Assert\IsTrue(message="Start date must be earlier than end date".)
 */
public function isStartDate()
{
    return $this->startDate < $this->endDate ;
}

In my controller, I check my form this way :
$myEntity = new MyEntity();
$form = $this->createForm(MyEntityType::class, $myEntity );

try {
    // Is form valid ?
    if ($form->handleRequest($request)->isValid()) {
        // Do things if form is Valid
    }
}

But the result is always false, even if startDate is earlier than endDate... I know I can check dates in my controller, but I want to do it with Symfony validators. How can I do ?

A:

You can fix this with Symfony custom callback. Please check the document for the details.
For the scenario given, you should have a validation callback as below :
/**
 * @Assert\Callback
 */
public function validate(ExecutionContextInterface $context, $payload) {
    if ($this->startDate < $this->endDate) {
        $context->buildViolation('Start date must be earlier than end date')
            ->atPath('startDate')
            ->addViolation();
    }
}

Note :

See, the error is set to a field path (startDate).
The code is not tested!.
Use correct path for ExecutionContextInterface

Hope this helps!

