Skip to content

Commit e4a2b75

Browse files
committed
[Translation][Dumper] added XLIFF 2.0 support.
1 parent df2b383 commit e4a2b75

File tree

4 files changed

+116
-13
lines changed

4 files changed

+116
-13
lines changed

Dumper/XliffFileDumper.php

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,45 @@ class XliffFileDumper extends FileDumper
2525
*/
2626
protected function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
2727
{
28+
$xliffVersion = '1.2';
29+
if (array_key_exists('xliff_version', $options)) {
30+
$xliffVersion = $options['xliff_version'];
31+
}
32+
2833
if (array_key_exists('default_locale', $options)) {
2934
$defaultLocale = $options['default_locale'];
3035
} else {
3136
$defaultLocale = \Locale::getDefault();
3237
}
3338

39+
if ('1.2' === $xliffVersion) {
40+
return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
41+
}
42+
if ('2.0' === $xliffVersion) {
43+
return $this->dumpXliff2($defaultLocale, $messages, $domain, $options);
44+
}
45+
46+
throw new \InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
protected function format(MessageCatalogue $messages, $domain)
53+
{
54+
return $this->formatCatalogue($messages, $domain);
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
protected function getExtension()
61+
{
62+
return 'xlf';
63+
}
64+
65+
private function dumpXliff1($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
66+
{
3467
$toolInfo = array('tool-id' => 'symfony', 'tool-name' => 'Symfony');
3568
if (array_key_exists('tool_info', $options)) {
3669
$toolInfo = array_merge($toolInfo, $options['tool_info']);
@@ -103,20 +136,46 @@ protected function formatCatalogue(MessageCatalogue $messages, $domain, array $o
103136
return $dom->saveXML();
104137
}
105138

106-
/**
107-
* {@inheritdoc}
108-
*/
109-
protected function format(MessageCatalogue $messages, $domain)
139+
private function dumpXliff2($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
110140
{
111-
return $this->formatCatalogue($messages, $domain);
112-
}
141+
$dom = new \DOMDocument('1.0', 'utf-8');
142+
$dom->formatOutput = true;
113143

114-
/**
115-
* {@inheritdoc}
116-
*/
117-
protected function getExtension()
118-
{
119-
return 'xlf';
144+
$xliff = $dom->appendChild($dom->createElement('xliff'));
145+
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
146+
$xliff->setAttribute('version', '2.0');
147+
$xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
148+
$xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
149+
150+
$xliffFile = $xliff->appendChild($dom->createElement('file'));
151+
$xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
152+
153+
foreach ($messages->all($domain) as $source => $target) {
154+
$translation = $dom->createElement('unit');
155+
$translation->setAttribute('id', md5($source));
156+
157+
$segment = $translation->appendChild($dom->createElement('segment'));
158+
159+
$s = $segment->appendChild($dom->createElement('source'));
160+
$s->appendChild($dom->createTextNode($source));
161+
162+
// Does the target contain characters requiring a CDATA section?
163+
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
164+
165+
$targetElement = $dom->createElement('target');
166+
$metadata = $messages->getMetadata($source, $domain);
167+
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
168+
foreach ($metadata['target-attributes'] as $name => $value) {
169+
$targetElement->setAttribute($name, $value);
170+
}
171+
}
172+
$t = $segment->appendChild($targetElement);
173+
$t->appendChild($text);
174+
175+
$xliffFile->appendChild($translation);
176+
}
177+
178+
return $dom->saveXML();
120179
}
121180

122181
/**

Tests/Dumper/XliffFileDumperTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ public function testDump()
4545
unlink($this->tempDir.'/messages.en_US.xlf');
4646
}
4747

48+
public function testDumpXliff2()
49+
{
50+
$catalogue = new MessageCatalogue('en_US');
51+
$catalogue->add(array(
52+
'foo' => 'bar',
53+
'key' => '',
54+
'key.with.cdata' => '<source> & <target>',
55+
));
56+
$catalogue->setMetadata('key', array('target-attributes' => array('order' => 1)));
57+
58+
$dumper = new XliffFileDumper();
59+
$dumper->dump($catalogue, array('path' => $this->tempDir, 'default_locale' => 'fr_FR', 'xliff_version' => '2.0'));
60+
61+
$this->assertEquals(
62+
file_get_contents(__DIR__.'/../fixtures/resources-2.0-clean.xlf'),
63+
file_get_contents($this->tempDir.'/messages.en_US.xlf')
64+
);
65+
66+
unlink($this->tempDir.'/messages.en_US.xlf');
67+
}
68+
4869
public function testDumpWithCustomToolInfo()
4970
{
5071
$options = array(

Tests/Loader/XliffFileLoaderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
namespace Symfony\Component\Translation\Tests\Loader;
1313

14-
use Symfony\Component\Config\Resource\FileResource;
1514
use Symfony\Component\Translation\Loader\XliffFileLoader;
15+
use Symfony\Component\Config\Resource\FileResource;
1616

1717
class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
1818
{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="fr-FR" trgLang="en-US">
3+
<file id="messages.en_US">
4+
<unit id="acbd18db4cc2f85cedef654fccc4a4d8">
5+
<segment>
6+
<source>foo</source>
7+
<target>bar</target>
8+
</segment>
9+
</unit>
10+
<unit id="3c6e0b8a9c15224a8228b9a98ca1531d">
11+
<segment>
12+
<source>key</source>
13+
<target order="1"></target>
14+
</segment>
15+
</unit>
16+
<unit id="18e6a493872558d949b4c16ea1fa6ab6">
17+
<segment>
18+
<source>key.with.cdata</source>
19+
<target><![CDATA[<source> & <target>]]></target>
20+
</segment>
21+
</unit>
22+
</file>
23+
</xliff>

0 commit comments

Comments
 (0)