Browse Source

merged branch francisbesset/session_locale (PR #686)

Commits
-------

72c074a [Session] Used \Locale::setDefault() when the locale is setted

Discussion
----------

[Session] Used \Locale::setDefault() when the locale is setted

For `DateType` in form component (by example), `\Locale::getDefault()` is used to displayed the name of months.

If `\Locale` class is not used when the locale is setted in the session, the name of months is not in a good language.
This PR solves this problem.

---------------------------------------------------------------------------

by pborreli at 2011/05/29 09:13:44 -0700

what if user doesn't have intl extension ?

---------------------------------------------------------------------------

by stof at 2011/05/29 09:24:04 -0700

You should wrap the calls to ``\Locale::setDefault`` in a ``class_exist`` check to avoid issue when using the stub implementation (for which calling ``setDefault`` is forbidden).

---------------------------------------------------------------------------

by francisbesset at 2011/05/29 09:26:40 -0700

@pborreli: Symfony have a fake Locale class and this class is used only if the server haven't intl enabled.

---------------------------------------------------------------------------

by stof at 2011/05/29 09:33:16 -0700

@francisbesset Yeah, but ``setDefault`` throw a ``BadMethodCall`` exception.

and so the check has to use ``extension_loaded`` instead of ``class_exists``.

---------------------------------------------------------------------------

by fabpot at 2011/06/13 10:12:15 -0700

Ticket #1121 is related to this PR.

---------------------------------------------------------------------------

by fabpot at 2011/06/15 06:18:28 -0700

I have just tried another implementation where the locale is passed as an argument to the built-in types and some data transformers (via a `LocaleAwareInterface` interface). That works fine as forms are immutable now, but the solution is obviously more "complex" as we need to pass the locale to many different classes. Also, using `Locale::setDefault()` has an advantage over my method: you can change the locale whenever you want within a PHP process (which can be useful even if this is an edge case). Last, but not the least, if make sense to update the PHP Locale to the user locale.

So, to sum up, this patch is probably the best solution (easy and flexible enough).
Fabien Potencier 14 năm trước cách đây
mục cha
commit
570db760ae

+ 14 - 2
src/Symfony/Component/HttpFoundation/Session.php

@@ -37,6 +37,7 @@ class Session implements \Serializable
         $this->storage = $storage;
         $this->defaultLocale = $defaultLocale;
         $this->attributes = array('_flash' => array(), '_locale' => $this->defaultLocale);
+        \Locale::setDefault($this->attributes['_locale']);
         $this->started = false;
     }
 
@@ -61,6 +62,8 @@ class Session implements \Serializable
             $this->attributes['_locale'] = $this->defaultLocale;
         }
 
+        \Locale::setDefault($this->attributes['_locale']);
+
         // flag current flash messages to be removed at shutdown
         $this->oldFlashes = array_flip(array_keys($this->attributes['_flash']));
 
@@ -104,7 +107,11 @@ class Session implements \Serializable
             $this->start();
         }
 
-        $this->attributes[$name] = $value;
+        if ('_locale' === $name) {
+            $this->setLocale($value);
+        } else {
+            $this->attributes[$name] = $value;
+        }
     }
 
     /**
@@ -128,6 +135,10 @@ class Session implements \Serializable
             $this->start();
         }
 
+        if (isset($attributes['_locale'])) {
+            $this->setLocale($attributes['_locale']);
+        }
+
         $this->attributes = $attributes;
     }
 
@@ -212,7 +223,7 @@ class Session implements \Serializable
             $this->start();
         }
 
-        $this->attributes['_locale'] = $locale;
+        \Locale::setDefault($this->attributes['_locale'] = $locale);
     }
 
     /**
@@ -321,6 +332,7 @@ class Session implements \Serializable
         if (isset($this->attributes['_flash'])) {
             $this->attributes['_flash'] = array_diff_key($this->attributes['_flash'], $this->oldFlashes);
         }
+
         $this->storage->write('_symfony2', $this->attributes);
     }
 

+ 10 - 1
tests/Symfony/Tests/Component/HttpFoundation/SessionTest.php

@@ -162,14 +162,20 @@ class SessionTest extends \PHPUnit_Framework_TestCase
     public function testLocale()
     {
         $this->assertSame('en', $this->session->getLocale(), 'default locale is en');
+        $this->assertSame('en', \Locale::getDefault(), '\Locale::getDefault() is en');
 
         $this->session->set('_locale','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');
+
+        $this->session->setAttributes(array('_locale' => 'de'));
+        $this->assertSame('de', $this->session->getLocale(), 'locale is de');
+        $this->assertSame('de', \Locale::getDefault(), '\Locale::getDefault() is de');
     }
 
     public function testLocaleAfterClear()
@@ -188,11 +194,14 @@ class SessionTest extends \PHPUnit_Framework_TestCase
         $this->session->start();
 
         $this->assertSame('en', $this->session->getLocale());
+        $this->assertSame('en', \Locale::getDefault());
+
         $this->assertSame(array(), $this->session->getFlashes());
         $this->assertSame(array('_flash' => array(), '_locale' => 'en'), $this->session->getAttributes());
 
         $this->session->start();
         $this->assertSame('en', $this->session->getLocale());
+        $this->assertSame('en', \Locale::getDefault());
     }
 
     protected function getSession()