Completed
Pull Request — master (#359)
by
unknown
09:13
created

MultilingualString::deserialize()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 6
nop 2
1
<?php
2
3
namespace CultuurNet\UDB3\ValueObject;
4
5
use CultuurNet\UDB3\Language;
6
use CultuurNet\UDB3\Model\ValueObject\Translation\TranslatedValueObject;
7
use ValueObjects\StringLiteral\StringLiteral;
8
9
class MultilingualString
10
{
11
    /**
12
     * @var Language
13
     */
14
    private $originalLanguage;
15
16
    /**
17
     * @var StringLiteral
18
     */
19
    private $originalString;
20
21
    /**
22
     * @var StringLiteral[]
23
     *   Associative array with languages as keys and translations as values.
24
     */
25
    private $translations;
26
27
    public function __construct(Language $originalLanguage, StringLiteral $originalString)
28
    {
29
        $this->originalLanguage = $originalLanguage;
30
        $this->originalString = $originalString;
31
        $this->translations = [];
32
    }
33
34
    /**
35
     * @return Language
36
     */
37
    public function getOriginalLanguage()
38
    {
39
        return $this->originalLanguage;
40
    }
41
42
    /**
43
     * @return StringLiteral
44
     */
45
    public function getOriginalString()
46
    {
47
        return $this->originalString;
48
    }
49
50
    /**
51
     * @param Language $language
52
     * @param StringLiteral $translation
53
     * @return MultilingualString
54
     */
55
    public function withTranslation(Language $language, StringLiteral $translation)
56
    {
57
        if ($language->getCode() == $this->originalLanguage->getCode()) {
58
            throw new \InvalidArgumentException('Can not translate to original language.');
59
        }
60
61
        $c = clone $this;
62
        $c->translations[$language->getCode()] = $translation;
63
        return $c;
64
    }
65
66
    /**
67
     * @return StringLiteral[]
68
     *   Associative array with languages as keys and translations as values.
69
     */
70
    public function getTranslations()
71
    {
72
        return $this->translations;
73
    }
74
75
    /**
76
     * @return StringLiteral[]
77
     *   Associative array with languages as keys and translations as values.
78
     */
79
    public function getTranslationsIncludingOriginal()
80
    {
81
        return array_merge(
82
            [$this->originalLanguage->getCode() => $this->originalString],
83
            $this->translations
84
        );
85
    }
86
87
    /**
88
     * @param Language $preferredLanguage
89
     * @param Language[] ...$fallbackLanguages
90
     *   One or more accept languages.
91
     * @return StringLiteral|null
92
     */
93
    public function getStringForLanguage(Language $preferredLanguage, Language ...$fallbackLanguages)
94
    {
95
        $languages = $fallbackLanguages;
96
        array_unshift($languages, $preferredLanguage);
97
98
        $translations = $this->getTranslationsIncludingOriginal();
99
100
        foreach ($languages as $language) {
101
            if (isset($translations[$language->getCode()])) {
102
                return $translations[$language->getCode()];
103
            }
104
        }
105
106
        return null;
107
    }
108
109
    /**
110
     * @return array
111
     */
112
    public function serialize()
113
    {
114
        $serialized = [];
115
116
        foreach ($this->getTranslationsIncludingOriginal() as $language => $translation) {
117
            $serialized[$language] = $translation->toNative();
118
        }
119
120
        return $serialized;
121
    }
122
123
    /**
124
     * @param array $data
125
     * @param string|null $originalLanguage
126
     * @return MultilingualString
127
     */
128
    public static function deserialize(array $data, $originalLanguage = null)
129
    {
130
        $languages = array_keys($data);
131
132
        if (!$originalLanguage || !isset($data[$originalLanguage])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $originalLanguage of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
133
            $originalLanguage = reset($languages);
134
        }
135
136
        $string = new MultilingualString(new Language($originalLanguage), new StringLiteral($data[$originalLanguage]));
137
        foreach ($data as $language => $translation) {
138
            if ($language === $originalLanguage) {
139
                continue;
140
            }
141
142
            $string = $string->withTranslation(new Language($language), new StringLiteral($translation));
143
        }
144
145
        return $string;
146
    }
147
148
    /**
149
     * @param TranslatedValueObject $udb3Model
150
     * @return MultilingualString
151
     */
152
    public static function fromUdb3ModelTranslatedValueObject(TranslatedValueObject $udb3Model)
153
    {
154
        $originalLanguage = $udb3Model->getOriginalLanguage();
155
        $originalValue = $udb3Model->getTranslation($originalLanguage);
156
157
        if (!method_exists($originalValue, 'toString')) {
158
            throw new \InvalidArgumentException(
159
                'Cannot create MultilingualString from TranslatedValueObject that cannot be casted to string.'
160
            );
161
        }
162
163
        $string = new MultilingualString(
164
            Language::fromUdb3ModelLanguage($originalLanguage),
165
            new StringLiteral($originalValue->toString())
166
        );
167
168
        foreach ($udb3Model->getLanguagesWithoutOriginal() as $language) {
169
            $translation = $udb3Model->getTranslation($language);
170
171
            $string = $string->withTranslation(
172
                new Language($language->toString()),
173
                new StringLiteral($translation->toString())
174
            );
175
        }
176
177
        return $string;
178
    }
179
}
180