2

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.

prossel
  • 111
  • 1
  • 7
  • ini_set('date.timezone', 'America/Los_Angeles'); ? – Julien B. Mar 26 '21 at 22:16
  • ini_set would be great to set the timezone to use in the database. I would use UTC in the tables. But where to set it efficiently in a Symfony project ? About the timezone the user wants to see dates, which is different for every user, depending where (s)he is around the world, we have to use both setTimeZone() for index and detail and setFormTypeOption (for forms). – prossel Mar 27 '21 at 08:41
  • Oh! Per user... hum, maybe you can use an event subscriber on kernel request...? – Julien B. Mar 27 '21 at 18:35

1 Answers1

1

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()),
        ];
    }
endo.anaconda
  • 2,449
  • 4
  • 29
  • 55
Julien B.
  • 3,023
  • 2
  • 18
  • 33