Completed
Push — master ( a09b4a...382e94 )
by Tobias
08:18
created

SymfonyPort::extractXliff2()   D

Complexity

Conditions 9
Paths 5

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 9.1582

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 21
cts 24
cp 0.875
rs 4.909
c 0
b 0
f 0
cc 9
eloc 23
nc 5
nop 3
crap 9.1582
1
<?php
2
3
/*
4
 * This file is part of the PHP Translation package.
5
 *
6
 * (c) PHP Translation team <[email protected]>
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 Translation\SymfonyStorage\Loader\Port;
13
14
use Symfony\Component\Translation\MessageCatalogue;
15
use Symfony\Component\Translation\Exception\InvalidArgumentException;
16
17
/**
18
 * This code is moved from the Symfony 3.4 repo. It will be removed when
19
 * we drop support for Symfony 3.3 and below.
20
 *
21
 * @author Tobias Nyholm <[email protected]>
22
 */
23
class SymfonyPort
24
{
25
    /**
26
     * @param \DOMDocument     $dom
27
     * @param MessageCatalogue $catalogue
28
     * @param string           $domain
29
     */
30 3
    public function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, $domain)
31
    {
32 3
        $xml = simplexml_import_dom($dom);
33 3
        $encoding = strtoupper($dom->encoding);
34
35 3
        $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');
36
37 3
        foreach ($xml->xpath('//xliff:unit') as $unit) {
38 3
            $segment = $unit->segment;
39 3
            $source = $segment->source;
40
41
            // If the xlf file has another encoding specified, try to convert it because
42
            // simple_xml will always return utf-8 encoded values
43 3
            $target = $this->utf8ToCharset((string) (isset($segment->target) ? $segment->target : $source), $encoding);
44
45 3
            $catalogue->set((string) $source, $target, $domain);
46
47 3
            $metadata = [];
48 3
            if (isset($segment->target) && $segment->target->attributes()) {
49
                $metadata['target-attributes'] = [];
50
                foreach ($segment->target->attributes() as $key => $value) {
51
                    $metadata['target-attributes'][$key] = (string) $value;
52
                }
53
            }
54
55 3
            if (isset($unit->notes)) {
56 2
                $metadata['notes'] = [];
57 2
                foreach ($unit->notes->note as $noteNode) {
58 2
                    $note = [];
59 2
                    foreach ($noteNode->attributes() as $key => $value) {
60 2
                        $note[$key] = (string) $value;
61
                    }
62 2
                    $note['content'] = (string) $noteNode;
63 2
                    $metadata['notes'][] = $note;
64
                }
65
            }
66
67 3
            $catalogue->setMetadata((string) $source, $metadata, $domain);
68
        }
69 3
    }
70
71
    /**
72
     * Convert a UTF8 string to the specified encoding.
73
     *
74
     * @param string $content  String to decode
75
     * @param string $encoding Target encoding
76
     *
77
     * @return string
78
     */
79 3
    private function utf8ToCharset($content, $encoding = null)
80
    {
81 3
        if ('UTF-8' !== $encoding && !empty($encoding)) {
82
            return mb_convert_encoding($content, $encoding, 'UTF-8');
83
        }
84
85 3
        return $content;
86
    }
87
88
    /**
89
     * Gets xliff file version based on the root "version" attribute.
90
     * Defaults to 1.2 for backwards compatibility.
91
     *
92
     * @param \DOMDocument $dom
93
     *
94
     * @throws InvalidArgumentException
95
     *
96
     * @return string
97
     *
98
     * @deprecated Will be removed when we drop support for SF2.7
99
     */
100
    public function getVersionNumber(\DOMDocument $dom)
101
    {
102
        /** @var \DOMNode $xliff */
103
        foreach ($dom->getElementsByTagName('xliff') as $xliff) {
104
            $version = $xliff->attributes->getNamedItem('version');
105
            if ($version) {
106
                return $version->nodeValue;
107
            }
108
109
            $namespace = $xliff->attributes->getNamedItem('xmlns');
110
            if ($namespace) {
111
                if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) {
112
                    throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace));
113
                }
114
115
                return substr($namespace, 34);
116
            }
117
        }
118
119
        // Falls back to v1.2
120
        return '1.2';
121
    }
122
123
    /**
124
     * Extract messages and metadata from DOMDocument into a MessageCatalogue.
125
     *
126
     * @param \DOMDocument     $dom       Source to extract messages and metadata
127
     * @param MessageCatalogue $catalogue Catalogue where we'll collect messages and metadata
128
     * @param string           $domain    The domain
129
     *
130
     * @deprecated Will be removed when we drop support for SF2.7
131
     */
132
    public function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, $domain)
133
    {
134
        $xml = simplexml_import_dom($dom);
135
        $encoding = strtoupper($dom->encoding);
136
137
        $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
138
        foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
139
            $attributes = $translation->attributes();
140
141
            if (!(isset($attributes['resname']) || isset($translation->source))) {
142
                continue;
143
            }
144
145
            $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
146
            // If the xlf file has another encoding specified, try to convert it because
147
            // simple_xml will always return utf-8 encoded values
148
            $target = $this->utf8ToCharset((string) (isset($translation->target) ? $translation->target : $source), $encoding);
149
150
            $catalogue->set((string) $source, $target, $domain);
151
152
            $metadata = [];
153
            if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) {
0 ignored issues
show
Deprecated Code introduced by
The method Translation\SymfonyStora...t::parseNotesMetadata() has been deprecated with message: Will be removed when we drop support for SF2.7

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
154
                $metadata['notes'] = $notes;
155
            }
156
157
            if (isset($translation->target) && $translation->target->attributes()) {
158
                $metadata['target-attributes'] = [];
159
                foreach ($translation->target->attributes() as $key => $value) {
160
                    $metadata['target-attributes'][$key] = (string) $value;
161
                }
162
            }
163
164
            if (isset($attributes['id'])) {
165
                $metadata['id'] = (string) $attributes['id'];
166
            }
167
168
            $catalogue->setMetadata((string) $source, $metadata, $domain);
169
        }
170
    }
171
172
    /**
173
     * @param \SimpleXMLElement|null $noteElement
174
     * @param string|null            $encoding
175
     *
176
     * @return array
177
     *
178
     * @deprecated Will be removed when we drop support for SF2.7
179
     */
180
    private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, $encoding = null)
181
    {
182
        $notes = [];
183
184
        if (null === $noteElement) {
185
            return $notes;
186
        }
187
188
        /** @var \SimpleXMLElement $xmlNote */
189
        foreach ($noteElement as $xmlNote) {
190
            $noteAttributes = $xmlNote->attributes();
191
            $note = ['content' => $this->utf8ToCharset((string) $xmlNote, $encoding)];
192
            if (isset($noteAttributes['priority'])) {
193
                $note['priority'] = (int) $noteAttributes['priority'];
194
            }
195
196
            if (isset($noteAttributes['from'])) {
197
                $note['from'] = (string) $noteAttributes['from'];
198
            }
199
200
            $notes[] = $note;
201
        }
202
203
        return $notes;
204
    }
205
}
206