Skip to content

Commit

Permalink
Add support for target attributes.
Browse files Browse the repository at this point in the history
The previous implementation ignored attributes in target nodes in xliff files
so they were lost when you load and then dump the same file. This change
should fix that problem.
  • Loading branch information
marcosdsanchez committed Aug 11, 2015
1 parent 64d0507 commit b913695
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 20 deletions.
23 changes: 20 additions & 3 deletions src/Symfony/Component/Translation/Dumper/XliffFileDumper.php
Expand Up @@ -70,11 +70,17 @@ protected function format(MessageCatalogue $messages, $domain)
// 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;
Expand Down Expand Up @@ -106,4 +112,15 @@ protected function getExtension()
{
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]));
}
}
56 changes: 39 additions & 17 deletions src/Symfony/Component/Translation/Loader/XliffFileLoader.php
Expand Up @@ -59,24 +59,15 @@ public function load($resource, $locale, $domain = 'messages')

$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')) {
Expand Down Expand Up @@ -185,4 +176,35 @@ private function getXmlErrors($internalErrors)

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;
}
}
Expand Up @@ -38,4 +38,39 @@ public function testDump()

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 = <<<EOT
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
<source>foo</source>
<target state="needs-translation">bar</target>
</trans-unit>
</body>
</file>
</xliff>
EOT;

$this->assertEquals(
$content,
file_get_contents($tempDir.'/messages.en_US.xlf')
);

unlink($tempDir.'/messages.en_US.xlf');
}
}
Expand Up @@ -73,6 +73,15 @@ public function testEncoding()
$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
*/
Expand Down
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="1">
<source>foo</source>
<target state="translated">bar</target>
</trans-unit>
<trans-unit id="2">
<source>extra</source>
<target state="needs-translation">bar</target>
</trans-unit>
<trans-unit id="3">
<source>key</source>
<target></target>
<note>baz</note>
<note priority="2" from="bar">qux</note>
</trans-unit>
</body>
</file>
</xliff>

0 comments on commit b913695

Please sign in to comment.