Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Tuesday, February 2, 2016

Symfony2: Inject current user in Service

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 }      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 by Mun Mun Das for Symfony2: Inject current user in Service


You can try injecting @service_container and do $this->container->get('security.context')->getToken()->getUser();.

Answer by miguel_ibero for Symfony2: Inject current user in Service


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

                                

Then in twig you could do:

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

Answer by Maksim Kotlyar for Symfony2: Inject current user in Service


The user is a bad candidate to be a service.

  • First it is a model not a service
  • Second there is service security.context where you can get user from.

In a twig template you can use app.user. See symfony doc global-template-variables. If you want to show something based on user permissions you can do {{ is_granted('ROLE_USER') }}.

Answer by Michael Villeneuve for Symfony2: Inject current user in Service


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"  

Answer by Finlay Beaton for Symfony2: Inject current user in Service


I would recommend binding a different event, if you use the kernel.controller event, you will have a token and have no problem. The token is not available in kernel.request since Symfony 2.3

I wrote a guide on how to implement User Timezones for Symfony 2.3+ and 2.6+ in Twig on my blog called Symfony 2.6+ User Timezones.

This is vastly superior to using a Twig Extension because you can use the standard date formatting functions in Twig, as well as provide separate backend UTC date, default Twig date timezones and User defined Twig date timezones.

Here is the most important excerpt:

src/AppBundle/EventListener/TwigSubscriber.php

twig = $twig;          $this->tokenStorage = $tokenStorage;      }        public static function getSubscribedEvents()      {          return [              'kernel.controller' => 'onKernelController'          ];      }        public function onKernelController(FilterControllerEvent $event)      {          $token = $this->tokenStorage->getToken();            if ($token !== null) {              $user = $token->getUser();                if ($user instanceof User) {                  $timezone = $user->getTimezone();                  if ($timezone !== null) {                      $this->twig->getExtension('core')->setTimezone($timezone);                  }              }          }      }  }  

Now you can use twig as normal and it uses your User preferences if available.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.