4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Translation\Dumper;
14 use Symfony\Component\Translation\MessageCatalogue;
17 * XliffFileDumper generates xliff files from a message catalogue.
19 * @author Michel Salib <michelsalib@hotmail.com>
21 class XliffFileDumper extends FileDumper
26 public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
28 $xliffVersion = '1.2';
29 if (array_key_exists('xliff_version', $options)) {
30 $xliffVersion = $options['xliff_version'];
33 if (array_key_exists('default_locale', $options)) {
34 $defaultLocale = $options['default_locale'];
36 $defaultLocale = \Locale::getDefault();
39 if ('1.2' === $xliffVersion) {
40 return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
42 if ('2.0' === $xliffVersion) {
43 return $this->dumpXliff2($defaultLocale, $messages, $domain, $options);
46 throw new \InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
52 protected function format(MessageCatalogue $messages, $domain)
54 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED);
56 return $this->formatCatalogue($messages, $domain);
62 protected function getExtension()
67 private function dumpXliff1($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
69 $toolInfo = array('tool-id' => 'symfony', 'tool-name' => 'Symfony');
70 if (array_key_exists('tool_info', $options)) {
71 $toolInfo = array_merge($toolInfo, $options['tool_info']);
74 $dom = new \DOMDocument('1.0', 'utf-8');
75 $dom->formatOutput = true;
77 $xliff = $dom->appendChild($dom->createElement('xliff'));
78 $xliff->setAttribute('version', '1.2');
79 $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
81 $xliffFile = $xliff->appendChild($dom->createElement('file'));
82 $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
83 $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
84 $xliffFile->setAttribute('datatype', 'plaintext');
85 $xliffFile->setAttribute('original', 'file.ext');
87 $xliffHead = $xliffFile->appendChild($dom->createElement('header'));
88 $xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
89 foreach ($toolInfo as $id => $value) {
90 $xliffTool->setAttribute($id, $value);
93 $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
94 foreach ($messages->all($domain) as $source => $target) {
95 $translation = $dom->createElement('trans-unit');
97 $translation->setAttribute('id', md5($source));
98 $translation->setAttribute('resname', $source);
100 $s = $translation->appendChild($dom->createElement('source'));
101 $s->appendChild($dom->createTextNode($source));
103 // Does the target contain characters requiring a CDATA section?
104 $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
106 $targetElement = $dom->createElement('target');
107 $metadata = $messages->getMetadata($source, $domain);
108 if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
109 foreach ($metadata['target-attributes'] as $name => $value) {
110 $targetElement->setAttribute($name, $value);
113 $t = $translation->appendChild($targetElement);
114 $t->appendChild($text);
116 if ($this->hasMetadataArrayInfo('notes', $metadata)) {
117 foreach ($metadata['notes'] as $note) {
118 if (!isset($note['content'])) {
122 $n = $translation->appendChild($dom->createElement('note'));
123 $n->appendChild($dom->createTextNode($note['content']));
125 if (isset($note['priority'])) {
126 $n->setAttribute('priority', $note['priority']);
129 if (isset($note['from'])) {
130 $n->setAttribute('from', $note['from']);
135 $xliffBody->appendChild($translation);
138 return $dom->saveXML();
141 private function dumpXliff2($defaultLocale, MessageCatalogue $messages, $domain, array $options = array())
143 $dom = new \DOMDocument('1.0', 'utf-8');
144 $dom->formatOutput = true;
146 $xliff = $dom->appendChild($dom->createElement('xliff'));
147 $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
148 $xliff->setAttribute('version', '2.0');
149 $xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
150 $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
152 $xliffFile = $xliff->appendChild($dom->createElement('file'));
153 $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
155 foreach ($messages->all($domain) as $source => $target) {
156 $translation = $dom->createElement('unit');
157 $translation->setAttribute('id', md5($source));
159 $segment = $translation->appendChild($dom->createElement('segment'));
161 $s = $segment->appendChild($dom->createElement('source'));
162 $s->appendChild($dom->createTextNode($source));
164 // Does the target contain characters requiring a CDATA section?
165 $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
167 $targetElement = $dom->createElement('target');
168 $metadata = $messages->getMetadata($source, $domain);
169 if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
170 foreach ($metadata['target-attributes'] as $name => $value) {
171 $targetElement->setAttribute($name, $value);
174 $t = $segment->appendChild($targetElement);
175 $t->appendChild($text);
177 $xliffFile->appendChild($translation);
180 return $dom->saveXML();
185 * @param array|null $metadata
189 private function hasMetadataArrayInfo($key, $metadata = null)
191 return null !== $metadata && array_key_exists($key, $metadata) && ($metadata[$key] instanceof \Traversable || is_array($metadata[$key]));