4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpKernel\EventListener;
14 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
15 use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
16 use Symfony\Component\HttpKernel\KernelEvents;
17 use Symfony\Component\HttpFoundation\RequestStack;
18 use Symfony\Component\HttpFoundation\Request;
19 use Symfony\Component\Routing\RequestContextAwareInterface;
20 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
23 * Initializes the locale based on the current request.
25 * This listener works in 2 modes:
27 * * 2.3 compatibility mode where you must call setRequest whenever the Request changes.
28 * * 2.4+ mode where you must pass a RequestStack instance in the constructor.
30 * @author Fabien Potencier <fabien@symfony.com>
32 class LocaleListener implements EventSubscriberInterface
35 private $defaultLocale;
36 private $requestStack;
41 * RequestStack will become required in 3.0.
43 * @param RequestStack $requestStack A RequestStack instance
44 * @param string $defaultLocale The default locale
45 * @param RequestContextAwareInterface|null $router The router
47 * @throws \InvalidArgumentException
49 public function __construct($requestStack = null, $defaultLocale = 'en', $router = null)
51 if ((null !== $requestStack && !$requestStack instanceof RequestStack) || $defaultLocale instanceof RequestContextAwareInterface || $router instanceof RequestStack) {
53 $router = func_num_args() < 2 ? null : $defaultLocale;
54 $defaultLocale = $requestStack;
55 $requestStack = func_num_args() < 3 ? null : $tmp;
57 @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as first argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
58 } elseif (!$requestStack instanceof RequestStack) {
59 @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
62 if (null !== $requestStack && !$requestStack instanceof RequestStack) {
63 throw new \InvalidArgumentException('RequestStack instance expected.');
65 if (null !== $router && !$router instanceof RequestContextAwareInterface) {
66 throw new \InvalidArgumentException('Router must implement RequestContextAwareInterface.');
69 $this->defaultLocale = $defaultLocale;
70 $this->requestStack = $requestStack;
71 $this->router = $router;
75 * Sets the current Request.
77 * This method was used to synchronize the Request, but as the HttpKernel
78 * is doing that automatically now, you should never call it directly.
79 * It is kept public for BC with the 2.3 version.
81 * @param Request|null $request A Request instance
83 * @deprecated since version 2.4, to be removed in 3.0.
85 public function setRequest(Request $request = null)
87 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED);
89 if (null === $request) {
93 $this->setLocale($request);
94 $this->setRouterContext($request);
97 public function onKernelRequest(GetResponseEvent $event)
99 $request = $event->getRequest();
100 $request->setDefaultLocale($this->defaultLocale);
102 $this->setLocale($request);
103 $this->setRouterContext($request);
106 public function onKernelFinishRequest(FinishRequestEvent $event)
108 if (null === $this->requestStack) {
109 return; // removed when requestStack is required
112 if (null !== $parentRequest = $this->requestStack->getParentRequest()) {
113 $this->setRouterContext($parentRequest);
117 private function setLocale(Request $request)
119 if ($locale = $request->attributes->get('_locale')) {
120 $request->setLocale($locale);
124 private function setRouterContext(Request $request)
126 if (null !== $this->router) {
127 $this->router->getContext()->setParameter('_locale', $request->getLocale());
131 public static function getSubscribedEvents()
134 // must be registered after the Router to have access to the _locale
135 KernelEvents::REQUEST => array(array('onKernelRequest', 16)),
136 KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)),