Completed
Push — master ( 228141...80539d )
by Mārtiņš
02:14
created

MessageStorage::translationToItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 3
dl 0
loc 18
ccs 15
cts 15
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Printful\GettextCms;
4
5
use Gettext\Translation;
6
use Gettext\Translations;
7
use Printful\GettextCms\Exceptions\InvalidTranslationException;
8
use Printful\GettextCms\Interfaces\MessageRepositoryInterface;
9
use Printful\GettextCms\Structures\MessageItem;
10
11
/**
12
 * Class handles all saving and retrieving logic of translations using the given repository
13
 */
14
class MessageStorage
15
{
16
    /** @var MessageRepositoryInterface */
17
    private $repository;
18
19 11
    public function __construct(MessageRepositoryInterface $repository)
20
    {
21 11
        $this->repository = $repository;
22 11
    }
23
24
    /**
25
     * Save translation object for a single domain and locale
26
     *
27
     * @param Translations $translations
28
     * @throws InvalidTranslationException
29
     */
30 6
    public function saveTranslations(Translations $translations)
31
    {
32 6
        $locale = $translations->getLanguage();
33 6
        $domain = (string)$translations->getDomain();
34
35 6
        if (!$locale) {
36 1
            throw new InvalidTranslationException('Locale is missing');
37
        }
38
39 5
        if (!$domain) {
40 1
            throw new InvalidTranslationException('Domain is missing');
41
        }
42
43 4
        foreach ($translations as $v) {
44 4
            $this->saveSingleTranslation($locale, $domain, $v);
45
        }
46 4
    }
47
48
    /**
49
     * Save a translation to database by merging it to a previously saved version.
50
     *
51
     * @param string $locale
52
     * @param string $domain
53
     * @param Translation $translation
54
     */
55 6
    public function saveSingleTranslation(string $locale, string $domain, Translation $translation)
56
    {
57 6
        $key = $this->getKey($locale, $domain, $translation);
58
59 6
        $existingItem = $this->repository->getSingle($key);
60
61 6
        if ($existingItem->exists()) {
62 2
            $existingTranslation = $this->itemToTranslation($existingItem);
63 2
            $existingTranslation->mergeWith($translation);
64 2
            $item = $this->translationToItem($locale, $domain, $existingTranslation);
65
66
            // Override the disabled state of the existing translation
67 2
            $item->isDisabled = $translation->isDisabled();
68
        } else {
69 6
            $item = $this->translationToItem($locale, $domain, $translation);
70
        }
71
72 6
        $item->hasOriginalTranslation = $translation->hasTranslation();
73 6
        $item->needsChecking = !$translation->hasTranslation();
74
75 6
        if ($translation->hasPlural() && !$translation->hasPluralTranslations()) {
76 2
            $item->needsChecking = true;
77
        }
78
79 6
        $this->repository->save($item);
80 6
    }
81
82
    /**
83
     * Generate a unique key for storage (basically a primary key)
84
     *
85
     * @param string $locale
86
     * @param string $domain
87
     * @param Translation $translation
88
     * @return string
89
     */
90 6
    private function getKey(string $locale, string $domain, Translation $translation): string
91
    {
92 6
        return md5($locale . '|' . $domain . '|' . $translation->getContext() . '|' . $translation->getOriginal());
93
    }
94
95
    /**
96
     * Convert a message item to a translation item
97
     *
98
     * @param MessageItem $item
99
     * @return Translation
100
     */
101 8
    private function itemToTranslation(MessageItem $item): Translation
102
    {
103 8
        $translation = new Translation($item->context, $item->original, $item->originalPlural);
104
105 8
        $translation->setTranslation($item->translation);
106 8
        $translation->setPluralTranslations($item->pluralTranslations);
107 8
        $translation->setDisabled($item->isDisabled);
108
109 8
        foreach ($item->references as $v) {
110 1
            $translation->addReference($v[0], $v[1]);
111
        }
112
113 8
        foreach ($item->comments as $v) {
114 1
            $translation->addComment($v);
115
        }
116
117 8
        foreach ($item->extractedComments as $v) {
118 1
            $translation->addExtractedComment($v);
119
        }
120
121 8
        return $translation;
122
    }
123
124
    /**
125
     * Convert a translation item to a message item
126
     *
127
     * @param string $locale
128
     * @param string $domain
129
     * @param Translation $translation
130
     * @return MessageItem
131
     */
132 6
    private function translationToItem(string $locale, string $domain, Translation $translation): MessageItem
133
    {
134 6
        $item = new MessageItem;
135
136 6
        $item->key = $this->getKey($locale, $domain, $translation);
137 6
        $item->domain = $domain;
138 6
        $item->locale = $locale;
139 6
        $item->context = (string)$translation->getContext();
140 6
        $item->original = $translation->getOriginal();
141 6
        $item->translation = $translation->getTranslation();
142 6
        $item->originalPlural = $translation->getPlural();
143 6
        $item->pluralTranslations = $translation->getPluralTranslations();
144 6
        $item->references = $translation->getReferences();
145 6
        $item->comments = $translation->getComments();
146 6
        $item->extractedComments = $translation->getExtractedComments();
147 6
        $item->isDisabled = $translation->isDisabled();
148
149 6
        return $item;
150
    }
151
152
    /**
153
     * All translations, including disabled, enabled and untranslated
154
     *
155
     * @param string $locale
156
     * @param $domain
157
     * @return Translations
158
     */
159 6
    public function getAll(string $locale, $domain): Translations
160
    {
161 6
        return $this->convertItems(
162 6
            $locale,
163 6
            (string)$domain,
164 6
            $this->repository->getAll($locale, (string)$domain)
165
        );
166
    }
167
168
    /**
169
     * All enabled translations including untranslated
170
     *
171
     * @param string $locale
172
     * @param $domain
173
     * @return Translations
174
     */
175 2
    public function getAllEnabled(string $locale, $domain): Translations
176
    {
177 2
        return $this->convertItems(
178 2
            $locale,
179 2
            (string)$domain,
180 2
            $this->repository->getEnabled($locale, (string)$domain)
181
        );
182
    }
183
184
    /**
185
     * Enabled and translated translations only
186
     *
187
     * @param string $locale
188
     * @param $domain
189
     * @return Translations
190
     */
191 2
    public function getEnabledTranslated(string $locale, $domain): Translations
192
    {
193 2
        return $this->convertItems(
194 2
            $locale,
195 2
            (string)$domain,
196 2
            $this->repository->getEnabledTranslated($locale, (string)$domain)
197
        );
198
    }
199
200
    /**
201
     * Enabled and translated translations only
202
     *
203
     * @param string $locale
204
     * @param $domain
205
     * @return Translations
206
     */
207
    public function getRequiresTranslating(string $locale, $domain): Translations
208
    {
209
        return $this->convertItems(
210
            $locale,
211
            (string)$domain,
212
            $this->repository->getRequiresTranslating($locale, (string)$domain)
213
        );
214
    }
215
216
    /**
217
     * Converts message items to a translation object
218
     *
219
     * @param string $locale
220
     * @param string|null $domain
221
     * @param MessageItem[] $items
222
     * @return Translations
223
     */
224 8
    private function convertItems(string $locale, $domain, array $items): Translations
225
    {
226 8
        $domain = (string)$domain;
227
228 8
        $translations = new Translations;
229 8
        $translations->setDomain($domain);
230 8
        $translations->setLanguage($locale);
231
232 8
        foreach ($items as $v) {
233 8
            $translation = $this->itemToTranslation($v);
234 8
            $translations[] = $translation;
235
        }
236
237 8
        return $translations;
238
    }
239
240
    /**
241
     * Mark all messages in the given domain and locale as disabled
242
     *
243
     * @param string $locale
244
     * @param string $domain
245
     */
246 2
    public function disableAll(string $locale, string $domain)
247
    {
248 2
        $this->repository->disableAll($locale, $domain);
249
    }
250
}