8000 [Translation] now support ResourceBundle · sdboyer/symfony@e6e5146 · GitHub
[go: up one dir, main page]

Skip to content

Commit e6e5146

Browse files
committed
[Translation] now support ResourceBundle
1 parent b99bb1e commit e6e5146

File tree

9 files changed

+173
-0
lines changed

9 files changed

+173
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<parameter key="translation.loader.xliff.class">Symfony\Component\Translation\Loader\XliffFileLoader</parameter>
1414
<parameter key="translation.loader.qt.class">Symfony\Component\Translation\Loader\QtTranslationsLoader</parameter>
1515
<parameter key="translation.loader.csv.class">Symfony\Component\Translation\Loader\CsvFileLoader</parameter>
16+
<parameter key="translation.loader.rb.class">Symfony\Component\Translation\Loader\ResourceBundleLoader</parameter>
1617
<parameter key="translation.dumper.php.class">Symfony\Component\Translation\Dumper\PhpFileDumper</parameter>
1718
<parameter key="translation.dumper.xliff.class">Symfony\Component\Translation\Dumper\XliffFileDumper</parameter>
1819
<parameter key="translation.dumper.yml.class">Symfony\Component\Translation\Dumper\YamlFileDumper</parameter>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Loader;
13+
14+
use Symfony\Component\Translation\MessageCatalogue;
15+
use Symfony\Component\Config\Resource\DirectoryResource;
16+
use Symfony\Component\Config\Resource\FileResource;
17+
18+
/**
19+
* ResourceBundleLoader loads translations from a resource bundle.
20+
*
21+
* @author stealth35
22+
*/
23+
class ResourceBundleLoader implements LoaderInterface
24+
{
25+
/**
26+
* {@inheritdoc}
27+
*/
28+
public function load($resource, $locale, $domain = 'messages')
29+
{
30+
$rb = new \ResourceBundle($locale, $resource);
31+
32+
if (!$rb) {
33+
throw new \RuntimeException("cannot load this resource : $rb");
34+
} elseif (intl_is_failure($rb->getErrorCode())) {
35+
throw new \RuntimeException($rb->getErrorMessage(), $rb->getErrorCode());
36+
}
37+
38+
$messages = $this->flatten($rb);
39+
$catalogue = new MessageCatalogue($locale);
40+
$catalogue->add($messages, $domain);
41+
42+
if (is_dir($resource)) {
43+
$catalogue->addResource(new DirectoryResource($resource));
44+
} elseif (is_file($resource.'.dat')) {
45+
$catalogue->addResource(new FileResource($resource.'.dat'));
46+
}
47+
48+
return $catalogue;
49+
}
50+
51+
/**
52+
* Flattens an ResourceBundle
53+
*
54+
* The scheme used is:
55+
* key { key2 { key3 { "value" } } }
56+
* Becomes:
57+
* 'key.key2.key3' => 'value'
58+
*
59+
* This function takes an array by reference and will modify it
60+
*
61+
* @param array \ResourceBundle $rb the ResourceBundle that will be flattened
62+
* @param array $messages used internally for recursive calls
63+
* @param string $path current path being parsed, used internally for recursive calls
64+
*
65+
* @return array the flattened ResourceBundle
66+
*/
67+
private function flatten(\ResourceBundle $rb, array &$messages = array(), $path = null)
68+
{
69+
foreach ($rb as $key => $value) {
70+
$nodePath = $path ? $path.'.'.$key : $key;
71+
if ($value instanceof \ResourceBundle) {
72+
$this->flatten($value, $messages, $nodePath);
73+
} else {
74+
$messages[$nodePath] = $value;
75+
}
76+
}
77+
78+
return $messages;
79+
}
80+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Tests\Component\Translation\Loader;
13+
14+
abstract class LocalizedTestCase extends \PHPUnit_Framework_TestCase
15+
{
16+
protected function setUp()
17+
{
18+
if (!extension_loaded('intl')) {
19+
$this->markTestSkipped('The "intl" extension is not available');
20+
}
21+
}
22+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Tests\Component\Translation\Loader;
13+
14+
use Symfony\Component\Translation\Loader\ResourceBundleLoader;
15+
use Symfony\Component\Config\Resource\DirectoryResource;
16+
use 10000 Symfony\Component\Config\Resource\FileResource;
17+
18+
class ResourceBundleFileLoaderTest extends LocalizedTestCase
19+
{
20+
public function testLoad()
21+
{
22+
$loader = new ResourceBundleLoader();
23+
$resource = __DIR__.'/../fixtures/resourcebundle/res';
24+
$catalogue = $loader->load($resource, 'en', 'domain1');
25+
26+
$this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
27+
$this->assertEquals('en', $catalogue->getLocale());
28+
$this->assertEquals(array(new DirectoryResource($resource)), $catalogue->getResources());
29+
}
30+
31+
public function testDatEnglishLoad()
32+
{
33+
$loader = new ResourceBundleLoader();
34+
$resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
35+
$catalogue = $loader->load($resource, 'en', 'domain1');
36+
37+
$this->assertEquals(array('symfony' => 'Symfony 2 is great'), $catalogue->all('domain1'));
38+
$this->assertEquals('en', $catalogue->getLocale());
39+
$this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
40+
}
41+
42+
public function testDatFrenchLoad()
43+
{
44+
$loader = new ResourceBundleLoader();
45+
$resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
46+
$catalogue = $loader->load($resource, 'fr', 'domain1');
47+
48+
$this->assertEquals(array('symfony' => 'Symfony 2 est génial'), $catalogue->all('domain1'));
49+
$this->assertEquals('fr', $catalogue->getLocale());
50+
$this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
51+
}
52+
53+
/**
54+
* @expectedException Exception
55+
*/
56+
public function testLoadInvalidResource()
57+
{
58+
$loader = new ResourceBundleLoader();
59+
$catalogue = $loader->load(__DIR__.'/../fixtures/resourcebundle/res/en.txt', 'en', 'domain1');
60+
}
61+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
en{
2+
symfony{"Symfony 2 is great"}
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fr{
2+
symfony{"Symfony 2 est génial"}
3+
}
Binary file not shown.
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
en {
2+
foo { "bar" }
3+
}

0 commit comments

Comments
 (0)
0