Completed
Push — master ( b9a4a6...f14b09 )
by ARCANEDEV
13s queued 11s
created

TransPublisher::publishJson()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6.4222

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 8
cts 13
cp 0.6153
rs 9.2728
c 0
b 0
f 0
cc 5
nc 3
nop 3
crap 6.4222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arcanedev\LaravelLang;
6
7
use Arcanedev\LaravelLang\Contracts\TransPublisher as TransPublisherContract;
8
use Arcanedev\LaravelLang\Contracts\TransManager as TransManagerContract;
9
use Arcanedev\LaravelLang\Exceptions\LangPublishException;
10
use Illuminate\Filesystem\Filesystem;
11
use Illuminate\Support\Str;
12
use SplFileInfo;
13
14
/**
15
 * Class     TransPublisher
16
 *
17
 * @author   ARCANEDEV <[email protected]>
18
 */
19
class TransPublisher implements TransPublisherContract
20
{
21
    /* -----------------------------------------------------------------
22
     |  Properties
23
     | -----------------------------------------------------------------
24
     */
25
26
    /**
27
     * The filesystem instance.
28
     *
29
     * @var \Illuminate\Filesystem\Filesystem
30
     */
31
    private $filesystem;
32
33
    /**
34
     * The TransManager instance.
35
     *
36
     * @var \Arcanedev\LaravelLang\Contracts\TransManager
37
     */
38
    private $manager;
39
40
    /**
41
     * Available locales.
42
     *
43
     * @var \Arcanedev\LaravelLang\Entities\LocaleCollection
44
     */
45
    private $locales;
46
47
    /**
48
     * The application lang path.
49
     *
50
     * @var string
51
     */
52
    private $langPath;
53
54
    /**
55
     * Publish's results.
56
     *
57
     * @var array
58
     */
59
    private $results = [];
60
61
    /* -----------------------------------------------------------------
62
     |  Constructor
63
     | -----------------------------------------------------------------
64
     */
65
66
    /**
67
     * Make TransPublisher instance.
68
     *
69
     * @param  \Illuminate\Filesystem\Filesystem              $filesystem
70
     * @param  \Arcanedev\LaravelLang\Contracts\TransManager  $manager
71
     * @param  string                                         $langPath
72
     */
73 56
    public function __construct(Filesystem $filesystem, TransManagerContract $manager, string $langPath)
74
    {
75 56
        $this->filesystem = $filesystem;
76 56
        $this->manager    = $manager;
77 56
        $this->langPath   = realpath($langPath);
78
79 56
        $this->init();
80 56
    }
81
82
    /**
83
     * Start the engine.
84
     */
85 56
    private function init(): void
86
    {
87 56
        $this->locales = $this->manager->getCollection('vendor-php');
88 56
    }
89
90
    /* -----------------------------------------------------------------
91
     |  Getters & Setters
92
     | -----------------------------------------------------------------
93
     */
94
95
    /**
96
     * Get the locale destination path.
97
     *
98
     * @param  string  $locale
99
     *
100
     * @return string
101
     */
102 32
    private function getDestinationPath(string $locale): string
103
    {
104 32
        return $this->langPath.DIRECTORY_SEPARATOR.$locale;
105
    }
106
107
    /**
108
     * Get a locale from the collection.
109
     *
110
     * @param  string  $key
111
     * @param  mixed   $default
112
     *
113
     * @return \Arcanedev\LaravelLang\Entities\Locale|mixed
114
     */
115 32
    private function getLocale(string $key, $default = null)
116
    {
117 32
        return $this->locales->get($key, $default);
118
    }
119
120
    /* -----------------------------------------------------------------
121
     |  Main Methods
122
     | -----------------------------------------------------------------
123
     */
124
125
    /**
126
     * Publish a lang.
127
     *
128
     * @param  string  $locale
129
     * @param  array   $options
130
     *
131
     * @return array
132
     */
133 40
    public function publish(string $locale, array $options = []): array
134
    {
135 40
        $this->resetResults();
136
137 40
        $locale = trim($locale);
138
139 40
        if ($this->isDefault($locale)) {
140 4
            $this->results['skipped'][] = $locale;
141
142 4
            return $this->results;
143
        }
144
145 36
        $this->checkLocale($locale);
146
147 32
        $source      = $this->getLocale($locale)->getPath();
148 32
        $destination = $this->getDestinationPath($locale);
149
150 32
        $this->filesystem->ensureDirectoryExists($destination);
151
152
        // Publish the PHP Translations
153 32
        foreach ($this->filesystem->files($source) as $file) {
154 32
            $this->publishFile($file, $locale, $destination, $options);
155
        }
156
157
        // Publish the JSON Translation
158 32
        if ($options['json'] ?? false) {
159 4
            $this->publishJson($locale, $destination);
160
        }
161
162 32
        return $this->results;
163
    }
164
165
    /**
166
     * Publish the json file.
167
     *
168
     * @param  string  $locale
169
     * @param  string  $destination
170
     * @param  array   $options
171
     *
172
     * @return bool
173
     */
174 4
    private function publishJson(string $locale, string $destination, array $options = []): bool
175
    {
176 4
        $file = $this->manager->getCollection('vendor-json')->get($locale);
177
178 4
        if (is_null($file)) {
179
            $this->results['skipped'][] = "{$locale}.json";
180
            return false;
181
        }
182
183 4
        if ($this->filesystem->exists($destFile = $destination.'.json') && ($options['force'] ?? false) === false) {
184
            $this->results['skipped'][] = "{$locale}.json";
185
            return false;
186
        }
187
188 4
        return tap($this->filesystem->copy($file->getPath(), $destFile), function (bool $published) use ($locale) {
189 4
            if ($published)
190 4
                $this->results['published'][] = "{$locale}.json";
191
            else
192
                $this->results['skipped'][] = "{$locale}.json";
193 4
        });
194
    }
195
196
    /* -----------------------------------------------------------------
197
     |  Check Methods
198
     | -----------------------------------------------------------------
199
     */
200
201
    /**
202
     * Check if the locale is a default one (English is shipped with laravel).
203
     *
204
     * @param  string  $locale
205
     *
206
     * @return bool
207
     */
208 44
    public function isDefault(string $locale): bool
209
    {
210 44
        return $locale === 'en';
211
    }
212
213
    /**
214
     * Check if the locale is supported.
215
     *
216
     * @param  string  $key
217
     *
218
     * @return bool
219
     */
220 36
    public function isSupported(string $key): bool
221
    {
222 36
        return $this->locales->has($key);
223
    }
224
225
    /**
226
     * Check if the locale is supported or fail.
227
     *
228
     * @param  string  $locale
229
     *
230
     * @throws \Arcanedev\LaravelLang\Exceptions\LangPublishException
231
     */
232 36
    private function checkLocale(string $locale): void
233
    {
234 36
        if ( ! $this->isSupported($locale)) {
235 4
            throw new LangPublishException("The locale [$locale] is not supported.");
236
        }
237 32
    }
238
239
    /* -----------------------------------------------------------------
240
     |  Other Methods
241
     | -----------------------------------------------------------------
242
     */
243
244
    /**
245
     * Publish the translation file.
246
     *
247
     * @param  SplFileInfo  $file
248
     * @param  string       $locale
249
     * @param  string       $destination
250
     * @param  array        $options
251
     */
252 32
    private function publishFile(SplFileInfo $file, string $locale, string $destination, array $options): void
253
    {
254 32
        $isInlineFile = Str::endsWith($file->getFilename(), '-inline.php');
255 32
        $destFile = $isInlineFile
256 32
            ? Str::replaceLast('-inline.php', '.php', $file->getFilename())
257 32
            : $file->getFilename();
258
259 32
        if ($this->isInResults($key = "{$locale}/{$destFile}"))
260 4
            return;
261
262
        // Ignore if inline option is not enabled
263 32
        if ($isInlineFile && (($options['inline'] ?? false) === false))
264 28
            return;
265
266
        // Ignore if force option is not enabled
267 32
        if ($this->filesystem->exists($destination.DIRECTORY_SEPARATOR.$destFile) && ($options['force'] ?? false) === false) {
268 8
            $this->results['skipped'][] = $key;
269 8
            return;
270
        }
271
272 32
        $this->filesystem->copy($file->getRealPath(), $destination.DIRECTORY_SEPARATOR.$destFile);
273 32
        $this->results['published'][] = $key;
274 32
    }
275
276
    /**
277
     * Reset the publish results.
278
     */
279 40
    private function resetResults(): void
280
    {
281 40
        $this->results = [
282
            'published' => [],
283
            'skipped'   => [],
284
        ];
285 40
    }
286
287
    /**
288
     * Check if the given key exists in results.
289
     *
290
     * @param  string  $key
291
     *
292
     * @return bool
293
     */
294 32
    private function isInResults(string $key): bool
295
    {
296 32
        return in_array($key, $this->results['published'])
297 32
            || in_array($key, $this->results['skipped']);
298
    }
299
}
300