Completed
Push — master ( bcebcf...1f9f52 )
by Tobias
06:16
created

StorageService::createStorages()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 0
cts 9
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 2
crap 12
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\Bundle\Service;
13
14
use Symfony\Component\Translation\MessageCatalogue;
15
use Translation\Bundle\Catalogue\CatalogueFetcher;
16
use Translation\Bundle\Catalogue\CatalogueWriter;
17
use Translation\Bundle\Model\Configuration;
18
use Translation\Common\Exception\LogicException;
19
use Translation\Common\Model\Message;
20
use Translation\Common\Storage;
21
use Translation\Common\TransferableStorage;
22
23
/**
24
 * A service that you use to handle the storages.
25
 *
26
 * @author Tobias Nyholm <[email protected]>
27
 */
28
final class StorageService implements Storage
29
{
30
    const DIRECTION_UP = 'up';
31
    const DIRECTION_DOWN = 'down';
32
33
    /**
34
     * @var Storage[]
35
     */
36
    private $localStorages = [];
37
38
    /**
39
     * @var Storage[]
40
     */
41
    private $remoteStorages = [];
42
43
    /**
44
     * @var CatalogueFetcher
45
     */
46
    private $catalogueFetcher;
47
48
    /**
49
     * @var CatalogueWriter
50
     */
51
    private $catalogueWriter;
52
53
    /**
54
     * @var Configuration
55
     */
56
    private $config;
57
58
    /**
59
     * @param CatalogueFetcher $catalogueFetcher
60
     * @param CatalogueWriter  $catalogueWriter
61
     * @param Configuration    $config
62
     */
63
    public function __construct(
64
        CatalogueFetcher $catalogueFetcher,
65
        CatalogueWriter $catalogueWriter,
66
        Configuration $config
67
    ) {
68
        $this->catalogueFetcher = $catalogueFetcher;
69
        $this->catalogueWriter = $catalogueWriter;
70
        $this->config = $config;
71
    }
72
73
    /**
74
     * Download all remote storages into all local storages.
75
     * This will overwrite your local copy.
76
     */
77
    public function download()
78
    {
79
        $catalogues = $this->doDownload();
80
81
        $this->catalogueWriter->writeCatalogues($this->config, $catalogues);
82
    }
83
84
    /**
85
     * Synchronize translations with remote.
86
     */
87
    public function sync($direction = self::DIRECTION_DOWN)
88
    {
89
        switch ($direction) {
90
            case self::DIRECTION_DOWN:
91
                $this->mergeDown();
92
                $this->mergeUp();
93
                break;
94
            case self::DIRECTION_UP:
95
                $this->mergeUp();
96
                $this->mergeDown();
97
                break;
98
            default:
99
                throw new LogicException(sprintf('Direction must be either "up" or "down". Value "%s" was provided', $direction));
100
        }
101
    }
102
103
    /**
104
     * Download and merge all translations from remote storages down to your local storages.
105
     * Only the local storages will be changed.
106
     */
107
    public function mergeDown()
108
    {
109
        $catalogues = $this->doDownload();
110
111
        foreach ($catalogues as $locale => $catalogue) {
112
            foreach ($catalogue->all() as $domain => $messages) {
113
                foreach ($messages as $key => $translation) {
114
                    $message = new Message($key, $domain, $locale, $translation);
115
                    $this->updateStorages($this->localStorages, $message);
116
                }
117
            }
118
        }
119
    }
120
121
    /**
122
     * Upload and merge all translations from local storages up to your remote storages.
123
     * Only the remote storages will be changed.
124
     *
125
     * This will overwrite your remote copy.
126
     */
127
    public function mergeUp()
128
    {
129
        $catalogues = $this->catalogueFetcher->getCatalogues($this->config);
130
        foreach ($catalogues as $catalogue) {
131
            foreach ($this->remoteStorages as $storage) {
132
                if ($storage instanceof TransferableStorage) {
133
                    $storage->import($catalogue);
134
                }
135
            }
136
        }
137
    }
138
139
    /**
140
     * Get the very latest version we know of a message. First look at the remote storage
141
     * fall back on the local ones.
142
     *
143
     * @param string $locale
144
     * @param string $domain
145
     * @param string $key
146
     *
147
     * @return null|Message
148
     */
149
    public function syncAndFetchMessage($locale, $domain, $key)
150
    {
151
        if (null === $message = $this->getFromStorages($this->remoteStorages, $locale, $domain, $key)) {
152
            // If message is not in remote storages, try local
153
            $message = $this->getFromStorages($this->localStorages, $locale, $domain, $key);
154
        }
155
156
        if (!$message) {
157
            return;
158
        }
159
160
        $this->updateStorages($this->localStorages, $message);
161
162
        return $message;
163
    }
164
165
    /**
166
     * Try to get a translation from all the storages, start looking in the first
167
     * local storage and then move on to the remote storages.
168
     * {@inheritdoc}
169
     */
170
    public function get($locale, $domain, $key)
171
    {
172
        foreach ([$this->localStorages, $this->remoteStorages] as $storages) {
173
            $value = $this->getFromStorages($storages, $locale, $domain, $key);
174
            if (!empty($value)) {
175
                return $value;
176
            }
177
        }
178
179
        return;
180
    }
181
182
    /**
183
     * @param Storage[] $storages
184
     * @param string    $locale
185
     * @param string    $domain
186
     * @param string    $key
187
     *
188
     * @return null|Message
189
     */
190
    private function getFromStorages(array $storages, $locale, $domain, $key)
191
    {
192
        foreach ($storages as $storage) {
193
            $value = $storage->get($locale, $domain, $key);
194
            if (!empty($value)) {
195
                return $value;
196
            }
197
        }
198
199
        return;
200
    }
201
202
    /**
203
     * Create all configured storages with this message. This will not overwrite
204
     * existing message.
205
     *
206
     * {@inheritdoc}
207
     */
208
    public function create(Message $message)
209
    {
210
        // Validate if message actually has data
211
        if (empty((array) $message)) {
212
            return;
213
        }
214
215
        foreach ([$this->localStorages, $this->remoteStorages] as $storages) {
216
            /** @var Storage $storage */
217
            foreach ($storages as $storage) {
218
                $storage->create($message);
219
            }
220
        }
221
    }
222
223
    /**
224
     * Update all configured storages with this message. If messages does not exist
225
     * it will be created.
226
     *
227
     * {@inheritdoc}
228
     */
229
    public function update(Message $message)
230
    {
231
        foreach ([$this->localStorages, $this->remoteStorages] as $storages) {
232
            $this->updateStorages($storages, $message);
233
        }
234
    }
235
236
    /**
237
     * @param Storage[] $storages
238
     * @param Message   $message
239
     */
240
    private function updateStorages(array $storages, Message $message)
241
    {
242
        // Validate if message actually has data
243
        if (empty((array) $message)) {
244
            return;
245
        }
246
247
        foreach ($storages as $storage) {
248
            $storage->update($message);
249
        }
250
    }
251
252
    /**
253
     * Delete the message form all storages.
254
     *
255
     * {@inheritdoc}
256
     */
257
    public function delete($locale, $domain, $key)
258
    {
259
        foreach ([$this->localStorages, $this->remoteStorages] as $storages) {
260
            /** @var Storage $storage */
261
            foreach ($storages as $storage) {
262
                $storage->delete($locale, $domain, $key);
263
            }
264
        }
265
    }
266
267
    /**
268
     * @param Storage $localStorage
269
     *
270
     * @return StorageService
271
     */
272
    public function addLocalStorage(Storage $localStorage)
273
    {
274
        $this->localStorages[] = $localStorage;
275
276
        return $this;
277
    }
278
279
    /**
280
     * @param Storage $remoteStorages
0 ignored issues
show
Documentation introduced by
There is no parameter named $remoteStorages. Did you maybe mean $remoteStorage?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
281
     *
282
     * @return StorageService
283
     */
284
    public function addRemoteStorage(Storage $remoteStorage)
285
    {
286
        $this->remoteStorages[] = $remoteStorage;
287
288
        return $this;
289
    }
290
291
    /**
292
     * Download catalogues from all storages.
293
     *
294
     * @return MessageCatalogue[]
295
     */
296
    private function doDownload()
297
    {
298
        $catalogues = [];
299
        foreach ($this->config->getLocales() as $locale) {
300
            $catalogues[$locale] = new MessageCatalogue($locale);
301
            foreach ($this->remoteStorages as $storage) {
302
                if ($storage instanceof TransferableStorage) {
303
                    $storage->export($catalogues[$locale]);
304
                }
305
            }
306
        }
307
308
        return $catalogues;
309
    }
310
}
311