diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
index 90b8d7989f..649f5298cf 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
@@ -35,6 +35,7 @@
%kernel.cache_dir%/translations
%kernel.debug%
+ %kernel.charset%
diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
index 34eb0395dc..1a9fd3efbd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
@@ -46,8 +46,6 @@ class Translator extends BaseTranslator
*/
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array(), Session $session = null)
{
- parent::__construct(null, $selector);
-
$this->session = $session;
$this->container = $container;
$this->loaderIds = $loaderIds;
@@ -55,6 +53,7 @@ class Translator extends BaseTranslator
$this->options = array(
'cache_dir' => null,
'debug' => false,
+ 'charset' => null,
);
// check option names
@@ -63,6 +62,11 @@ class Translator extends BaseTranslator
}
$this->options = array_merge($this->options, $options);
+
+ if ($this->options['charset'] === 'UTF-8') {
+ $this->options['charset'] = null;
+ }
+ parent::__construct(null, $selector, $this->options['charset']);
}
/**
diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php
index 6661af0b27..2bdff61243 100644
--- a/src/Symfony/Component/Translation/Translator.php
+++ b/src/Symfony/Component/Translation/Translator.php
@@ -28,16 +28,18 @@ class Translator implements TranslatorInterface
private $loaders;
private $resources;
private $selector;
+ private $charset;
/**
* Constructor.
*
* @param string $locale The locale
* @param MessageSelector $selector The message selector for pluralization
+ * @param string $charset Application charset
*
* @api
*/
- public function __construct($locale, MessageSelector $selector)
+ public function __construct($locale, MessageSelector $selector, $charset = null)
{
$this->locale = $locale;
$this->selector = $selector;
@@ -45,6 +47,7 @@ class Translator implements TranslatorInterface
$this->resources = array();
$this->catalogues = array();
$this->fallbackLocales = array();
+ $this->charset = $charset;
}
/**
@@ -173,7 +176,18 @@ class Translator implements TranslatorInterface
if (!isset($this->loaders[$resource[0]])) {
throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0]));
}
- $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
+ $catalogue = $this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]);
+ if (null !== $this->charset && extension_loaded('mbstring')) {
+ foreach ($catalogue->all() as $domain => $messages) {
+ foreach ($messages as $key => $translation) {
+ $srcCharset = mb_detect_encoding($translation);
+ if ($srcCharset !== $this->charset) {
+ $catalogue->set($key, mb_convert_encoding($translation, $this->charset, $srcCharset), $domain);
+ }
+ }
+ }
+ }
+ $this->catalogues[$locale]->addCatalogue($catalogue);
}
}
}
diff --git a/tests/Symfony/Tests/Component/Translation/TranslatorTest.php b/tests/Symfony/Tests/Component/Translation/TranslatorTest.php
index f1eb5ee807..111ed7e7aa 100644
--- a/tests/Symfony/Tests/Component/Translation/TranslatorTest.php
+++ b/tests/Symfony/Tests/Component/Translation/TranslatorTest.php
@@ -132,6 +132,27 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
}
+ /**
+ * @dataProvider getLoadCatalogueTests
+ */
+ public function testLoadCatalogueConvertsEncoding($translation, $charset)
+ {
+ if (!extension_loaded('mbstring')) {
+ $this->markTestSkipped('This test relies on the mbstring extension');
+ }
+ $translator = new Translator('en', new MessageSelector(), $charset);
+ $translator->addLoader('array', new ArrayLoader());
+ $translator->addResource('array', array('id' => $translation), 'en', 'messages');
+
+ if (null !== $charset && mb_detect_encoding($translation) !== $charset) {
+ $expected = mb_convert_encoding($translation, $charset, mb_detect_encoding($translation));
+ } else {
+ $expected = $translation;
+ }
+
+ $this->assertEquals($expected, $translator->trans('id', array(), 'messages', 'en'));
+ }
+
/**
* @dataProvider getTransChoiceTests
*/
@@ -199,6 +220,21 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
);
}
+ public function getLoadCatalogueTests()
+ {
+ return array(
+ array('oia', null),
+ array('oia', 'UTF-8'),
+ array('öïä', 'UTF-8'),
+ array('oia', 'ISO-8859-1'),
+ array('öïä', 'ISO-8859-1'),
+ array('цфЭ', 'UTF-8'),
+ array('цфЭ', 'KOI8-R'),
+ array('ヨラリ', 'UTF-8'),
+ array('ヨラリ', 'SJIS'),
+ );
+ }
+
public function testTransChoiceFallback()
{
$translator = new Translator('ru', new MessageSelector());