Сущность getUser в EventSubscriber - PullRequest
       2

Сущность getUser в EventSubscriber

0 голосов
/ 30 августа 2018

Я начал создавать свое первое веб-приложение с помощью Symfony. В этом приложении я получил управление пользователями с аутентификацией и мультиязычностью. В базе данных пользователей tabel - это столбец lang для каждого пользователя. Я получил изменение языка по умолчанию для приложения, изменив его с помощью параметра _GET, а также путем входа в систему с использованием значения базы данных. Теперь я хочу изменить значение в базе данных автоматически, переключая язык с помощью параметра URL _GET в EventSubscriber. К сожалению, я не знал, как получить сущность пользователя в моей функции onKernelRequest, чтобы сохранить выбранный язык в базе данных. Вся логика смены языка осуществляется в следующем коде:

<?php
namespace App\EventSubscriber;

use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class LocaleSubscriber implements EventSubscriberInterface
{
    private $defaultLocale;
    private $allowedLangs;
    private $session;

    public function __construct(SessionInterface $session, $defaultLocale = 'de')
    {
        $this->defaultLocale = $defaultLocale;
        $this->allowedLangs = ['de', 'en'];
        $this->session = $session;
    }

    public function onInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();

        if (null !== $user->getLocale()) {
            $this->session->set('_locale', $user->getLocale());
        }
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
            return;
        }

        // try to see if the locale has been set as a _locale routing parameter
        if ($locale = $request->attributes->get('_locale')) {
            $request->getSession()->set('_locale', $locale);
        } elseif(array_key_exists('_locale', $_GET) && array_search($_GET['_locale'], $this->allowedLangs) !== FALSE) {
            $request->setLocale($_GET['_locale']);
            $request->getSession()->set('_locale', $_GET['_locale']);
        } else {
            // if no explicit locale has been set on this request, use one from the session
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }

    public static function getSubscribedEvents()
    {
        return array(
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            SecurityEvents::INTERACTIVE_LOGIN => array(array('onInteractiveLogin', 15)),
            KernelEvents::REQUEST => array(array('onKernelRequest', 20)),
        );
    }
}

Спасибо заранее Питер

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Проблема с пустым токеном - неправильное событие. Я переключился на "KernelEvents :: CONTROLLER". Теперь я получил свой пользовательский объект. Мой рабочий код:

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class UserLocaleSubscriber implements EventSubscriberInterface
{
    private $tokenStorage;
    private $em;
    private $allowedLangs;

    public function __construct(TokenStorageInterface $tokenStorage, EntityManagerInterface $em)
    {
        $this->tokenStorage = $tokenStorage;
        $this->em = $em;
        $this->allowedLangs = ['de', 'en'];
    }

    public function onKernelController(FilterControllerEvent $event)
    {
        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
            return;
        }

        if(array_key_exists('_locale', $_GET) && array_search($_GET['_locale'], $this->allowedLangs) !== FALSE) {
            if (!$event->isMasterRequest()) {
                return;
            }

            if (!$token = $this->tokenStorage->getToken()) {
                return ;
            }

            if (!$token->isAuthenticated()) {
                return ;
            }

            if (!$user = $token->getUser()) {
                return ;
            }

            $locale = $_GET['_locale'];
            // update user
            $user->setLocale($locale);

            $this->em->flush($user);
            $request->setLocale($locale);
            $request->getSession()->set('_locale', $locale);
        }
    }

    public static function getSubscribedEvents()
    {
        return array(
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            KernelEvents::CONTROLLER => array(array('onKernelController', 1)),
        );
    }
}
0 голосов
/ 31 августа 2018

Сущность присутствует в LifecycleEventArgs.

public function prePersist(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();
0 голосов
/ 30 августа 2018

Сначала я бы разделил LocaleSubscriber класс и переместил onKernelRequest и onInteractiveLogin на отдельных слушателей / подписчиков - меньше зависимостей для каждой услуги.

Чтобы получить текущего пользователя в onKernelRequest событии, вам нужно внедрить TokenStorage сервис:

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class LocaleSubscriber implements EventSubscriberInterface
{
    private $tokenStorage;
    private $em;

    public function __construct(
        TokenStorageInterface $tokenStorage, 
        EntityManagerInterface $em
    ) {
        $this->tokenStorage = $tokenStorage;
        $this->em = $em;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        if (!$event->isMasterRequest()) {
            return;
        }

        if (!$token = $this->tokenStorage->getToken()) {
            return ;
        }

        if (!$token->isAuthenticated()) {
            return ;
        }

        if (!$user = $token->getUser()) {
            return ;
        }

        $request = $event->getRequest();

        // update user
        $user->setLocale($locale);

        $this->em->flush($user);

    }

}

Обратите внимание, что это не проверено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...