Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\Translation\Dumper;
13
 
14
use Symfony\Component\Translation\Exception\InvalidArgumentException;
15
use Symfony\Component\Translation\MessageCatalogue;
16
 
17
/**
18
 * XliffFileDumper generates xliff files from a message catalogue.
19
 *
20
 * @author Michel Salib <michelsalib@hotmail.com>
21
 */
22
class XliffFileDumper extends FileDumper
23
{
24
    public function __construct(
25
        private string $extension = 'xlf',
26
    ) {
27
    }
28
 
29
    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string
30
    {
31
        $xliffVersion = '1.2';
32
        if (\array_key_exists('xliff_version', $options)) {
33
            $xliffVersion = $options['xliff_version'];
34
        }
35
 
36
        if (\array_key_exists('default_locale', $options)) {
37
            $defaultLocale = $options['default_locale'];
38
        } else {
39
            $defaultLocale = \Locale::getDefault();
40
        }
41
 
42
        if ('1.2' === $xliffVersion) {
43
            return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
44
        }
45
        if ('2.0' === $xliffVersion) {
46
            return $this->dumpXliff2($defaultLocale, $messages, $domain);
47
        }
48
 
49
        throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
50
    }
51
 
52
    protected function getExtension(): string
53
    {
54
        return $this->extension;
55
    }
56
 
57
    private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?string $domain, array $options = [])
58
    {
59
        $toolInfo = ['tool-id' => 'symfony', 'tool-name' => 'Symfony'];
60
        if (\array_key_exists('tool_info', $options)) {
61
            $toolInfo = array_merge($toolInfo, $options['tool_info']);
62
        }
63
 
64
        $dom = new \DOMDocument('1.0', 'utf-8');
65
        $dom->formatOutput = true;
66
 
67
        $xliff = $dom->appendChild($dom->createElement('xliff'));
68
        $xliff->setAttribute('version', '1.2');
69
        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
70
 
71
        $xliffFile = $xliff->appendChild($dom->createElement('file'));
72
        $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
73
        $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
74
        $xliffFile->setAttribute('datatype', 'plaintext');
75
        $xliffFile->setAttribute('original', 'file.ext');
76
 
77
        $xliffHead = $xliffFile->appendChild($dom->createElement('header'));
78
        $xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
79
        foreach ($toolInfo as $id => $value) {
80
            $xliffTool->setAttribute($id, $value);
81
        }
82
 
83
        if ($catalogueMetadata = $messages->getCatalogueMetadata('', $domain) ?? []) {
84
            $xliffPropGroup = $xliffHead->appendChild($dom->createElement('prop-group'));
85
            foreach ($catalogueMetadata as $key => $value) {
86
                $xliffProp = $xliffPropGroup->appendChild($dom->createElement('prop'));
87
                $xliffProp->setAttribute('prop-type', $key);
88
                $xliffProp->appendChild($dom->createTextNode($value));
89
            }
90
        }
91
 
92
        $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
93
        foreach ($messages->all($domain) as $source => $target) {
94
            $translation = $dom->createElement('trans-unit');
95
 
96
            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
97
            $translation->setAttribute('resname', $source);
98
 
99
            $s = $translation->appendChild($dom->createElement('source'));
100
            $s->appendChild($dom->createTextNode($source));
101
 
102
            // Does the target contain characters requiring a CDATA section?
103
            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
104
 
105
            $targetElement = $dom->createElement('target');
106
            $metadata = $messages->getMetadata($source, $domain);
107
            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
108
                foreach ($metadata['target-attributes'] as $name => $value) {
109
                    $targetElement->setAttribute($name, $value);
110
                }
111
            }
112
            $t = $translation->appendChild($targetElement);
113
            $t->appendChild($text);
114
 
115
            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
116
                foreach ($metadata['notes'] as $note) {
117
                    if (!isset($note['content'])) {
118
                        continue;
119
                    }
120
 
121
                    $n = $translation->appendChild($dom->createElement('note'));
122
                    $n->appendChild($dom->createTextNode($note['content']));
123
 
124
                    if (isset($note['priority'])) {
125
                        $n->setAttribute('priority', $note['priority']);
126
                    }
127
 
128
                    if (isset($note['from'])) {
129
                        $n->setAttribute('from', $note['from']);
130
                    }
131
                }
132
            }
133
 
134
            $xliffBody->appendChild($translation);
135
        }
136
 
137
        return $dom->saveXML();
138
    }
139
 
140
    private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?string $domain)
141
    {
142
        $dom = new \DOMDocument('1.0', 'utf-8');
143
        $dom->formatOutput = true;
144
 
145
        $xliff = $dom->appendChild($dom->createElement('xliff'));
146
        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
147
        $xliff->setAttribute('version', '2.0');
148
        $xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
149
        $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
150
 
151
        $xliffFile = $xliff->appendChild($dom->createElement('file'));
152
        if (str_ends_with($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
153
            $xliffFile->setAttribute('id', substr($domain, 0, -\strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)).'.'.$messages->getLocale());
154
        } else {
155
            $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
156
        }
157
 
158
        if ($catalogueMetadata = $messages->getCatalogueMetadata('', $domain) ?? []) {
159
            $xliff->setAttribute('xmlns:m', 'urn:oasis:names:tc:xliff:metadata:2.0');
160
            $xliffMetadata = $xliffFile->appendChild($dom->createElement('m:metadata'));
161
            foreach ($catalogueMetadata as $key => $value) {
162
                $xliffMeta = $xliffMetadata->appendChild($dom->createElement('prop'));
163
                $xliffMeta->setAttribute('type', $key);
164
                $xliffMeta->appendChild($dom->createTextNode($value));
165
            }
166
        }
167
 
168
        foreach ($messages->all($domain) as $source => $target) {
169
            $translation = $dom->createElement('unit');
170
            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
171
 
172
            if (\strlen($source) <= 80) {
173
                $translation->setAttribute('name', $source);
174
            }
175
 
176
            $metadata = $messages->getMetadata($source, $domain);
177
 
178
            // Add notes section
179
            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
180
                $notesElement = $dom->createElement('notes');
181
                foreach ($metadata['notes'] as $note) {
182
                    $n = $dom->createElement('note');
183
                    $n->appendChild($dom->createTextNode($note['content'] ?? ''));
184
                    unset($note['content']);
185
 
186
                    foreach ($note as $name => $value) {
187
                        $n->setAttribute($name, $value);
188
                    }
189
                    $notesElement->appendChild($n);
190
                }
191
                $translation->appendChild($notesElement);
192
            }
193
 
194
            $segment = $translation->appendChild($dom->createElement('segment'));
195
 
196
            $s = $segment->appendChild($dom->createElement('source'));
197
            $s->appendChild($dom->createTextNode($source));
198
 
199
            // Does the target contain characters requiring a CDATA section?
200
            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
201
 
202
            $targetElement = $dom->createElement('target');
203
            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
204
                foreach ($metadata['target-attributes'] as $name => $value) {
205
                    $targetElement->setAttribute($name, $value);
206
                }
207
            }
208
            $t = $segment->appendChild($targetElement);
209
            $t->appendChild($text);
210
 
211
            $xliffFile->appendChild($translation);
212
        }
213
 
214
        return $dom->saveXML();
215
    }
216
 
217
    private function hasMetadataArrayInfo(string $key, array $metadata = null): bool
218
    {
219
        return is_iterable($metadata[$key] ?? null);
220
    }
221
}