Home » Php » php – How to make session variables available as Twig globals?

php – How to make session variables available as Twig globals?

Posted by: admin February 25, 2020 Leave a comment

Questions:

Within a twig view, it’s possible to get a session variable with

{% set myVar=app.session.get('myVar') %}

It’s handy, but I need to do it each time I use a view that doesn’t extends base template.

Instead, I would like to set those sessions variables, as twig globals.

I tried to use @session in config/packages/twig.yaml, under globals, but beside @session.storage, I can’t find any methods to access my variables.

I thought about doing it in my kernelListener event, but I don’t know which service to import to add some dynamics twig globals (if it’s even possible).

How to&Answers:

Custom extension is the way to go. Descriptive, easy to test. No need to call an event listener when not using Twig.

My solution uses lazy Twig extension which are available since Twig 1.35 and 2.4.4

Both will autowire and autoconfigure:

final class SessionRuntime implements RuntimeExtensionInterface
{
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function get(string $id, $default = null)
    {
        return $this->session->get($id, $default);
    }
}

final class SessionExtension extends AbstractExtension
{
    public function getFunctions()
    {
        return [
            new TwigFunction('from_session', [SessionRuntime::class, 'get']),
        ];
    }

    public function getFilters()
    {
        return [
            new TwigFilter('from_session', [SessionRuntime::class, 'get']),
        ];
    }
}

Usage:

Hello {{ 'name'|from_session }}. Last visit: {{ 'last_visit'|from_session('never') }}

Or:

Hello {{ from_session('name') }}

If you are really so strongly after globals, instead create custom service and bind it to the session global variable, eg:

globals:
    session: `@App\Twig\Runtime\SessionRuntime`


class SessionRuntime
{
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function __call(string $key, array $params = [])
    {
        return $this->session->get($key);
    }
}

and in Twig:

{{ session.yourSessionKey }}

Answer:

Found the solution.
I had to inject Twig\Environment within my kernelListener class

use Twig\Environment as TwigEnvironment;

class kernelListener {
    private $twigEnvironment;

    public function __construct(TwigEnvironment $twigEnvironment,) {
        $this->twigEnvironment=$twigEnvironment;
    }

    public function onKernelController(ControllerEvent $event) {
        $myGlobalValue='someValue';

        /** @var Session $session */
        $session=$event->getRequest()->getSession();
        $session->set('myGlobalValue', $myGlobalValue)


        $this->twigEnvironment->addGlobal('myGlobalValue', $myGlobalValue);
    }
}

With this, twigGobalName can be accessed in all twig views.

Did valid Emix answer as it’s not wrong either.
Just a constrain on my end make my own answer fit my needs