Completed
Push — master ( 83b029...ea7456 )
by ARCANEDEV
14s queued 12s
created

TransPublisher::publishJson()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 6.8088

Importance

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