From 4073319d0f6757c98a53b70a3fe85bd8a9eef591 Mon Sep 17 00:00:00 2001 From: Pablo Borowicz Date: Thu, 8 Nov 2018 18:05:28 -0300 Subject: [PATCH] Load original file metadata when loading Xliff 1.2 files --- .../Component/Translation/CHANGELOG.md | 5 ++ .../Translation/Loader/XliffFileLoader.php | 62 +++++++++------- .../Tests/Loader/XliffFileLoaderTest.php | 73 ++++++++++++++++++- .../Tests/fixtures/resources-multi-files.xlf | 27 +++++++ 4 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 src/Symfony/Component/Translation/Tests/fixtures/resources-multi-files.xlf diff --git a/src/Symfony/Component/Translation/CHANGELOG.md b/src/Symfony/Component/Translation/CHANGELOG.md index 87eb2fa4a3..42ae7789fa 100644 --- a/src/Symfony/Component/Translation/CHANGELOG.md +++ b/src/Symfony/Component/Translation/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +4.3.0 +----- + + * Improved Xliff 1.2 loader to load the original file's metadata + 4.2.0 ----- diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index 1106ec65f0..33599400c5 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -82,38 +82,50 @@ class XliffFileLoader implements LoaderInterface $xml = simplexml_import_dom($dom); $encoding = strtoupper($dom->encoding); - $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2'); - foreach ($xml->xpath('//xliff:trans-unit') as $translation) { - $attributes = $translation->attributes(); + $namespace = 'urn:oasis:names:tc:xliff:document:1.2'; + $xml->registerXPathNamespace('xliff', $namespace); - if (!(isset($attributes['resname']) || isset($translation->source))) { - continue; - } + foreach ($xml->xpath('//xliff:file') as $file) { + $fileAttributes = $file->attributes(); - $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source; - // If the xlf file has another encoding specified, try to convert it because - // simple_xml will always return utf-8 encoded values - $target = $this->utf8ToCharset((string) (isset($translation->target) ? $translation->target : $translation->source), $encoding); + $file->registerXPathNamespace('xliff', $namespace); - $catalogue->set((string) $source, $target, $domain); + foreach ($file->xpath('.//xliff:trans-unit') as $translation) { + $attributes = $translation->attributes(); - $metadata = array(); - if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) { - $metadata['notes'] = $notes; - } - - if (isset($translation->target) && $translation->target->attributes()) { - $metadata['target-attributes'] = array(); - foreach ($translation->target->attributes() as $key => $value) { - $metadata['target-attributes'][$key] = (string) $value; + if (!(isset($attributes['resname']) || isset($translation->source))) { + continue; } - } - if (isset($attributes['id'])) { - $metadata['id'] = (string) $attributes['id']; - } + $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source; + // If the xlf file has another encoding specified, try to convert it because + // simple_xml will always return utf-8 encoded values + $target = $this->utf8ToCharset((string) ($translation->target ?? $translation->source), $encoding); - $catalogue->setMetadata((string) $source, $metadata, $domain); + $catalogue->set((string) $source, $target, $domain); + + $metadata = array( + 'file' => array( + 'original' => (string) $fileAttributes['original'], + ), + ); + if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) { + $metadata['notes'] = $notes; + } + + if (isset($translation->target) && $translation->target->attributes()) { + $metadata['target-attributes'] = array(); + foreach ($translation->target->attributes() as $key => $value) { + $metadata['target-attributes'][$key] = (string) $value; + } + } + + if (isset($attributes['id'])) { + $metadata['id'] = (string) $attributes['id']; + } + + $catalogue->setMetadata((string) $source, $metadata, $domain); + } } } diff --git a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php index c6958486c1..cf21c8227f 100644 --- a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php +++ b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php @@ -84,7 +84,16 @@ class XliffFileLoaderTest extends TestCase $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1')); $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1')); - $this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz'))), 'id' => '1'), $catalogue->getMetadata('foo', 'domain1')); + $this->assertEquals( + array( + 'notes' => array(array('content' => utf8_decode('bäz'))), + 'id' => '1', + 'file' => array( + 'original' => 'file.ext', + ), + ), + $catalogue->getMetadata('foo', 'domain1') + ); } public function testTargetAttributesAreStoredCorrectly() @@ -164,11 +173,41 @@ class XliffFileLoaderTest extends TestCase $loader = new XliffFileLoader(); $catalogue = $loader->load(__DIR__.'/../fixtures/withnote.xlf', 'en', 'domain1'); - $this->assertEquals(array('notes' => array(array('priority' => 1, 'content' => 'foo')), 'id' => '1'), $catalogue->getMetadata('foo', 'domain1')); + $this->assertEquals( + array( + 'notes' => array(array('priority' => 1, 'content' => 'foo')), + 'id' => '1', + 'file' => array( + 'original' => 'file.ext', + ), + ), + $catalogue->getMetadata('foo', 'domain1') + ); // message without target - $this->assertEquals(array('notes' => array(array('content' => 'bar', 'from' => 'foo')), 'id' => '2'), $catalogue->getMetadata('extra', 'domain1')); + $this->assertEquals( + array( + 'notes' => array(array('content' => 'bar', 'from' => 'foo')), + 'id' => '2', + 'file' => array( + 'original' => 'file.ext', + ), + ), + $catalogue->getMetadata('extra', 'domain1') + ); // message with empty target - $this->assertEquals(array('notes' => array(array('content' => 'baz'), array('priority' => 2, 'from' => 'bar', 'content' => 'qux')), 'id' => '123'), $catalogue->getMetadata('key', 'domain1')); + $this->assertEquals( + array( + 'notes' => array( + array('content' => 'baz'), + array('priority' => 2, 'from' => 'bar', 'content' => 'qux'), + ), + 'id' => '123', + 'file' => array( + 'original' => 'file.ext', + ), + ), + $catalogue->getMetadata('key', 'domain1') + ); } public function testLoadVersion2() @@ -257,4 +296,30 @@ class XliffFileLoaderTest extends TestCase $this->assertSame('processed', $metadata['notes'][0]['category']); $this->assertSame('true', $metadata['notes'][0]['content']); } + + public function testLoadWithMultipleFileNodes() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/resources-multi-files.xlf', 'en', 'domain1'); + + $this->assertEquals( + array( + 'id' => '1', + 'file' => array( + 'original' => 'file.ext', + ), + ), + $catalogue->getMetadata('foo', 'domain1') + ); + $this->assertEquals( + array( + 'notes' => array(array('content' => 'note')), + 'id' => '4', + 'file' => array( + 'original' => 'otherfile.ext', + ), + ), + $catalogue->getMetadata('test', 'domain1') + ); + } } diff --git a/src/Symfony/Component/Translation/Tests/fixtures/resources-multi-files.xlf b/src/Symfony/Component/Translation/Tests/fixtures/resources-multi-files.xlf new file mode 100644 index 0000000000..5f451508bc --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/fixtures/resources-multi-files.xlf @@ -0,0 +1,27 @@ + + + + + + foo + bar + + + + + + + extra + + + key + + + + test + with + note + + + +