Completed
Push — master ( 70c6ff...a20241 )
by Oscar
12s queued 10s
created

Xliff::getUnitID()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Gettext\Generators;
4
5
use Gettext\Translation;
6
use Gettext\Translations;
7
use DOMDocument;
8
9
class Xliff extends Generator implements GeneratorInterface
10
{
11
    const UNIT_ID_REGEXP = '/^XLIFF_UNIT_ID: (.*)$/';
12
13
    /**
14
     * {@inheritdoc}
15
     */
16
    public static function toString(Translations $translations, array $options = [])
17
    {
18
        $dom = new DOMDocument('1.0', 'utf-8');
19
        $dom->formatOutput = true;
20
        $xliff = $dom->appendChild($dom->createElement('xliff'));
21
        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
22
        $xliff->setAttribute('version', '2.0');
23
        $xliff->setAttribute('srcLang', $translations->getLanguage());
24
        $xliff->setAttribute('trgLang', $translations->getLanguage());
25
        $file = $xliff->appendChild($dom->createElement('file'));
26
        $file->setAttribute('id', $translations->getDomain().'.'.$translations->getLanguage());
27
28
        //Save headers as notes
29
        $notes = $dom->createElement('notes');
30
31
        foreach ($translations->getHeaders() as $name => $value) {
32
            $notes->appendChild(self::createTextNode($dom, 'note', $value))->setAttribute('id', $name);
33
        }
34
35
        if ($notes->hasChildNodes()) {
36
            $file->appendChild($notes);
37
        }
38
39
        foreach ($translations as $translation) {
40
            //Find an XLIFF unit ID, if one is available; otherwise generate
41
            $unitId = self::getUnitID($translation)?:md5($translation->getContext().$translation->getOriginal());
42
43
            $unit = $dom->createElement('unit');
44
            $unit->setAttribute('id', $unitId);
45
46
            //Save comments as notes
47
            $notes = $dom->createElement('notes');
48
49
            $notes->appendChild(self::createTextNode($dom, 'note', $translation->getContext()))
50
                ->setAttribute('category', 'context');
51
52
            foreach ($translation->getComments() as $comment) {
53
                //Skip XLIFF unit ID comments.
54
                if (preg_match(self::UNIT_ID_REGEXP, $comment)) {
55
                    continue;
56
                }
57
58
                $notes->appendChild(self::createTextNode($dom, 'note', $comment))
59
                    ->setAttribute('category', 'comment');
60
            }
61
62
            foreach ($translation->getExtractedComments() as $comment) {
63
                $notes->appendChild(self::createTextNode($dom, 'note', $comment))
64
                    ->setAttribute('category', 'extracted-comment');
65
            }
66
67
            foreach ($translation->getFlags() as $flag) {
68
                $notes->appendChild(self::createTextNode($dom, 'note', $flag))
69
                    ->setAttribute('category', 'flag');
70
            }
71
72
            foreach ($translation->getReferences() as $reference) {
73
                $notes->appendChild(self::createTextNode($dom, 'note', $reference[0].':'.$reference[1]))
74
                    ->setAttribute('category', 'reference');
75
            }
76
77
            $unit->appendChild($notes);
78
79
            $segment = $unit->appendChild($dom->createElement('segment'));
80
            $segment->appendChild(self::createTextNode($dom, 'source', $translation->getOriginal()));
81
            $segment->appendChild(self::createTextNode($dom, 'target', $translation->getTranslation()));
82
83
            foreach ($translation->getPluralTranslations() as $plural) {
84
                if ($plural !== '') {
85
                    $segment->appendChild(self::createTextNode($dom, 'target', $plural));
86
                }
87
            }
88
89
            $file->appendChild($unit);
90
        }
91
92
        return $dom->saveXML();
93
    }
94
95
    private static function createTextNode(DOMDocument $dom, $name, $string)
96
    {
97
        $node = $dom->createElement($name);
98
        $text = (preg_match('/[&<>]/', $string) === 1)
99
             ? $dom->createCDATASection($string)
100
             : $dom->createTextNode($string);
101
        $node->appendChild($text);
102
103
        return $node;
104
    }
105
106
    /**
107
     * Gets the translation's unit ID, if one is available.
108
     *
109
     * @param Translation $translation
110
     *
111
     * @return string|null
112
     */
113
    public static function getUnitID(Translation $translation)
114
    {
115
        foreach ($translation->getComments() as $comment) {
116
            if (preg_match(self::UNIT_ID_REGEXP, $comment, $matches)) {
117
                return $matches[1];
118
            }
119
        }
120
        return null;
121
    }
122
}
123