with php dependency-injection symfony fosuserbundle

php - with - Symfony2: Inyectar usuario actual en Servicio



symfony 3.4 fosuserbundle (7)

Intento inyectar el usuario actualmente conectado a un servicio. Mi objetivo es ampliar algunas funcionalidades de ramas para que se muestren en función de las preferencias del usuario. En este ejemplo, quiero mostrar cualquier función de fecha usando la zona horaria específica del usuario.

No parece haber ninguna forma de inyectar al usuario actual en un servicio, lo cual me parece realmente extraño. Al inyectar el contexto de seguridad, no tiene un token incluso si el usuario está conectado

Estoy usando el paquete de usuario de FOS.

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

¿Me estoy perdiendo de algo?


Creo que esta pregunta merece una respuesta actualizada desde 2.6.x + desde las nuevas mejoras del componente de seguridad.

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 } }

Servicios.yml

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


Desde Symfony 2.6.

Necesitas usar @ security.token_storage

use Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface; class UserDateExtension extends /Twig_Extension { /** * @var TokenStorageInterface */ protected $tokenStorage; /** * @param $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 }

}

Y Services.yml

twig.date_extension: class: Acme/Twig/SpecialDateExtension tags: - { name: twig.extension } arguments: ["@security.token_storage"]

referencia: symfony.com/blog/…


El usuario es un mal candidato para ser un servicio.

  • Primero es un modelo, no un servicio
  • En segundo lugar, existe la seguridad del servicio. Contexto desde el que puede obtener el usuario.

En una plantilla twig puedes usar app.user . Ver symfony doc global-template-variables . Si desea mostrar algo en función de los permisos del usuario, puede hacer {{is_granted (''ROLE_USER'')}}.


Puedes intentar inyectar @service_container y hacer $this->container->get(''security.context'')->getToken()->getUser(); .


Recomendaría enlazar un evento diferente, si usa el evento kernel.controller, tendrá un token y no tendrá ningún problema. El token no está disponible en kernel.request desde Symfony 2.3

Escribí una guía sobre cómo implementar 2.6+ usuario para Symfony 2.3+ 2.6+ y 2.6+ en Twig en mi blog llamado Symfony 2.6+ zonas horarias de usuario .

Esto es muy superior al uso de una extensión Twig porque puede usar las funciones de formateo de fecha estándar en Twig, así como proporcionar una fecha UTC de backend separada, zonas horarias de fecha Twig predeterminadas y zonas horarias de fecha Twig definidas por el usuario.

Aquí está el extracto más importante:

src / AppBundle / EventListener / TwigSubscriber.php

<?php namespace AppBundle/EventListener; use AppBundle/Entity/User; use Symfony/Component/EventDispatcher/EventSubscriberInterface; use Symfony/Component/HttpKernel/Event/FilterControllerEvent; use Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface; class TwigSubscriber implements EventSubscriberInterface { protected $twig; protected $tokenStorage; function __construct(/Twig_Environment $twig, TokenStorageInterface $tokenStorage) { $this->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); } } } } }

Ahora puedes usar twig como siempre y usa tus preferencias de usuario si están disponibles.


Yo usaría una extensión de ramita para eso:

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 }

Ahora en 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>

Luego en twig puedes hacer:

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