diff --git a/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php b/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php index 58d19733db..47e082c22e 100644 --- a/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php +++ b/src/Symfony/Component/Translation/Dumper/XliffFileDumper.php @@ -70,11 +70,17 @@ class XliffFileDumper extends FileDumper // Does the target contain characters requiring a CDATA section? $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target); - $t = $translation->appendChild($dom->createElement('target')); + $targetElement = $dom->createElement('target'); + $metadata = $messages->getMetadata($source, $domain); + if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) { + foreach ($metadata['target-attributes'] as $name => $value) { + $targetElement->setAttribute($name, $value); + } + } + $t = $translation->appendChild($targetElement); $t->appendChild($text); - $metadata = $messages->getMetadata($source, $domain); - if (null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes'])) { + if ($this->hasMetadataArrayInfo('notes', $metadata)) { foreach ($metadata['notes'] as $note) { if (!isset($note['content'])) { continue; @@ -106,4 +112,15 @@ class XliffFileDumper extends FileDumper { return 'xlf'; } + + /** + * @param string $key + * @param array|null $metadata + * + * @return bool + */ + private function hasMetadataArrayInfo($key, $metadata = null) + { + return null !== $metadata && array_key_exists($key, $metadata) && ($metadata[$key] instanceof \Traversable || is_array($metadata[$key])); + } } diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php index d2b5407f82..f2cbacb4f0 100644 --- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php +++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php @@ -59,24 +59,15 @@ class XliffFileLoader implements LoaderInterface $catalogue->set((string) $source, $target, $domain); - if (isset($translation->note)) { - $notes = array(); - foreach ($translation->note as $xmlNote) { - $noteAttributes = $xmlNote->attributes(); - $note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding)); - if (isset($noteAttributes['priority'])) { - $note['priority'] = (int) $noteAttributes['priority']; - } - - if (isset($noteAttributes['from'])) { - $note['from'] = (string) $noteAttributes['from']; - } - - $notes[] = $note; - } - - $catalogue->setMetadata((string) $source, array('notes' => $notes), $domain); + $metadata = array(); + if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) { + $metadata['notes'] = $notes; } + if ($translation->target->attributes()) { + $metadata['target-attributes'] = $translation->target->attributes(); + } + + $catalogue->setMetadata((string) $source, $metadata, $domain); } if (class_exists('Symfony\Component\Config\Resource\FileResource')) { @@ -185,4 +176,35 @@ class XliffFileLoader implements LoaderInterface return $errors; } + + /** + * @param \SimpleXMLElement|null $noteElement + * @param string|null $encoding + * + * @return array + */ + private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, $encoding = null) + { + $notes = array(); + + if (null === $noteElement) { + return $notes; + } + + foreach ($noteElement as $xmlNote) { + $noteAttributes = $xmlNote->attributes(); + $note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding)); + if (isset($noteAttributes['priority'])) { + $note['priority'] = (int) $noteAttributes['priority']; + } + + if (isset($noteAttributes['from'])) { + $note['from'] = (string) $noteAttributes['from']; + } + + $notes[] = $note; + } + + return $notes; + } } diff --git a/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php b/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php index dff2cc4c94..b1f9826c29 100644 --- a/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php +++ b/src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php @@ -38,4 +38,39 @@ class XliffFileDumperTest extends \PHPUnit_Framework_TestCase unlink($tempDir.'/messages.en_US.xlf'); } + + public function testTargetAttributesMetadataIsSetInFile() + { + $catalogue = new MessageCatalogue('en_US'); + $catalogue->add(array( + 'foo' => 'bar', + )); + $catalogue->setMetadata('foo', array('target-attributes' => array('state' => 'needs-translation'))); + + $tempDir = sys_get_temp_dir(); + $dumper = new XliffFileDumper(); + $dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR')); + + $content = << + + + + + foo + bar + + + + + +EOT; + + $this->assertEquals( + $content, + file_get_contents($tempDir.'/messages.en_US.xlf') + ); + + unlink($tempDir.'/messages.en_US.xlf'); + } } diff --git a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php index c3d65b4932..18c3aaeb25 100644 --- a/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php +++ b/src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php @@ -73,6 +73,15 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz')))), $catalogue->getMetadata('foo', 'domain1')); } + public function testTargetAttributesAreStoredCorrectly() + { + $loader = new XliffFileLoader(); + $catalogue = $loader->load(__DIR__.'/../fixtures/with-attributes.xlf', 'en', 'domain1'); + + $metadata = $catalogue->getMetadata('foo', 'domain1'); + $this->assertEquals('translated', $metadata['target-attributes']['state']); + } + /** * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException */ diff --git a/src/Symfony/Component/Translation/Tests/fixtures/with-attributes.xlf b/src/Symfony/Component/Translation/Tests/fixtures/with-attributes.xlf new file mode 100644 index 0000000000..78730629cd --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/fixtures/with-attributes.xlf @@ -0,0 +1,21 @@ + + + + + + foo + bar + + + extra + bar + + + key + + baz + qux + + + +