Я пытаюсь ввести текущий зарегистрированный пользователь в службу. Моя цель состоит в том, чтобы расширить некоторые функциональные возможности, чтобы выводить их на основе пользовательских настроек. В этом примере я хочу вывести любую функцию даты, используя пользовательский часовой пояс.
Кажется, что нет никакого способа ввести текущего пользователя в сервис, который кажется мне очень странным. При вводе контекста безопасности он не имеет маркера, даже если пользователь зарегистрирован
Я использую пакет 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
Пользователь – плохой кандидат на обслуживание.
В шаблоне ветви вы можете использовать app.user . См. Глобальные шаблонные переменные symfony doc. Если вы хотите показать что-то на основе прав пользователя, вы можете сделать {{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
Я бы рекомендовал привязать другое событие, если вы используете событие kernel.controller, у вас будет токен и не будет проблем. Токен не доступен в kernel.request
поскольку Symfony 2.3
Я написал руководство по использованию пользовательских 2.6+
для Symfony 2.3+
и 2.6+
в Twig в моем блоге под названием Symfony 2.6+ User Timezones .
Это значительно превосходит использование расширения Twig, поскольку вы можете использовать стандартные функции форматирования даты в Twig, а также предоставлять отдельную временную дату UTC, стандартные временные метки Twig date и пользовательские временные интервалы даты Twig.
Вот наиболее важный отрывок:
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); } } } } }
Теперь вы можете использовать веточку как обычно, и она использует ваши предпочтения пользователя, если они доступны.
Вы можете попробовать ввести @service_container
и сделать $this->container->get('security.context')->getToken()->getUser();
,