Skip to content

Commit 7d97c1b

Browse files
Add support for target attributes.
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.
1 parent 64d0507 commit 7d97c1b

File tree

5 files changed

+127
-21
lines changed

5 files changed

+127
-21
lines changed

src/Symfony/Component/Translation/Dumper/XliffFileDumper.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,17 @@ protected function format(MessageCatalogue $messages, $domain)
7070
// Does the target contain characters requiring a CDATA section?
7171
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
7272

73-
$t = $translation->appendChild($dom->createElement('target'));
73+
$targetElement = $dom->createElement('target');
74+
$metadata = $messages->getMetadata($source, $domain);
75+
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
76+
foreach ($metadata['target-attributes'] as $name => $value) {
77+
$targetElement->setAttribute($name, $value);
78+
}
79+
}
80+
$t = $translation->appendChild($targetElement);
7481
$t->appendChild($text);
7582

76-
$metadata = $messages->getMetadata($source, $domain);
77-
if (null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes'])) {
83+
if ($this->hasMetadataArrayInfo('notes', $metadata)) {
7884
foreach ($metadata['notes'] as $note) {
7985
if (!isset($note['content'])) {
8086
continue;
@@ -92,7 +98,6 @@ protected function format(MessageCatalogue $messages, $domain)
9298
}
9399
}
94100
}
95-
96101
$xliffBody->appendChild($translation);
97102
}
98103

@@ -106,4 +111,18 @@ protected function getExtension()
106111
{
107112
return 'xlf';
108113
}
114+
115+
/**
116+
* @param string $key
117+
* @param array|null $metadata
118+
*
119+
* @return bool
120+
*/
121+
private function hasMetadataArrayInfo($key, $metadata = null)
122+
{
123+
return
124+
null !== $metadata &&
125+
array_key_exists($key, $metadata) &&
126+
($metadata[$key] instanceof \Traversable || is_array($metadata[$key]));
127+
}
109128
}

src/Symfony/Component/Translation/Loader/XliffFileLoader.php

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,15 @@ public function load($resource, $locale, $domain = 'messages')
5959

6060
$catalogue->set((string) $source, $target, $domain);
6161

62-
if (isset($translation->note)) {
63-
$notes = array();
64-
foreach ($translation->note as $xmlNote) {
65-
$noteAttributes = $xmlNote->attributes();
66-
$note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
67-
if (isset($noteAttributes['priority'])) {
68-
$note['priority'] = (int) $noteAttributes['priority'];
69-
}
70-
71-
if (isset($noteAttributes['from'])) {
72-
$note['from'] = (string) $noteAttributes['from'];
73-
}
74-
75-
$notes[] = $note;
76-
}
77-
78-
$catalogue->setMetadata((string) $source, array('notes' => $notes), $domain);
62+
$metadata = array();
63+
if ($notes = $this->setNotesMetadata($translation->note, $encoding)) {
64+
$metadata['notes'] = $notes;
7965
}
66+
if ($translation->target->attributes()) {
67+
$metadata['target-attributes'] = $translation->target->attributes();
68+
}
69+
70+
$catalogue->setMetadata((string) $source, $metadata, $domain);
8071
}
8172

8273
if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
@@ -185,4 +176,35 @@ private function getXmlErrors($internalErrors)
185176

186177
return $errors;
187178
}
179+
180+
/**
181+
* @param \SimpleXMLElement $noteElement
182+
* @param string $encoding
183+
*
184+
* @return array
185+
*/
186+
private function setNotesMetadata($noteElement = null, $encoding = null)
187+
{
188+
$notes = array();
189+
190+
if (null === $noteElement) {
191+
return $notes;
192+
}
193+
194+
foreach ($noteElement as $xmlNote) {
195+
$noteAttributes = $xmlNote->attributes();
196+
$note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
197+
if (isset($noteAttributes['priority'])) {
198+
$note['priority'] = (int) $noteAttributes['priority'];
199+
}
200+
201+
if (isset($noteAttributes['from'])) {
202+
$note['from'] = (string) $noteAttributes['from'];
203+
}
204+
205+
$notes[] = $note;
206+
}
207+
208+
return $notes;
209+
}
188210
}

src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,39 @@ public function testDump()
3838

3939
unlink($tempDir.'/messages.en_US.xlf');
4040
}
41+
42+
public function testTargetAttributesMetadataIsSetInFile()
43+
{
44+
$catalogue = new MessageCatalogue('en_US');
45+
$catalogue->add(array(
46+
'foo' => 'bar',
47+
));
48+
$catalogue->setMetadata('foo', array('target-attributes' => array('state' => 'needs-translation')));
49+
50+
$tempDir = sys_get_temp_dir();
51+
$dumper = new XliffFileDumper();
52+
$dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR'));
53+
54+
$content = <<<EOT
55+
<?xml version="1.0" encoding="utf-8"?>
56+
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
57+
<file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
58+
<body>
59+
<trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
60+
<source>foo</source>
61+
<target state="needs-translation">bar</target>
62+
</trans-unit>
63+
</body>
64+
</file>
65+
</xliff>
66+
67+
EOT;
68+
69+
$this->assertEquals(
70+
$content,
71+
file_get_contents($tempDir.'/messages.en_US.xlf')
72+
);
73+
74+
unlink($tempDir.'/messages.en_US.xlf');
75+
}
4176
}

src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ public function testEncoding()
7373
$this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz')))), $catalogue->getMetadata('foo', 'domain1'));
7474
}
7575

76+
public function testTargetAttributesAreStoredCorrectly()
77+
{
78+
$loader = new XliffFileLoader();
79+
$catalogue = $loader->load(__DIR__.'/../fixtures/with-attributes.xlf', 'en', 'domain1');
80+
81+
$metadata = $catalogue->getMetadata('foo', 'domain1');
82+
$this->assertEquals('translated', $metadata['target-attributes']['state']);
83+
}
84+
7685
/**
7786
* @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
7887
*/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
3+
<file source-language="en" datatype="plaintext" original="file.ext">
4+
<body>
5+
<trans-unit id="1">
6+
<source>foo</source>
7+
<target state="translated">bar</target>
8+
</trans-unit>
9+
<trans-unit id="2">
10+
<source>extra</source>
11+
<target state="needs-translation">bar</target>
12+
</trans-unit>
13+
<trans-unit id="3">
14+
<source>key</source>
15+
<target></target>
16+
<note>baz</note>
17+
<note priority="2" from="bar">qux</note>
18+
</trans-unit>
19+
</body>
20+
</file>
21+
</xliff>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy