<?php 
 
namespace App\EventListener; 
 
use DateTime; 
use Doctrine\DBAL\Exception; 
use App\Entity\User; 
use Symfony\Component\HttpKernel\Event\RequestEvent; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 
use Doctrine\DBAL\Types\Type; 
use App\DoctrineDBALTypes\UTCDateTimeType; 
use Twig\Environment; 
use Twig\Extension\CoreExtension; 
 
class TimezoneListener 
{ 
 
    /** 
     * @var TokenStorageInterface 
     */ 
    private $tokenStorage; 
 
    /** 
     * @var string 
     */ 
    private $timeZone; 
 
    /** 
     * @var Environment 
     */ 
    private $twig; 
 
    /** 
     * 
     * @param TokenStorageInterface $tokenStorage 
     * @param Environment $twig 
     * @param string $timeZone 
     */ 
    public function __construct(TokenStorageInterface $tokenStorage, Environment $twig, string $timeZone = 'Europe/Berlin') 
    { 
        $this->tokenStorage = $tokenStorage; 
        $this->twig = $twig; 
        $this->timeZone = $timeZone; 
    } 
 
    /** 
     * 
     * @param RequestEvent $event 
     * @throws Exception 
     */ 
    public function onKernelRequest(RequestEvent $event): void 
    { 
        $token = $this->tokenStorage->getToken(); 
 
        // override doctrine datetime class 
        Type::overrideType('datetime', UTCDateTimeType::class); 
        Type::overrideType('datetimetz', UTCDateTimeType::class); 
 
        // set time zone 
        if (!defined('_USER_TIMEZONE_')) { 
            if ($token != null && (($user = $token->getUser()) instanceof User) && $user->getTimezone()) { 
                define('_USER_TIMEZONE_', $user->getTimezone()); 
            } else { 
                define('_USER_TIMEZONE_', $this->timeZone); 
            } 
        } 
        date_default_timezone_set(_USER_TIMEZONE_); 
 
        // get utc time zone offset 
        $now = new DateTime(); 
        $mins = $now->getOffset() / 60; 
        $sgn = ($mins < 0 ? -1 : 1); 
        $mins = abs($mins); 
        $hrs = floor($mins / 60); 
        $mins -= $hrs * 60; 
        $offset = sprintf('%+d:%02d', $hrs * $sgn, $mins); 
        $this->twig->addGlobal('TIMEZONE_UTC', $offset); 
        $this->twig->getExtension(CoreExtension::class)->setTimezone(_USER_TIMEZONE_); 
    } 
 
}