Symfony2:在服务中注入当前用户
我正在尝试将当前login的用户注入到服务中。 我的目标是扩展一些树枝function,根据用户的喜好输出。 在这个例子中,我想使用用户特定的时区输出任何date函数。
似乎没有办法将当前用户注入到服务中,这对我来说似乎很奇怪。 注入安全上下文时,即使用户已login,它也没有令牌
我正在使用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
我错过了什么吗?
我会用一个树枝延伸:
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 }
现在在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>
然后在树枝上,你可以做:
{{ date | user_date('d/m/Y') }}
我认为这个问题值得自2.6.x +以来更新的答案,因为新的安全组件的改进。
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"
services.yml
my_service: class: ... arguments: - "@=service('security.token_storage').getToken().getUser()"
Service.php
protected $currentUser; public function __construct($user) { $this->currentUser = $user; }
http://symfony.com/doc/current/book/service_container.html#using-the-expression-language
用户是一个糟糕的候选人是一个服务。
- 首先它是一个模型而不是服务
- 其次是服务security.context你可以从哪里获得用户。
在树枝模板中,您可以使用app.user 。 请参阅symfony doc 全局模板variables 。 如果你想显示一些基于用户权限的东西,你可以{{is_granted('ROLE_USER')}}。
来自Symfony 2.6。
你需要使用@ 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 }
}
和Services.yml
twig.date_extension: class: Acme\Twig\SpecialDateExtension tags: - { name: twig.extension } arguments: ["@security.token_storage"]
参考: http : //symfony.com/blog/new-in-symfony-2-6-security-component-improvements
我build议绑定一个不同的事件,如果你使用kernel.controller事件,你将有一个令牌,没有问题。 自Symfony 2.3
以来,该令牌在kernel.request
不可用
我写了一篇关于如何在我的名为Symfony 2.6+用户时区的博客中实现Symfony 2.3+
和2.6+的用户时区的指南 。
这比使用Twig Extension要好得多,因为您可以在Twig中使用标准的date格式化function,并且提供单独的后端UTCdate,默认的Twigdate时区和用户定义的Twigdate时区。
这是最重要的摘录:
的src /的appbundle /事件监听/ 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); } } } } }
现在,您可以像平常一样使用树枝,并使用您的用户首选项(如果可用)。
你可以尝试注入@service_container
,做$this->container->get('security.context')->getToken()->getUser();
。