moved management of the locale from the Session class to the Request class
The locale management does not require sessions anymore. In the Symfony2 spirit, the locale should be part of your URLs. If this is the case (via the special _locale request attribute), Symfony will store it in the request (getLocale()). This feature is now also configurable/replaceable at will as everything is now managed by the new LocaleListener event listener. How to upgrade: The default locale configuration has been moved from session to the main configuration: Before: framework: session: default_locale: en After: framework: default_locale: en Whenever you want to get the current locale, call getLocale() on the request (was on the session before).
This commit is contained in:
parent
8b55541aee
commit
74bc699b27
|
@ -59,6 +59,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||||
|
|
||||||
### HttpFoundation
|
### HttpFoundation
|
||||||
|
|
||||||
|
* [BC BREAK] moved management of the locale from the Session class to the Request class
|
||||||
* added a generic access to the PHP built-in filter mechanism: ParameterBag::filter()
|
* added a generic access to the PHP built-in filter mechanism: ParameterBag::filter()
|
||||||
* made FileBinaryMimeTypeGuesser command configurable
|
* made FileBinaryMimeTypeGuesser command configurable
|
||||||
* added Request::getUser() and Request::getPassword()
|
* added Request::getUser() and Request::getPassword()
|
||||||
|
|
|
@ -3,11 +3,40 @@ UPGRADE FROM 2.0 to 2.1
|
||||||
|
|
||||||
* assets_base_urls and base_urls merging strategy has changed
|
* assets_base_urls and base_urls merging strategy has changed
|
||||||
|
|
||||||
Unlike most configuration blocks, successive values for
|
Unlike most configuration blocks, successive values for
|
||||||
``assets_base_urls`` will overwrite each other instead of being merged.
|
``assets_base_urls`` will overwrite each other instead of being merged.
|
||||||
This behavior was chosen because developers will typically define base
|
This behavior was chosen because developers will typically define base
|
||||||
URL's for each environment. Given that most projects tend to inherit
|
URL's for each environment. Given that most projects tend to inherit
|
||||||
configurations (e.g. ``config_test.yml`` imports ``config_dev.yml``)
|
configurations (e.g. ``config_test.yml`` imports ``config_dev.yml``)
|
||||||
and/or share a common base configuration (i.e. ``config.yml``), merging
|
and/or share a common base configuration (i.e. ``config.yml``), merging
|
||||||
could yield a set of base URL's for multiple environments.
|
could yield a set of base URL's for multiple environments.
|
||||||
|
|
||||||
|
* moved management of the locale from the Session class to the Request class
|
||||||
|
|
||||||
|
Configuring the default locale:
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
framework:
|
||||||
|
session:
|
||||||
|
default_locale: fr
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
framework:
|
||||||
|
default_locale: fr
|
||||||
|
|
||||||
|
Retrieving the locale from a Twig template:
|
||||||
|
|
||||||
|
Before: {{ app.request.session.locale }}
|
||||||
|
After: {{ app.request.locale }}
|
||||||
|
|
||||||
|
Retrieving the locale from a PHP template:
|
||||||
|
|
||||||
|
Before: $view['session']->getLocale()
|
||||||
|
After: $view['request']->getLocale()
|
||||||
|
|
||||||
|
Retrieving the locale from PHP code:
|
||||||
|
|
||||||
|
Before: $session->getLocale()
|
||||||
|
After: $request->getLocale()
|
||||||
|
|
|
@ -51,6 +51,7 @@ class Configuration implements ConfigurationInterface
|
||||||
->scalarNode('secret')->isRequired()->end()
|
->scalarNode('secret')->isRequired()->end()
|
||||||
->scalarNode('ide')->defaultNull()->end()
|
->scalarNode('ide')->defaultNull()->end()
|
||||||
->booleanNode('test')->end()
|
->booleanNode('test')->end()
|
||||||
|
->scalarNode('default_locale')->defaultValue('en')->end()
|
||||||
->end()
|
->end()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -161,7 +162,6 @@ class Configuration implements ConfigurationInterface
|
||||||
->canBeUnset()
|
->canBeUnset()
|
||||||
->children()
|
->children()
|
||||||
->booleanNode('auto_start')->defaultFalse()->end()
|
->booleanNode('auto_start')->defaultFalse()->end()
|
||||||
->scalarNode('default_locale')->defaultValue('en')->end()
|
|
||||||
->scalarNode('storage_id')->defaultValue('session.storage.native')->end()
|
->scalarNode('storage_id')->defaultValue('session.storage.native')->end()
|
||||||
->scalarNode('name')->end()
|
->scalarNode('name')->end()
|
||||||
->scalarNode('lifetime')->end()
|
->scalarNode('lifetime')->end()
|
||||||
|
|
|
@ -65,6 +65,8 @@ class FrameworkExtension extends Extension
|
||||||
|
|
||||||
$container->setParameter('kernel.trust_proxy_headers', $config['trust_proxy_headers']);
|
$container->setParameter('kernel.trust_proxy_headers', $config['trust_proxy_headers']);
|
||||||
|
|
||||||
|
$container->setParameter('kernel.default_locale', $config['default_locale']);
|
||||||
|
|
||||||
if (!empty($config['test'])) {
|
if (!empty($config['test'])) {
|
||||||
$loader->load('test.xml');
|
$loader->load('test.xml');
|
||||||
}
|
}
|
||||||
|
@ -280,7 +282,6 @@ class FrameworkExtension extends Extension
|
||||||
|
|
||||||
// session
|
// session
|
||||||
$container->getDefinition('session_listener')->addArgument($config['auto_start']);
|
$container->getDefinition('session_listener')->addArgument($config['auto_start']);
|
||||||
$container->setParameter('session.default_locale', $config['default_locale']);
|
|
||||||
|
|
||||||
// session storage
|
// session storage
|
||||||
$container->setAlias('session.storage', $config['storage_id']);
|
$container->setAlias('session.storage', $config['storage_id']);
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
|
use Symfony\Component\Routing\RouterInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the locale based on the current request.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class LocaleListener
|
||||||
|
{
|
||||||
|
private $router;
|
||||||
|
private $defaultLocale;
|
||||||
|
|
||||||
|
public function __construct($defaultLocale = 'en', RouterInterface $router = null)
|
||||||
|
{
|
||||||
|
$this->defaultLocale = $defaultLocale;
|
||||||
|
$this->router = $router;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEarlyKernelRequest(GetResponseEvent $event)
|
||||||
|
{
|
||||||
|
$request = $event->getRequest();
|
||||||
|
if ($request->hasPreviousSession()) {
|
||||||
|
$request->setDefaultLocale($request->getSession()->get('_locale', $this->defaultLocale));
|
||||||
|
} else {
|
||||||
|
$request->setDefaultLocale($this->defaultLocale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onKernelRequest(GetResponseEvent $event)
|
||||||
|
{
|
||||||
|
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = $event->getRequest();
|
||||||
|
if ($locale = $request->attributes->get('_locale')) {
|
||||||
|
$request->setLocale($locale);
|
||||||
|
|
||||||
|
if ($request->hasPreviousSession()) {
|
||||||
|
$request->getSession()->set('_locale', $request->getLocale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->router) {
|
||||||
|
$this->router->getContext()->setParameter('_locale', $request->getLocale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,19 +88,6 @@ class RouterListener
|
||||||
|
|
||||||
throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e);
|
throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
|
|
||||||
$context = $this->router->getContext();
|
|
||||||
$session = $request->getSession();
|
|
||||||
if ($locale = $request->attributes->get('_locale')) {
|
|
||||||
if ($session) {
|
|
||||||
$session->setLocale($locale);
|
|
||||||
}
|
|
||||||
$context->setParameter('_locale', $locale);
|
|
||||||
} elseif ($session) {
|
|
||||||
$context->setParameter('_locale', $session->getLocale());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parametersToString(array $parameters)
|
private function parametersToString(array $parameters)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<xsd:attribute name="trust-proxy-headers" type="xsd:string" />
|
<xsd:attribute name="trust-proxy-headers" type="xsd:string" />
|
||||||
<xsd:attribute name="ide" type="xsd:string" />
|
<xsd:attribute name="ide" type="xsd:string" />
|
||||||
<xsd:attribute name="secret" type="xsd:string" />
|
<xsd:attribute name="secret" type="xsd:string" />
|
||||||
|
<xsd:attribute name="default-locale" type="xsd:string" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="form">
|
<xsd:complexType name="form">
|
||||||
|
@ -72,7 +73,6 @@
|
||||||
|
|
||||||
<xsd:complexType name="session">
|
<xsd:complexType name="session">
|
||||||
<xsd:attribute name="storage-id" type="xsd:string" />
|
<xsd:attribute name="storage-id" type="xsd:string" />
|
||||||
<xsd:attribute name="default-locale" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
<xsd:attribute name="lifetime" type="xsd:integer" />
|
<xsd:attribute name="lifetime" type="xsd:integer" />
|
||||||
<xsd:attribute name="path" type="xsd:string" />
|
<xsd:attribute name="path" type="xsd:string" />
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
<services>
|
<services>
|
||||||
<service id="session" class="%session.class%">
|
<service id="session" class="%session.class%">
|
||||||
<argument type="service" id="session.storage" />
|
<argument type="service" id="session.storage" />
|
||||||
<argument>%session.default_locale%</argument>
|
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="session.storage.native" class="%session.storage.native.class%" public="false">
|
<service id="session.storage.native" class="%session.storage.native.class%" public="false">
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
<argument key="debug">%kernel.debug%</argument>
|
<argument key="debug">%kernel.debug%</argument>
|
||||||
<argument key="charset">%kernel.charset%</argument>
|
<argument key="charset">%kernel.charset%</argument>
|
||||||
</argument>
|
</argument>
|
||||||
<argument type="service" id="session" on-invalid="ignore" />
|
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="translator" class="%translator.identity.class%">
|
<service id="translator" class="%translator.identity.class%">
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<parameter key="controller_resolver.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver</parameter>
|
<parameter key="controller_resolver.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver</parameter>
|
||||||
<parameter key="controller_name_converter.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser</parameter>
|
<parameter key="controller_name_converter.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser</parameter>
|
||||||
<parameter key="response_listener.class">Symfony\Component\HttpKernel\EventListener\ResponseListener</parameter>
|
<parameter key="response_listener.class">Symfony\Component\HttpKernel\EventListener\ResponseListener</parameter>
|
||||||
|
<parameter key="locale_listener.class">Symfony\Bundle\FrameworkBundle\EventListener\LocaleListener</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
|
@ -27,5 +28,12 @@
|
||||||
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
|
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
|
||||||
<argument>%kernel.charset%</argument>
|
<argument>%kernel.charset%</argument>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="locale_listener" class="%locale_listener.class%">
|
||||||
|
<tag name="kernel.event_listener" event="kernel.request" method="onEarlyKernelRequest" priority="255" />
|
||||||
|
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="-1" />
|
||||||
|
<argument>%kernel.default_locale%</argument>
|
||||||
|
<argument type="service" id="router" on-invalid="ignore" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
|
|
@ -46,6 +46,16 @@ class RequestHelper extends Helper
|
||||||
return $this->request->get($key, $default);
|
return $this->request->get($key, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the locale
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLocale()
|
||||||
|
{
|
||||||
|
return $this->request->getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the canonical name of this helper.
|
* Returns the canonical name of this helper.
|
||||||
*
|
*
|
||||||
|
|
|
@ -46,16 +46,6 @@ class SessionHelper extends Helper
|
||||||
return $this->session->get($name, $default);
|
return $this->session->get($name, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the locale
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getLocale()
|
|
||||||
{
|
|
||||||
return $this->session->getLocale();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFlash($name, $default = null)
|
public function getFlash($name, $default = null)
|
||||||
{
|
{
|
||||||
return $this->session->getFlash($name, $default);
|
return $this->session->getFlash($name, $default);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
$container->loadFromExtension('framework', array(
|
$container->loadFromExtension('framework', array(
|
||||||
'secret' => 's3cr3t',
|
'secret' => 's3cr3t',
|
||||||
|
'default_locale' => 'fr',
|
||||||
'form' => null,
|
'form' => null,
|
||||||
'csrf_protection' => array(
|
'csrf_protection' => array(
|
||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
|
@ -19,7 +20,6 @@ $container->loadFromExtension('framework', array(
|
||||||
),
|
),
|
||||||
'session' => array(
|
'session' => array(
|
||||||
'auto_start' => true,
|
'auto_start' => true,
|
||||||
'default_locale' => 'fr',
|
|
||||||
'storage_id' => 'session.storage.native',
|
'storage_id' => 'session.storage.native',
|
||||||
'name' => '_SYMFONY',
|
'name' => '_SYMFONY',
|
||||||
'lifetime' => 86400,
|
'lifetime' => 86400,
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
|
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
|
||||||
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||||||
|
|
||||||
<framework:config secret="s3cr3t" ide="file%%link%%format">
|
<framework:config secret="s3cr3t" ide="file%%link%%format" default-locale="fr">
|
||||||
<framework:csrf-protection enabled="true" field-name="_csrf" />
|
<framework:csrf-protection enabled="true" field-name="_csrf" />
|
||||||
<framework:form />
|
<framework:form />
|
||||||
<framework:esi enabled="true" />
|
<framework:esi enabled="true" />
|
||||||
<framework:profiler only-exceptions="true" />
|
<framework:profiler only-exceptions="true" />
|
||||||
<framework:router resource="%kernel.root_dir%/config/routing.xml" type="xml" />
|
<framework:router resource="%kernel.root_dir%/config/routing.xml" type="xml" />
|
||||||
<framework:session auto-start="true" default-locale="fr" storage-id="session.storage.native" name="_SYMFONY" lifetime="86400" path="/" domain="example.com" secure="true" httponly="true" />
|
<framework:session auto-start="true" storage-id="session.storage.native" name="_SYMFONY" lifetime="86400" path="/" domain="example.com" secure="true" httponly="true" />
|
||||||
<framework:templating assets-version="SomeVersionScheme" cache="/path/to/cache" >
|
<framework:templating assets-version="SomeVersionScheme" cache="/path/to/cache" >
|
||||||
<framework:loader>loader.foo</framework:loader>
|
<framework:loader>loader.foo</framework:loader>
|
||||||
<framework:loader>loader.bar</framework:loader>
|
<framework:loader>loader.bar</framework:loader>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
framework:
|
framework:
|
||||||
secret: s3cr3t
|
secret: s3cr3t
|
||||||
|
default_locale: fr
|
||||||
form: ~
|
form: ~
|
||||||
csrf_protection:
|
csrf_protection:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
@ -13,7 +14,6 @@ framework:
|
||||||
type: xml
|
type: xml
|
||||||
session:
|
session:
|
||||||
auto_start: true
|
auto_start: true
|
||||||
default_locale: fr
|
|
||||||
storage_id: session.storage.native
|
storage_id: session.storage.native
|
||||||
name: _SYMFONY
|
name: _SYMFONY
|
||||||
lifetime: 86400
|
lifetime: 86400
|
||||||
|
|
|
@ -76,8 +76,7 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||||
$container = $this->createContainerFromFile('full');
|
$container = $this->createContainerFromFile('full');
|
||||||
|
|
||||||
$this->assertTrue($container->hasDefinition('session'), '->registerSessionConfiguration() loads session.xml');
|
$this->assertTrue($container->hasDefinition('session'), '->registerSessionConfiguration() loads session.xml');
|
||||||
$this->assertEquals('fr', $container->getParameter('session.default_locale'));
|
$this->assertEquals('fr', $container->getParameter('kernel.default_locale'));
|
||||||
$this->assertEquals('%session.default_locale%', $container->getDefinition('session')->getArgument(1));
|
|
||||||
$this->assertTrue($container->getDefinition('session_listener')->getArgument(1));
|
$this->assertTrue($container->getDefinition('session_listener')->getArgument(1));
|
||||||
$this->assertEquals('session.storage.native', (string) $container->getAlias('session.storage'));
|
$this->assertEquals('session.storage.native', (string) $container->getAlias('session.storage'));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\Tests\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\EventListener\LocaleListener;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
|
|
||||||
|
class LocaleListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testDefaultLocaleWithoutSession()
|
||||||
|
{
|
||||||
|
$listener = new LocaleListener('fr');
|
||||||
|
$event = $this->getEvent($request = Request::create('/'));
|
||||||
|
|
||||||
|
$listener->onEarlyKernelRequest($event);
|
||||||
|
$this->assertEquals('fr', $request->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultLocaleWithSession()
|
||||||
|
{
|
||||||
|
$request = Request::create('/');
|
||||||
|
session_name('foo');
|
||||||
|
$request->cookies->set('foo', 'value');
|
||||||
|
|
||||||
|
$session = $this->getMock('Symfony\Component\HttpFoundation\Session', array('get'), array(), '', false);
|
||||||
|
$session->expects($this->once())->method('get')->will($this->returnValue('es'));
|
||||||
|
$request->setSession($session);
|
||||||
|
|
||||||
|
$listener = new LocaleListener('fr');
|
||||||
|
$event = $this->getEvent($request);
|
||||||
|
|
||||||
|
$listener->onEarlyKernelRequest($event);
|
||||||
|
$this->assertEquals('es', $request->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLocaleFromRequestAttribute()
|
||||||
|
{
|
||||||
|
$request = Request::create('/');
|
||||||
|
session_name('foo');
|
||||||
|
$request->cookies->set('foo', 'value');
|
||||||
|
|
||||||
|
$request->attributes->set('_locale', 'es');
|
||||||
|
$listener = new LocaleListener('fr');
|
||||||
|
$event = $this->getEvent($request);
|
||||||
|
|
||||||
|
// also updates the session _locale value
|
||||||
|
$session = $this->getMock('Symfony\Component\HttpFoundation\Session', array('set'), array(), '', false);
|
||||||
|
$session->expects($this->once())->method('set')->with('_locale', 'es');
|
||||||
|
$request->setSession($session);
|
||||||
|
|
||||||
|
$listener->onKernelRequest($event);
|
||||||
|
$this->assertEquals('es', $request->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLocaleSetForRoutingContext()
|
||||||
|
{
|
||||||
|
// the request context is updated
|
||||||
|
$context = $this->getMock('Symfony\Component\Routing\RequestContext');
|
||||||
|
$context->expects($this->once())->method('setParameter')->with('_locale', 'es');
|
||||||
|
|
||||||
|
$router = $this->getMock('Symfony\Component\Routing\Router', array('getContext'), array(), '', false);
|
||||||
|
$router->expects($this->once())->method('getContext')->will($this->returnValue($context));
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
|
||||||
|
$request->attributes->set('_locale', 'es');
|
||||||
|
$listener = new LocaleListener('fr', $router);
|
||||||
|
$listener->onKernelRequest($this->getEvent($request));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getEvent(Request $request)
|
||||||
|
{
|
||||||
|
return new GetResponseEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, HttpKernelInterface::MASTER_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,13 @@ class RequestHelperTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertNull($helper->getParameter('foo'));
|
$this->assertNull($helper->getParameter('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetLocale()
|
||||||
|
{
|
||||||
|
$helper = new RequestHelper($this->request);
|
||||||
|
|
||||||
|
$this->assertEquals('en', $helper->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetName()
|
public function testGetName()
|
||||||
{
|
{
|
||||||
$helper = new RequestHelper($this->request);
|
$helper = new RequestHelper($this->request);
|
||||||
|
|
|
@ -60,13 +60,6 @@ class SessionHelperTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertNull($helper->get('foo'));
|
$this->assertNull($helper->get('foo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetLocale()
|
|
||||||
{
|
|
||||||
$helper = new SessionHelper($this->request);
|
|
||||||
|
|
||||||
$this->assertEquals('en', $helper->getLocale());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetName()
|
public function testGetName()
|
||||||
{
|
{
|
||||||
$helper = new SessionHelper($this->request);
|
$helper = new SessionHelper($this->request);
|
||||||
|
|
|
@ -15,7 +15,6 @@ use Symfony\Component\Translation\Translator as BaseTranslator;
|
||||||
use Symfony\Component\Translation\Loader\LoaderInterface;
|
use Symfony\Component\Translation\Loader\LoaderInterface;
|
||||||
use Symfony\Component\Translation\MessageSelector;
|
use Symfony\Component\Translation\MessageSelector;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\HttpFoundation\Session;
|
|
||||||
use Symfony\Component\Config\ConfigCache;
|
use Symfony\Component\Config\ConfigCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +26,6 @@ class Translator extends BaseTranslator
|
||||||
{
|
{
|
||||||
protected $container;
|
protected $container;
|
||||||
protected $options;
|
protected $options;
|
||||||
protected $session;
|
|
||||||
protected $loaderIds;
|
protected $loaderIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,11 +40,9 @@ class Translator extends BaseTranslator
|
||||||
* @param MessageSelector $selector The message selector for pluralization
|
* @param MessageSelector $selector The message selector for pluralization
|
||||||
* @param array $loaderIds An array of loader Ids
|
* @param array $loaderIds An array of loader Ids
|
||||||
* @param array $options An array of options
|
* @param array $options An array of options
|
||||||
* @param Session $session A Session instance
|
|
||||||
*/
|
*/
|
||||||
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array(), Session $session = null)
|
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array())
|
||||||
{
|
{
|
||||||
$this->session = $session;
|
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
$this->loaderIds = $loaderIds;
|
$this->loaderIds = $loaderIds;
|
||||||
|
|
||||||
|
@ -74,8 +70,8 @@ class Translator extends BaseTranslator
|
||||||
*/
|
*/
|
||||||
public function getLocale()
|
public function getLocale()
|
||||||
{
|
{
|
||||||
if (null === $this->locale && null !== $this->session) {
|
if (null === $this->locale && $this->container->has('request')) {
|
||||||
$this->locale = $this->session->getLocale();
|
$this->locale = $this->container->get('request')->getLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->locale;
|
return $this->locale;
|
||||||
|
|
|
@ -7,8 +7,8 @@ framework:
|
||||||
validation: { enabled: true, enable_annotations: true }
|
validation: { enabled: true, enable_annotations: true }
|
||||||
form: ~
|
form: ~
|
||||||
test: ~
|
test: ~
|
||||||
|
default_locale: en
|
||||||
session:
|
session:
|
||||||
default_locale: en
|
|
||||||
auto_start: true
|
auto_start: true
|
||||||
storage_id: session.storage.filesystem
|
storage_id: session.storage.filesystem
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,8 @@ class Request
|
||||||
protected $method;
|
protected $method;
|
||||||
protected $format;
|
protected $format;
|
||||||
protected $session;
|
protected $session;
|
||||||
|
protected $locale;
|
||||||
|
protected $defaultLocale = 'en';
|
||||||
|
|
||||||
static protected $formats;
|
static protected $formats;
|
||||||
|
|
||||||
|
@ -892,6 +894,21 @@ class Request
|
||||||
$this->format = $format;
|
$this->format = $format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setDefaultLocale($locale)
|
||||||
|
{
|
||||||
|
$this->setPhpDefaultLocale($this->defaultLocale = $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLocale($locale)
|
||||||
|
{
|
||||||
|
$this->setPhpDefaultLocale($this->locale = $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLocale()
|
||||||
|
{
|
||||||
|
return null === $this->locale ? $this->defaultLocale : $this->locale;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the method is safe or not.
|
* Checks whether the method is safe or not.
|
||||||
*
|
*
|
||||||
|
@ -1262,4 +1279,17 @@ class Request
|
||||||
'rss' => array('application/rss+xml'),
|
'rss' => array('application/rss+xml'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setPhpDefaultLocale($locale)
|
||||||
|
{
|
||||||
|
// if either the class Locale doesn't exist, or an exception is thrown when
|
||||||
|
// setting the default locale, the intl module is not installed, and
|
||||||
|
// the call can be ignored:
|
||||||
|
try {
|
||||||
|
if (class_exists('Locale', false)) {
|
||||||
|
\Locale::setDefault($locale);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,25 +27,19 @@ class Session implements \Serializable
|
||||||
protected $attributes;
|
protected $attributes;
|
||||||
protected $flashes;
|
protected $flashes;
|
||||||
protected $oldFlashes;
|
protected $oldFlashes;
|
||||||
protected $locale;
|
|
||||||
protected $defaultLocale;
|
|
||||||
protected $closed;
|
protected $closed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param SessionStorageInterface $storage A SessionStorageInterface instance
|
* @param SessionStorageInterface $storage A SessionStorageInterface instance
|
||||||
* @param string $defaultLocale The default locale
|
|
||||||
*/
|
*/
|
||||||
public function __construct(SessionStorageInterface $storage, $defaultLocale = 'en')
|
public function __construct(SessionStorageInterface $storage)
|
||||||
{
|
{
|
||||||
$this->storage = $storage;
|
$this->storage = $storage;
|
||||||
$this->defaultLocale = $defaultLocale;
|
|
||||||
$this->locale = $defaultLocale;
|
|
||||||
$this->flashes = array();
|
$this->flashes = array();
|
||||||
$this->oldFlashes = array();
|
$this->oldFlashes = array();
|
||||||
$this->attributes = array();
|
$this->attributes = array();
|
||||||
$this->setPhpDefaultLocale($this->defaultLocale);
|
|
||||||
$this->started = false;
|
$this->started = false;
|
||||||
$this->closed = false;
|
$this->closed = false;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +62,6 @@ class Session implements \Serializable
|
||||||
if (isset($attributes['attributes'])) {
|
if (isset($attributes['attributes'])) {
|
||||||
$this->attributes = $attributes['attributes'];
|
$this->attributes = $attributes['attributes'];
|
||||||
$this->flashes = $attributes['flashes'];
|
$this->flashes = $attributes['flashes'];
|
||||||
$this->locale = $attributes['locale'];
|
|
||||||
$this->setPhpDefaultLocale($this->locale);
|
|
||||||
|
|
||||||
// flag current flash messages to be removed at shutdown
|
// flag current flash messages to be removed at shutdown
|
||||||
$this->oldFlashes = $this->flashes;
|
$this->oldFlashes = $this->flashes;
|
||||||
|
@ -183,7 +175,6 @@ class Session implements \Serializable
|
||||||
|
|
||||||
$this->attributes = array();
|
$this->attributes = array();
|
||||||
$this->flashes = array();
|
$this->flashes = array();
|
||||||
$this->setPhpDefaultLocale($this->locale = $this->defaultLocale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,30 +215,6 @@ class Session implements \Serializable
|
||||||
return $this->storage->getId();
|
return $this->storage->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the locale
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getLocale()
|
|
||||||
{
|
|
||||||
return $this->locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the locale.
|
|
||||||
*
|
|
||||||
* @param string $locale
|
|
||||||
*/
|
|
||||||
public function setLocale($locale)
|
|
||||||
{
|
|
||||||
if (false === $this->started) {
|
|
||||||
$this->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setPhpDefaultLocale($this->locale = $locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the flash messages.
|
* Gets the flash messages.
|
||||||
*
|
*
|
||||||
|
@ -356,7 +323,6 @@ class Session implements \Serializable
|
||||||
$this->storage->write('_symfony2', array(
|
$this->storage->write('_symfony2', array(
|
||||||
'attributes' => $this->attributes,
|
'attributes' => $this->attributes,
|
||||||
'flashes' => $this->flashes,
|
'flashes' => $this->flashes,
|
||||||
'locale' => $this->locale,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,26 +346,13 @@ class Session implements \Serializable
|
||||||
|
|
||||||
public function serialize()
|
public function serialize()
|
||||||
{
|
{
|
||||||
return serialize(array($this->storage, $this->defaultLocale));
|
return serialize($this->storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unserialize($serialized)
|
public function unserialize($serialized)
|
||||||
{
|
{
|
||||||
list($this->storage, $this->defaultLocale) = unserialize($serialized);
|
$this->storage = unserialize($serialized);
|
||||||
$this->attributes = array();
|
$this->attributes = array();
|
||||||
$this->started = false;
|
$this->started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setPhpDefaultLocale($locale)
|
|
||||||
{
|
|
||||||
// if either the class Locale doesn't exist, or an exception is thrown when
|
|
||||||
// setting the default locale, the intl module is not installed, and
|
|
||||||
// the call can be ignored:
|
|
||||||
try {
|
|
||||||
if (class_exists('Locale', false)) {
|
|
||||||
\Locale::setDefault($locale);
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,11 +127,7 @@ class HttpUtils
|
||||||
try {
|
try {
|
||||||
$parameters = $this->router->match($request->getPathInfo());
|
$parameters = $this->router->match($request->getPathInfo());
|
||||||
|
|
||||||
if (isset($parameters['_locale'])) {
|
$context->setParameter('_locale', isset($parameters['_locale']) ? $parameters['_locale'] : $request->getLocale());
|
||||||
$context->setParameter('_locale', $parameters['_locale']);
|
|
||||||
} elseif ($session = $request->getSession()) {
|
|
||||||
$context->setParameter('_locale', $session->getLocale());
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// let's hope user doesn't use the locale in the path
|
// let's hope user doesn't use the locale in the path
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,10 +146,7 @@ class RequestMatcherTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$matcher = new RequestMatcher();
|
$matcher = new RequestMatcher();
|
||||||
$request = Request::create('/en/login');
|
$request = Request::create('/en/login');
|
||||||
|
$request->setLocale('en');
|
||||||
$session = new Session(new ArraySessionStorage());
|
|
||||||
$session->setLocale('en');
|
|
||||||
$request->setSession($session);
|
|
||||||
|
|
||||||
$matcher->matchPath('^/{_locale}/login$');
|
$matcher->matchPath('^/{_locale}/login$');
|
||||||
$this->assertFalse($matcher->matches($request));
|
$this->assertFalse($matcher->matches($request));
|
||||||
|
|
|
@ -128,34 +128,28 @@ class SessionTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testSerialize()
|
public function testSerialize()
|
||||||
{
|
{
|
||||||
$defaultLocale = 'en';
|
$this->session = new Session($this->storage);
|
||||||
$this->session = new Session($this->storage, $defaultLocale);
|
|
||||||
|
|
||||||
$compare = serialize(array($this->storage, $defaultLocale));
|
$compare = serialize($this->storage);
|
||||||
|
|
||||||
$this->assertSame($compare, $this->session->serialize());
|
$this->assertSame($compare, $this->session->serialize());
|
||||||
|
|
||||||
$this->session->unserialize($compare);
|
$this->session->unserialize($compare);
|
||||||
|
|
||||||
$_defaultLocale = new \ReflectionProperty(get_class($this->session), 'defaultLocale');
|
|
||||||
$_defaultLocale->setAccessible(true);
|
|
||||||
|
|
||||||
$_storage = new \ReflectionProperty(get_class($this->session), 'storage');
|
$_storage = new \ReflectionProperty(get_class($this->session), 'storage');
|
||||||
$_storage->setAccessible(true);
|
$_storage->setAccessible(true);
|
||||||
|
|
||||||
$this->assertEquals($_defaultLocale->getValue($this->session), $defaultLocale, 'options match');
|
|
||||||
$this->assertEquals($_storage->getValue($this->session), $this->storage, 'storage match');
|
$this->assertEquals($_storage->getValue($this->session), $this->storage, 'storage match');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSave()
|
public function testSave()
|
||||||
{
|
{
|
||||||
$this->storage = new ArraySessionStorage();
|
$this->storage = new ArraySessionStorage();
|
||||||
$defaultLocale = 'fr';
|
$this->session = new Session($this->storage);
|
||||||
$this->session = new Session($this->storage, $defaultLocale);
|
|
||||||
$this->session->set('foo', 'bar');
|
$this->session->set('foo', 'bar');
|
||||||
|
|
||||||
$this->session->save();
|
$this->session->save();
|
||||||
$compare = array('_symfony2' => array('attributes' => array('foo' => 'bar'), 'flashes' => array(), 'locale' => 'fr'));
|
$compare = array('_symfony2' => array('attributes' => array('foo' => 'bar'), 'flashes' => array()));
|
||||||
|
|
||||||
$r = new \ReflectionObject($this->storage);
|
$r = new \ReflectionObject($this->storage);
|
||||||
$p = $r->getProperty('data');
|
$p = $r->getProperty('data');
|
||||||
|
@ -164,27 +158,6 @@ class SessionTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame($p->getValue($this->storage), $compare);
|
$this->assertSame($p->getValue($this->storage), $compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLocale()
|
|
||||||
{
|
|
||||||
$this->assertSame('en', $this->session->getLocale(), 'default locale is en');
|
|
||||||
$this->assertSame('en', \Locale::getDefault(), '\Locale::getDefault() is en');
|
|
||||||
|
|
||||||
$this->session->setLocale('de');
|
|
||||||
$this->assertSame('de', $this->session->getLocale(), 'locale is de');
|
|
||||||
$this->assertSame('de', \Locale::getDefault(), '\Locale::getDefault() is de');
|
|
||||||
|
|
||||||
$this->session = $this->getSession();
|
|
||||||
$this->session->setLocale('fr');
|
|
||||||
$this->assertSame('fr', $this->session->getLocale(), 'locale is fr');
|
|
||||||
$this->assertSame('fr', \Locale::getDefault(), '\Locale::getDefault() is fr');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLocaleAfterClear()
|
|
||||||
{
|
|
||||||
$this->session->clear();
|
|
||||||
$this->assertEquals('en', $this->session->getLocale());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetId()
|
public function testGetId()
|
||||||
{
|
{
|
||||||
$this->assertNull($this->session->getId());
|
$this->assertNull($this->session->getId());
|
||||||
|
@ -194,9 +167,6 @@ class SessionTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$this->session->start();
|
$this->session->start();
|
||||||
|
|
||||||
$this->assertSame('en', $this->session->getLocale());
|
|
||||||
$this->assertSame('en', \Locale::getDefault());
|
|
||||||
|
|
||||||
$this->assertSame(array(), $this->session->getFlashes());
|
$this->assertSame(array(), $this->session->getFlashes());
|
||||||
$this->assertSame(array(), $this->session->all());
|
$this->assertSame(array(), $this->session->all());
|
||||||
}
|
}
|
||||||
|
@ -210,7 +180,6 @@ class SessionTest extends \PHPUnit_Framework_TestCase
|
||||||
$expected = array(
|
$expected = array(
|
||||||
'attributes'=>array('foo'=>'bar'),
|
'attributes'=>array('foo'=>'bar'),
|
||||||
'flashes'=>array(),
|
'flashes'=>array(),
|
||||||
'locale'=>'en'
|
|
||||||
);
|
);
|
||||||
$saved = $this->storage->read('_symfony2');
|
$saved = $this->storage->read('_symfony2');
|
||||||
$this->assertSame($expected, $saved);
|
$this->assertSame($expected, $saved);
|
||||||
|
@ -227,7 +196,6 @@ class SessionTest extends \PHPUnit_Framework_TestCase
|
||||||
$expected = array(
|
$expected = array(
|
||||||
'attributes'=>array('foo'=>'bar'),
|
'attributes'=>array('foo'=>'bar'),
|
||||||
'flashes'=>array(),
|
'flashes'=>array(),
|
||||||
'locale'=>'en'
|
|
||||||
);
|
);
|
||||||
$saved = $this->storage->read('_symfony2');
|
$saved = $this->storage->read('_symfony2');
|
||||||
$this->assertSame($expected, $saved);
|
$this->assertSame($expected, $saved);
|
||||||
|
|
Reference in New Issue