Symfony2在每个请求中存储与用户相关的内容

时间:2014-07-31 13:46:47

标签: symfony

我想在用户发出的每个请求中存储用户使用的最后一个区域设置。我已经在数据库中创建了一个Field,只需要最好的练习方式,而不需要在每个Controller中进行大的修改。

谢谢大家。

2 个答案:

答案 0 :(得分:1)

您可以将您的语言环境存储在会话中,并将其与事件侦听器一起使用。并在用户登录时设置会话中的用户区域设置。

-LocaleListener:将语言环境存储在会话

中的会话和用户区域设置中

-UserLocaleListener:在用户登录时设置会话

中的用户区域设置
<?php

namespace YourApp\YourBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class LocaleListener implements EventSubscriberInterface
{
    private $defaultLocale;


    public function __construct($defaultLocale = 'en')
    {
        $this->defaultLocale = $defaultLocale;
    }

    public function onKernelRequest17(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);
        } 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 the default Locale listener
        KernelEvents::REQUEST => array(array('onKernelRequest17', 17)),
        );
    }
}

第二次服务:

<?php

namespace YourApp\YourBundle\EventListener;

use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class UserLocaleListener
{
    private $session;

    public function setSession(Session $session)
    {
        $this->session = $session;
    }

    /**
     * kernel.request event. If a guest user doesn't have an opened session, locale is equal to
     * "undefined" as configured by default in parameters.ini. If so, set as a locale the user's
     * preferred language.
     *
     * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
     */
    public function setLocaleForUnauthenticatedUser(GetResponseEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
            return;
        }
        $request = $event->getRequest();
        if ('undefined' == $request->getLocale()) {
            if ($locale = $request->getSession()->get('_locale')) {
                $request->setLocale($locale);
            } else {
                $request->setLocale($request->getPreferredLanguage());
            }
        }
    }

    /**
     * security.interactive_login event. If a user chose a language in preferences, it would be set,
     * if not, a locale that was set by setLocaleForUnauthenticatedUser remains.
     *
     * @param \Symfony\Component\Security\Http\Event\InteractiveLoginEvent $event
     */
    public function setLocaleForAuthenticatedUser(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();

        if ($lang = $user->getLocale()) {
            $event->getRequest()->setLocale($lang);
            $this->session->set('_locale', $lang);
        }
    }

}

services.yml

services:
    yourapp_your.locale_listener:
        class: YourApp\YourBundle\EventListener\LocaleListener
        arguments: ["%kernel.default_locale%"]
        tags:
            - { name: kernel.event_subscriber }

    yourapp_your.locale.interactive_login_listener:
        class: YourApp\YourBundle\EventListener\UserLocaleListener
        calls:
            - [ setSession, [@session] ]
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: setLocaleForAuthenticatedUser }

这是使用

答案 1 :(得分:0)

这是我在数据库中保存每个请求的语言环境的实现。 这对我来说是必要的,因为我需要为简报保留语言环境。

LocaleListener:

namespace MyApp\MyBundle\EventListener;

use \Symfony\Component\HttpKernel\Event\GetResponseEvent;

use \Symfony\Component\HttpKernel\KernelEvents;
use \Symfony\Component\EventDispatcher\EventSubscriberInterface;
use \FOS\UserBundle\Model\UserManagerInterface;
use \Symfony\Component\Security\Core\SecurityContext;
use \MyApp\MyBundle\Entity\User;

class LocaleListener implements EventSubscriberInterface
{
    private $userManager;
    private $securityContext;
    private $defaultLocale;

    public function __construct(UserManagerInterface $userManager, SecurityContext $securityContext, $defaultLocale = 'en')
    {
        $this->userManager = $userManager;
        $this->securityContext = $securityContext;
        $this->defaultLocale = $defaultLocale;
    }

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

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

       // save last locale to the user if he is logged in
       $user = $this->getUser();
       if($user instanceof User)
       {
           $user->setDefaultLanguage($locale);
           $this->userManager->updateUser($user);
       }

    }

    private function getUser()
    {
        $token = $this->securityContext->getToken();
        if($token !== null)
            return $this->securityContext->getToken()->getUser();
    }

    public static function getSubscribedEvents()
    {
        return array(
            // must be registered before the default Locale listener
        KernelEvents::REQUEST => array(array('onKernelRequest17', 17)),
        );
    }
}

services.yml:

myApp_myBundle.locale_listener:
    class: MyApp\MyBundle\EventListener\LocaleListener
    arguments: [@fos_user.user_manager, @security.context, "%kernel.default_locale%"]
    tags:
        - { name: kernel.event_subscriber }