2013-09-06 5 views
2

내 웹 사이트에서 Symfony, 마스터 버전을 실행 중입니다. 지금까지 웹 사이트에서 LocalListener logic을 사용할 수 있었지만 코드가 내 버전과 호환되지 않기 때문에 약간의 차이가있었습니다. these paths를 사용하여,첫 번째 요청시 사용자 로캘이 작동하지 않습니다.

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

    if ($locale = $request->get('_locale')) { 
     $request->getSession()->set('_locale', $locale); 
    } 
    $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); 
} 

그런 식으로, 내 페이지에서 간단한 언어 선택을 넣을 수 있고, 새로운 언어는 첫 번째 요청에 적용됩니다 : (내 생각) 나는 단지 onKernelRequest 방법이 방법을 단순화 . ("else"조건을 해제해도 발생하지 않을 것입니다.)

그런 다음 사용자가 로그인하고 프로필에 로케일을 지정한 경우 사용자 계정에 저장된 로캘을 고려하고 싶습니다.

가 가 이

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

    $token = $this->container->get('security.context')->getToken(); 
    if (is_object($token)) { 
    $user = $token->getUser(); 
    if (is_object($user)) { 
     $userlocale = $user->getLocale(); 
     if ($userlocale) { 
     $request->getSession()->set('_locale', $userlocale); 
     $request->setLocale($userlocale); 
     return; 
     } 
    } 
} 

    if ($locale = $request->get('_locale')) { 
     $request->getSession()->set('_locale', $locale); 
    } 
    $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); 
} 
(편집 : 죄송 가난한 들여 쓰기, 어떻게 든 유래 ... 제대로 들여 쓰기하지 않음) 사용자가

는 기본적으로이 확인하는 경우 그래서 함수에서이 코드 조각을 추가 로그인되어있는 경우, 사용자가 로케일을 설정했는지 여부를 판별 한 경우 로케일을 사용자 로케일로 설정합니다. 이제는 작동하지만, 즉시 .... 내 프로필에 로그인하거나 로케일을 변경할 때마다 내가 얻을 수있는 다음 페이지는 이전에 설정된 로케일에 계속 남아 있습니다. 새 페이지를로드 할 때만 번역이 제대로 변경되고 다음 요청에 대해 그대로 유지됩니다.

여기 내 질문이 있습니다.이 변경 사항을 게시 후 로그인 및 프로필 편집 후 요청에 적용하기 위해 추가해야 할 사항이 있습니까?

답변

1

감사합니다. Elnur에게 감사드립니다. jms_i18n 솔루션 (Elnur의 답변에있는 의견 참조)으로 돌아 가기로 결심했으며, 내 솔루션을 구축하는 데 도움이 된 this question을 발견했습니다. 그래서 EventSubscriber 확장 클래스에서 내 자신의 간단한 "확장되지 않은"클래스로 전환했습니다. 여기에 작업 코드 :

<?php 
//src/myApp/MainBundle/EventListener/LocaleListener.php 
namespace myApp\MainBundle\EventListener; 

use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\HttpKernel\HttpKernelInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\HttpFoundation\Cookie; 

class LocaleListener 
{ 
    private $container; 

    public function __construct(ContainerInterface $container) 
    { 
    $this->container = $container; 
    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
    if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) { 
     return; 
    } 
    $request = $event->getRequest(); 
    if ($request->getRequestFormat() !== 'html') { 
     return; 
    } 

    $token = $this->container->get('security.context')->getToken(); 
    if (is_object($token)) { 
     $user = $token->getUser(); 
     if (is_object($user)) { 
     $userlocale = $user->getLocale(); 
     if ($userlocale && $userlocale != $request->get('_locale')) { 
      $parmArray = $request->get('_route_params'); 
      $parmArray['_locale'] = $userlocale; 

      $redirectResponse = new RedirectResponse($this->container->get('router')->generate($request->get('_route'), $parmArray)); 
      $redirectResponse->headers->setCookie(new Cookie('b_locale', $userlocale, time() + 2592000)); 

      $event->setResponse($redirectResponse); 
     } 
     } 
    } 
    } 
} 

그리고 여기에 서비스에 등록하는 방법입니다 : 내 마음을 변경 엘너에

# app/config/config.yml 
services: 
    myapp_main.locale_listener: 
     class: myApp\MainBundle\EventListener\LocaleListener 
     arguments: ["@service_container"] 
     tags: 
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 

많은 감사.당신은 hasPreviousSession을 위해 요청하는

if (!$request->hasPreviousSession()) { 
    return; 
} 

을 그리고있다하지만 로케일을 가지고 나던 나는이 원인이 무엇인지 모르는 :

0

잘 될지 모르겠습니다. 그러나 사용자가 로케일에 로그인하면 그/그녀의 세션에서 설정됩니다.

당신이 당신의 리스너에이 같은 작업을 수행 할 수 있습니다 사용자가 로켈을 선택합니다

$request = $event->getRequest(); 
    $session = $request->getSession(); 
    $locale = $session->get('_locale'); 
    if (!empty($locale)) { 
    $request->setLocale($locale); 
    } 

및 링크

당신이 어떤 행동

public function localeAction($locale) 
    { 
     $this->get('session')->set('_locale', $locale); 

     return $this->redirect($this->generateUrl('route')); 
    } 
를 만들 수 있습니다
2

당신은 단지 새로운 로케일을 설정할 필요가 있지만, 또한 사용자가 변경 사항을 적용하기 위해 사용자를 리디렉션 할 수도 있습니다.

또한 it's not a good practice to store the locale in the session — you should keep the locale in the URL입니다. 이렇게하면 적절한 로케일을 사용하는 URL로 리디렉션되는 것이 훨씬 더 적합합니다.

+0

하지만처럼 작동하지만 나는 번들이 사용자 로케일을 처리하지 생각하지 않는다 ... 그래서 i18n 번들의 요청은 항상 사용자의 로케일을 무시합니다. 물론 i18n 번들을 동작시키는 방법에 대한 아이디어가 있고 그에게 말하면 사용자 로케일을 덮어 쓰지 않아도됩니다. – SylvainB

+1

같은 방식으로 : 사용자 로케일이 다른 경우 다른 로케일로 리디렉션합니다. –

+0

어디에서, 듣는 사람? 거기에있는 경로를 추적 할 수 있습니까? – SylvainB

0

난 그냥 당신이 당신의 청취자에게 특별히이에 문제가있는 것을 발견 그러나 이것이 첫 번째 요청의 주요 문제입니다. 당신이 그것을 변경하는 경우 :

if ($request->hasPreviousSession() && $this->defaultLocale == $request->get('_locale')) { 
     return; 
    } 

내가 그 목적에 전에 jms_i18n를 사용 ... 매력 :

내가 아는
관련 문제