crudsymfony5easyadmin3

Set default view_timezone for all DateTimeField


In an EasyAdmin 3 / Symfony 5.2 backend, I have several *CrudController classes with datetime fields which are all configured like:

public function configureFields(string $pageName): iterable
{
    return [
        // ...
        DateTimeField::new('createdAt')
            ->setTimezone($this->getUser()->getTimezone())
            ->setFormTypeOption('view_timezone', $this->getUser()->getTimezone()),
    ];
}

Instead of copy paste the same code for every datetime field of every entity, is there a way to define the timezone once as default ?

Edit:

I found out that setTimezone() can be called once for the whole *CrudController class in ConfigureCrud() and this applies by default to all fields:

class MyCrudController extends AbstractCrudController
{
    public function configureCrud(Crud $crud): Crud
    {
        return $crud->setTimezone($this->getUser()->getTimezone());
    }
}

Actually it can even be set on the dashboard to apply as default for all its crud controllers and their fields.

class DashboardController extends AbstractDashboardController
{
    public function configureCrud(): Crud
    {
        // Default config for all cruds in this controller. 
        // Only impact index and detail actions. 
        // For Forms, use ->setFormTypeOption('view_timezone', '...') 
        // on all fields
        return Crud::new()->setTimezone($this->getUser()->getTimezone());
    }
}

So, the configureCrud() in the DashboardController class is the easiest solution to for index and detail actions.

I'm still interested in a similar solution to avoir setFormTypeOption('view_timezone', '...') on every field.


Solution

  • One thing you could do is creating a method to shorten your code. I made a trait to do that, but it could be a method from a base class that you extend, a class with a static method or something like that. Note that the setTimezone() here is optional if you set it at the controller or dashboard level, but to make sure they stay in sync I included it here anyway.

        <?php
        // src/Helper/Admin/DateTimeFieldTrait.php
        namespace App\Helper\Admin;
        
        use App\Entity\User;
        use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
        
        trait DateTimeFieldTrait
        {
            protected function createDateTimeFieldForUser(string $propertyName, User $user): DateTimeField
            {
                return DateTimeField::new($propertyName)
                    ->setTimezone($user->getTimezone())
                    ->setFormTypeOption('view_timezone', $user->getTimezone())
                    ;
            }
        }
    

    Then in your code, you could use it where needed.

        //...
        use DateTimeFieldTrait;
        // ...
        
        public function configureFields(string $pageName): iterable
        {
            return [
                // ...
                $this->createDateTimeFieldForUser('createdAt', $this->getUser()),
            ];
        }