n0xie n0xie - 6 months ago 378
PHP Question

Symfony2: Inject current user in Service

I am trying to inject the currently logged in user into a service. My goal is to extend some twig functionality to output it based on user preferences. In this example I want to output any date function using the user specific Timezone.

There doesn't seem to be any way to inject the current user into a service, which seems really odd to me. When injecting the security context, it doesn't have a token even if the user is logged in

I am using FOS user bundle.

services:
...
twigdate.listener.request:
class: App\AppBundle\Services\TwigDateRequestListener
arguments: [@twig, @security.context]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }


<?php

namespace App\AppBundle\Services;

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class TwigDateRequestListener
{
protected $twig;

function __construct(\Twig_Environment $twig, SecurityContext $context) {

$this->twig = $twig;
//$this->user = $context->get...;

var_dump($context); die;
}

public function onKernelRequest(GetResponseEvent $event) {
// $this->twig->getExtension('core')->setDateFormat($user->getProfile()->getFormat());
// $this->twig->getExtension('core')->setTimeZone($user->getProfile()->getTimezone());
}
}

output:

object(Symfony\Component\Security\Core\SecurityContext)[325]
private 'token' => null
private 'accessDecisionManager' =>
object(Symfony\Component\Security\Core\Authorization\AccessDecisionManager)[150]
private 'voters' =>
array
0 =>
object(Symfony\Component\Security\Core\Authorization\Voter\RoleHierarchyVoter)[151]
...
1 =>
object(Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter)[153]
...
2 =>
object(Symfony\Component\Security\Acl\Voter\AclVoter)[155]
...
private 'strategy' => string 'decideAffirmative' (length=17)
private 'allowIfAllAbstainDecisions' => boolean false
private 'allowIfEqualGrantedDeniedDecisions' => boolean true
private 'authenticationManager' =>
object(Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager)[324]
private 'providers' =>
array
0 =>
object(Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider)[323]
...
1 =>
object(Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider)[149]
...
private 'eraseCredentials' => boolean true
private 'alwaysAuthenticate' => boolean false


Am I missing something?

Answer

I would use a twig extension for that:

class UserDateExtension extends \Twig_Extension
{
    private $context;

    public function __construct(SecurityContext $context)
    {
        $this->context = $context;
    }

    public function getUser()
    {
        return $this->context->getToken()->getUser();
    }

    public function getFilters()
    {
        return array(
            'user_date' => new \Twig_Filter_Method($this, "formatUserDate"),
        );
    }

    public function formatUserDate($date, $format)
    {
        $user = $this->getUser();
        // do stuff
    }

Now in services.xml

    <service id="user_date_twig_extension" class="%user_date_twig_extension.class%">
        <tag name="twig.extension" />
        <argument type="service" id="security.context" />
    </service>

Then in twig you could do:

{{ date | user_date('d/m/Y') }}
Comments