Danil Pyatnitsev
Danil Pyatnitsev

Reputation: 2292

Unable to add global twig

I have an AppAuthAuthenticator, and on onAuthenticationFailure I dispatch an event:

if ($count === self::NOTIFY_ATTEMPTS) {
    $this->eventDispatcher->dispatch(new TooManyWrongLoginAttemptsEvent($user));
}

in TooManyWrongLoginAttemptsEvent I render (with Environment) email message and send it to Bus.

I have TimezoneListener:

namespace App\EventListener;

use App\DoctrineDBALTypes\UTCDateTimeType;
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 Twig\Environment;

class TimezoneListener
{
    /** @var TokenStorageInterface */
    private $tokenStorage;
    /** @var Environment  */
    private $twig;

    /**
     * @param TokenStorageInterface $token_storage
     * @param Environment $twig
     */
    public function __construct(TokenStorageInterface $token_storage, Environment $twig) {
        $this->tokenStorage = $token_storage;
        $this->twig = $twig;
    }

    /**
     *
     * @param RequestEvent $event
     *
     * @throws \Doctrine\DBAL\DBALException
     */
    public function onKernelRequest(RequestEvent $event) {
        $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_', 'UTC');
            }
        }
        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);
    }
}

and services.yaml config:

App\EventListener\TimezoneListener:
    tags:
        - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

Service that handle event autoloaded by symfony itself.

And with this configuration I have following error:

Unable to add global "TIMEZONE_UTC" as the runtime or the extensions have already been initialized.

I see, that twig initiates at AppAuthAuthenticator::onAuthenticationFailure and when TimezoneListener try to add global twig var it's throws error, and if I change priority of TimezoneListener to 6 it's can't handle timezone (show +00:00)

How to configure this two events right?

Upvotes: 1

Views: 604

Answers (1)

yceruto
yceruto

Reputation: 9575

To avoid the error when adding the global variable you could define a default value through the Twig configuration:

# config/packages/twig.yaml
twig:
    globals:
        TIMEZONE_UTC: 0

Upvotes: 2

Related Questions