From e6e5146ccba6ac80f6a3823ff6ce89bb3667aa39 Mon Sep 17 00:00:00 2001 From: stealth35 Date: Mon, 12 Sep 2011 13:17:14 +0200 Subject: [PATCH] [Translation] now support ResourceBundle --- .../Resources/config/translation.xml | 1 + .../Loader/ResourceBundleLoader.php | 80 ++++++++++++++++++ .../Translation/Loader/LocalizedTestCase.php | 22 +++++ .../Loader/ResourceBundleLoaderTest.php | 61 +++++++++++++ .../fixtures/resourcebundle/dat/en.txt | 3 + .../fixtures/resourcebundle/dat/fr.txt | 3 + .../fixtures/resourcebundle/dat/resources.dat | Bin 0 -> 352 bytes .../fixtures/resourcebundle/res/en.res | Bin 0 -> 84 bytes .../fixtures/resourcebundle/res/en.txt | 3 + 9 files changed, 173 insertions(+) create mode 100644 src/Symfony/Component/Translation/Loader/ResourceBundleLoader.php create mode 100644 tests/Symfony/Tests/Component/Translation/Loader/LocalizedTestCase.php create mode 100644 tests/Symfony/Tests/Component/Translation/Loader/ResourceBundleLoaderTest.php create mode 100644 tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/en.txt create mode 100644 tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/fr.txt create mode 100644 tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/resources.dat create mode 100644 tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/res/en.res create mode 100644 tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/res/en.txt diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index f534b358bebb..95284306dd5e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -13,6 +13,7 @@ Symfony\Component\Translation\Loader\XliffFileLoader Symfony\Component\Translation\Loader\QtTranslationsLoader Symfony\Component\Translation\Loader\CsvFileLoader + Symfony\Component\Translation\Loader\ResourceBundleLoader Symfony\Component\Translation\Dumper\PhpFileDumper Symfony\Component\Translation\Dumper\XliffFileDumper Symfony\Component\Translation\Dumper\YamlFileDumper diff --git a/src/Symfony/Component/Translation/Loader/ResourceBundleLoader.php b/src/Symfony/Component/Translation/Loader/ResourceBundleLoader.php new file mode 100644 index 000000000000..b68aeb52cb11 --- /dev/null +++ b/src/Symfony/Component/Translation/Loader/ResourceBundleLoader.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Loader; + +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Config\Resource\FileResource; + +/** + * ResourceBundleLoader loads translations from a resource bundle. + * + * @author stealth35 + */ +class ResourceBundleLoader implements LoaderInterface +{ + /** + * {@inheritdoc} + */ + public function load($resource, $locale, $domain = 'messages') + { + $rb = new \ResourceBundle($locale, $resource); + + if (!$rb) { + throw new \RuntimeException("cannot load this resource : $rb"); + } elseif (intl_is_failure($rb->getErrorCode())) { + throw new \RuntimeException($rb->getErrorMessage(), $rb->getErrorCode()); + } + + $messages = $this->flatten($rb); + $catalogue = new MessageCatalogue($locale); + $catalogue->add($messages, $domain); + + if (is_dir($resource)) { + $catalogue->addResource(new DirectoryResource($resource)); + } elseif (is_file($resource.'.dat')) { + $catalogue->addResource(new FileResource($resource.'.dat')); + } + + return $catalogue; + } + + /** + * Flattens an ResourceBundle + * + * The scheme used is: + * key { key2 { key3 { "value" } } } + * Becomes: + * 'key.key2.key3' => 'value' + * + * This function takes an array by reference and will modify it + * + * @param array \ResourceBundle $rb the ResourceBundle that will be flattened + * @param array $messages used internally for recursive calls + * @param string $path current path being parsed, used internally for recursive calls + * + * @return array the flattened ResourceBundle + */ + private function flatten(\ResourceBundle $rb, array &$messages = array(), $path = null) + { + foreach ($rb as $key => $value) { + $nodePath = $path ? $path.'.'.$key : $key; + if ($value instanceof \ResourceBundle) { + $this->flatten($value, $messages, $nodePath); + } else { + $messages[$nodePath] = $value; + } + } + + return $messages; + } +} diff --git a/tests/Symfony/Tests/Component/Translation/Loader/LocalizedTestCase.php b/tests/Symfony/Tests/Component/Translation/Loader/LocalizedTestCase.php new file mode 100644 index 000000000000..3f08272d176b --- /dev/null +++ b/tests/Symfony/Tests/Component/Translation/Loader/LocalizedTestCase.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Translation\Loader; + +abstract class LocalizedTestCase extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!extension_loaded('intl')) { + $this->markTestSkipped('The "intl" extension is not available'); + } + } +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Translation/Loader/ResourceBundleLoaderTest.php b/tests/Symfony/Tests/Component/Translation/Loader/ResourceBundleLoaderTest.php new file mode 100644 index 000000000000..0d62b8a9e4ab --- /dev/null +++ b/tests/Symfony/Tests/Component/Translation/Loader/ResourceBundleLoaderTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Translation\Loader; + +use Symfony\Component\Translation\Loader\ResourceBundleLoader; +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Config\Resource\FileResource; + +class ResourceBundleFileLoaderTest extends LocalizedTestCase +{ + public function testLoad() + { + $loader = new ResourceBundleLoader(); + $resource = __DIR__.'/../fixtures/resourcebundle/res'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new DirectoryResource($resource)), $catalogue->getResources()); + } + + public function testDatEnglishLoad() + { + $loader = new ResourceBundleLoader(); + $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources'; + $catalogue = $loader->load($resource, 'en', 'domain1'); + + $this->assertEquals(array('symfony' => 'Symfony 2 is great'), $catalogue->all('domain1')); + $this->assertEquals('en', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources()); + } + + public function testDatFrenchLoad() + { + $loader = new ResourceBundleLoader(); + $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources'; + $catalogue = $loader->load($resource, 'fr', 'domain1'); + + $this->assertEquals(array('symfony' => 'Symfony 2 est génial'), $catalogue->all('domain1')); + $this->assertEquals('fr', $catalogue->getLocale()); + $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources()); + } + + /** + * @expectedException Exception + */ + public function testLoadInvalidResource() + { + $loader = new ResourceBundleLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/resourcebundle/res/en.txt', 'en', 'domain1'); + } +} diff --git a/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/en.txt b/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/en.txt new file mode 100644 index 000000000000..c04a4e8522ca --- /dev/null +++ b/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/en.txt @@ -0,0 +1,3 @@ +en{ + symfony{"Symfony 2 is great"} +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/fr.txt b/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/fr.txt new file mode 100644 index 000000000000..7e84f67ae073 --- /dev/null +++ b/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/fr.txt @@ -0,0 +1,3 @@ +fr{ + symfony{"Symfony 2 est génial"} +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/resources.dat b/tests/Symfony/Tests/Component/Translation/fixtures/resourcebundle/dat/resources.dat new file mode 100644 index 0000000000000000000000000000000000000000..b8b5b2bc5e1e988ae940ad3df98e145f1de2e154 GIT binary patch literal 352 zcmah@K?=e!5S&y&@GN@GMZ78W1)@Gc^aUcR6l?-XJ>*M$h41hO{=(T9- z-Ny;_l$`gJ3