Php – Symfony2: Inject current user in Service

dependency-injectionfosuserbundlephpsymfony

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?

Best Solution

I think that this question deserves an updated answer since 2.6.x+ since the new security component improvements.

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class UserDateExtension extends \Twig_Extension
{
    /**
     * @var TokenStorage
     */
    protected $tokenStorage;


    /**
     * @param \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage    $tokenStorage
     */
    public function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

    public function getUser()
    {
        return $this->tokenStorage->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
    }
}

Services.yml

twig.date_extension:
    class: Acme\Twig\SpecialDateExtension
    tags:
        - { name: twig.extension }
    arguments:
        - "@security.token_storage"
Related Question