symfonycrudeasyadmin

Symfony easy admin how to compare DateTimeField to current date


i'm programming a backend for a project with the easy admin bundle for the first time and i'm having trouble modifying a crud controller to suit my needs. I have a Borrowing entity that has an expected return date field. What I want is that the text of that field in the crud controller is displayed in red if the expected current date is passed.

I tried the following code but it doesn't work :

<?php

namespace App\Controller\Admin;

use App\Entity\Borrowing;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;

class BorrowingCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Borrowing::class;
    }


    public function configureFields(string $pageName): iterable
    {
        $id = IntegerField::new('id');

        $prolongated = BooleanField::new('prolongated');

        $borrowingDate = DateTimeField::new('borrowingDate')
            ->formatValue(function ($value) {
                return $value->format('Y-m-d');
            });

        $currentDate = new \DateTime();

        $cssClass = DateTimeField::new('expectedReturnDate') < $currentDate ? 'text-danger' : '';

        $expectedReturnDate = DateTimeField::new('expectedReturnDate')->formatValue(function ($value) {
            return $value->format('Y-m-d');
        })
            ->setCssClass($cssClass);

        $finalReturnDate = DateTimeField::new('finalReturnDate')->formatValue(function ($value) {
            if ($value === null) {
                return null;
            } else {
                return $value->format('Y-m-d');
            }
        });

        $fieldsArray = [
            $id,
            $prolongated,
            $borrowingDate,
            $expectedReturnDate,
            $finalReturnDate
        ];
        
        return $fieldsArray;
    }
}

I tried to dd(DateTimeField::new('expectedReturnDate')) to see why it doesn't work, but weirdly all I get is a dto object and I can't find how to access it's value. I tried everything and i'm out of ideas. Help would be greatly appreciated. Thanks in advance.

Solution

I modified my expected return date field in the borrowingCrudController. It now looks like this :

yield DateTimeField::new('expectedReturnDate')->formatValue(function ($value) {
            return $value->format('Y-m-d');
        })
            ->setTemplatePath('admin/field/date_expected_return.html.twig'); 

I also created a date_expected_return.html.twig file in templates/admin/field with the following code in it :

 {# admin/field/date_expected_return.html.twig #} 
<time class="{{field.formattedValue < 'now'|date("Y-m-d") ? "text-danger" : ""}} " datetime="{{ field.value|date('c') }}" title="{{ field.value|date('r') }}">{{ field.formattedValue }}</time> 

and now it works !


Solution

  • You cannot get a date value from DateTimeField::new('expectedReturnDate') which just return a easy admin field which is a DTO object to configure your field.

    By the way you can use yield since configureFields expect an iterable, that would make a cleaner method.

    In your case, you may want to create a custom template to handle how and when your field should become red. So use addTemplatePath to add a new custom template to handle your use case.

    public function configureFields(string $pageName): iterable
    {
        yield IntegerField::new('id');
    
        yield BooleanField::new('prolongated');
    
        yield DateTimeField::new('borrowingDate')
            ->setFormat('Y-m-d');
        yield DateTimeField::new('expectedReturnDate')
            ->setTemplatePath('admin/field/date_expected_return.html.twig')
            ->setFormat('Y-m-d');
    
        yield DateTimeField::new('finalReturnDate')
            ->setFormat('Y-m-d');
    }
    

    And your new twig file:

    {# admin/field/date_expected_return.html.twig #}
    {% if field.value < 'now'|date() %}
        <span class="text-danger">{{ field.value }}</span>
    {% else %}
        <span>{{ field.value }}</span>
    {% endif %}
    

    You may need to check how to get the value in your template, I do not recall if it's really field.value, but you can just {{ dump(field) }} and update the template if needed.

    If you do not know you can configure your default date time format in your easy admin dashboard configuration. Instead of setting the format everywhere.