8000 merged branch Seldaek/trans_charset (PR #2339) · hackur/symfony@89fd965 · GitHub
[go: up one dir, main page]

Skip to content

Commit 89fd965

Browse files
committed
merged branch Seldaek/trans_charset (PR symfony#2339)
Commits ------- 5473d3b [Translation] Allow use of UTF-8 encoded catalogues into non-UTF-8 applications deb6dea [Translation] Add failing tests to verify that UTF-8 lang files can't be used with another charset Discussion ---------- Allow use of UTF-8 catalogues in non-UTF-8 applications This is symfony#2313 but targetting the master branch. Bug fix: yes Feature addition: ?:) Backwards compatibility break: no Symfony2 tests pass: yes Fixes the following tickets: - The problem I'm having is that, while porting an existing app, we are using UTF-8 everywhere to have a migration path ready, but the current application and DB is still in ISO-8859-1, which means translations containing accented chars are broken. Also, we didn't hit the issue yet since we don't use forms much, but I imagine we would have similar issues with core translations for the validator which are all UTF-8 encoded. Note that I explicitly suppressed this conversion in case your application is setup as UTF-8, to make sure most people are not affected by any slow down this introduces.
2 parents a4413b8 + 5473d3b commit 89fd965

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<argument type="collection">
3636
<argument key="cache_dir">%kernel.cache_dir%/translations</argument>
3737
<argument key="debug">%kernel.debug%</argument>
38+
<argument key="charset">%kernel.charset%</argument>
3839
</argument>
3940
<argument type="service" id="session" on-invalid="ignore" />
4041
</service>

src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,14 @@ class Translator extends BaseTranslator
4646
*/
4747
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array(), Session $session = null)
4848
{
49-
parent::__construct(null, $selector);
50-
5149
$this->session = $session;
5250
$this->container = $container;
5351
$this->loaderIds = $loaderIds;
5452

5553
$this->options = array(
5654
'cache_dir' => null,
5755
'debug' => false,
56+
'charset' => null,
5857
);
5958

6059
// check option names
@@ -63,6 +62,11 @@ public function __construct(ContainerInterface $container, MessageSelector $sele
6362
}
6463

6564
$this->options = array_merge($this->options, $options);
65+
66+
if ($this->options['charset'] === 'UTF-8') {
67+
$this->options['charset'] = null;
68+
}
69+
parent::__construct(null, $selector, $this->options['charset']);
6670
}
6771

6872
/**

src/Symfony/Component/Translation/Translator.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,26 @@ class Translator implements TranslatorInterface
2828
private $loaders;
2929
private $resources;
3030
private $selector;
31+
private $charset;
3132

3233
/**
3334
* Constructor.
3435
*
3536
* @param string $locale The locale
3637
* @param MessageSelector $selector The message selector for pluralization
38+
* @param string $charset Application charset
3739
*
3840
* @api
3941
*/
40-
public function __construct($locale, MessageSelector $selector)
42+
public function __construct($locale, MessageSelector $selector, $charset = null)
4143
{
4244
$this->locale = $locale;
4345
$this->selector = $selector;
4446
$this->loaders = array();
4547
$this->resources = array();
4648
$this->catalogues = array();
4749
$this->fallbackLocales = array();
50+
$this->charset = $charset;
4851
}
4952

5053
/**
@@ -173,7 +176,18 @@ private function doLoadCatalogue($locale)
173176
if (!isset($this->loaders[$resource[0]])) {
174177
throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0]));
175178
}
176-
$this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
179+
$catalogue = $this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]);
180+
if (null !== $this->charset && extension_loaded('mbstring')) {
181+
foreach ($catalogue->all() as $domain => $messages) {
182+
foreach ($messages as $key => $translation) {
183+
$srcCharset = mb_detect_encoding($translation);
184+
if ($srcCharset !== $this->charset) {
185+
$catalogue->set($key, mb_convert_encoding($translation, $this->charset, $srcCharset), $domain);
186+
}
187+
}
188+
}
189+
}
190+
$this->catalogues[$locale]->addCatalogue($catalogue);
177191
}
178192
}
179193
}

tests/Symfony/Tests/Component/Translation/TranslatorTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,27 @@ public function testFlattenedTrans($expected, $messages, $id)
132132
$this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
133133
}
134134

135+
/**
136+
* @dataProvider getLoadCatalogueTests
137+
*/
138+
public function testLoadCatalogueConvertsEncoding($translation, $charset)
139+
{
140+
if (!extension_loaded('mbstring')) {
141+
$this->markTestSkipped('This test relies on the mbstring extension');
142+
}
143+
$translator = new Translator('en', new MessageSelector(), $charset);
144+
$translator->addLoader('array', new ArrayLoader());
145+
$translator->addResource('array', array('id' => $translation), 'en', 'messages');
146+
147+
if (null !== $charset && mb_detect_encoding($translation) !== $charset) {
148+
$expected = mb_convert_encoding($translation, $charset, mb_detect_encoding($translation));
149+
} else {
150+
$expected = $translation;
151+
}
152+
153+
$this->assertEquals($expected, $translator->trans('id', array(), 'messages', 'en'));
154+
}
155+
135156
/**
136157
* @dataProvider getTransChoiceTests
137158
*/
@@ -199,6 +220,21 @@ public function getTransChoiceTests()
199220
);
200221
}
201222

223+
public function getLoadCatalogueTests()
224+
{
225+
return array(
226+
array('oia', null),
227+
array('oia', 'UTF-8'),
228+
array('öïä', 'UTF-8'),
229+
array('oia', 'ISO-8859-1'),
230+
array('öïä', 'ISO-8859-1'),
231+
array('цфЭ', 'UTF-8'),
232+
array('цфЭ', 'KOI8-R'),
233+
array('ヨラリ', 'UTF-8'),
234+
array('ヨラリ', 'SJIS'),
235+
);
236+
}
237+
202238
public function testTransChoiceFallback()
203239
{
204240
$translator = new Translator('ru', new MessageSelector());

0 commit comments

Comments
 (0)
0