Passed
Push — master ( 6b8e14...f27647 )
by Avtandil
03:15
created

MultiLang::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
ccs 2
cts 2
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the Laravel MultiLang package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\LaravelMultiLang;
12
13
use Closure;
14
use Illuminate\Cache\CacheManager as Cache;
15
use Illuminate\Database\DatabaseManager as Database;
16
use Illuminate\Http\Request;
17
use Illuminate\Support\Collection;
18
use Illuminate\Support\Str;
19
use InvalidArgumentException;
20
21
class MultiLang
22
{
23
    /**
24
     * Language/Locale.
25
     *
26
     * @var string
27
     */
28
    protected $lang;
29
30
    /**
31
     * System environment
32
     *
33
     * @var string
34
     */
35
    protected $environment;
36
37
    /**
38
     * Config.
39
     *
40
     * @var \Longman\LaravelMultiLang\Config
41
     */
42
    protected $config;
43
44
    /**
45
     * Repository
46
     *
47
     * @var \Longman\LaravelMultiLang\Repository
48
     */
49
    protected $repository;
50
51
    /**
52
     * Texts.
53
     *
54
     * @var array
55
     */
56
    protected $texts;
57
58
    /**
59
     * Missing texts.
60
     *
61
     * @var array
62
     */
63
    protected $new_texts;
64
65
    /**
66
     * Application scope.
67
     *
68
     * @var string
69
     */
70
    protected $scope = 'global';
71
72
    /**
73
     * Create a new MultiLang instance.
74
     *
75
     * @param string $environment
76
     * @param array $config
77
     * @param \Illuminate\Cache\CacheManager $cache
78
     * @param \Illuminate\Database\DatabaseManager $db
79
     */
80 33
    public function __construct($environment, array $config, Cache $cache, Database $db)
81
    {
82 33
        $this->environment = $environment;
83
84 33
        $this->setConfig($config);
85
86 33
        $this->setRepository(new Repository($this->config, $cache, $db));
87 33
    }
88
89
    /**
90
     * Set multilang config
91
     *
92
     * @param array $config
93
     * @return $this
94
     */
95 33
    public function setConfig(array $config)
96
    {
97 33
        $this->config = new Config($config);
98
99 33
        return $this;
100
    }
101
102
    /**
103
     * Get multilang config
104
     *
105
     * @return \Longman\LaravelMultiLang\Config
106
     */
107 1
    public function getConfig(): Config
108
    {
109
110 1
        return $this->config;
111
    }
112
113
    /**
114
     * Set repository object
115
     *
116
     * @param \Longman\LaravelMultiLang\Repository $repository
117
     * @return $this
118
     */
119 33
    public function setRepository(Repository $repository)
120
    {
121 33
        $this->repository = $repository;
122
123 33
        return $this;
124
    }
125
126
    /**
127
     * Get repository object
128
     *
129
     * @return \Longman\LaravelMultiLang\Repository
130
     */
131 3
    public function getRepository()
132
    {
133 3
        return $this->repository;
134
    }
135
136
    /**
137
     * Set application scope
138
     *
139
     * @param $scope
140
     * @return $this
141
     */
142 1
    public function setScope($scope)
143
    {
144 1
        $this->scope = $scope;
145
146 1
        return $this;
147
    }
148
149
    /**
150
     * Get application scope
151
     *
152
     * @return string
153
     */
154 1
    public function getScope()
155
    {
156 1
        return $this->scope;
157
    }
158
159
    /**
160
     * Set locale and load texts
161
     *
162
     * @param  string $lang
163
     * @param  array $texts
164
     * @return void
165
     */
166 27
    public function setLocale($lang, array $texts = null)
167
    {
168 27
        if (! $lang) {
169 1
            throw new InvalidArgumentException('Locale is empty');
170
        }
171 26
        $this->lang = $lang;
172
173 26
        if (! is_array($texts)) {
174 23
            $texts = $this->loadTexts($this->getLocale(), $this->scope);
175
        }
176
177 26
        $this->texts = $texts;
178 26
    }
179
180
    /**
181
     * Load texts
182
     *
183
     * @param  string $lang
184
     * @param  string $scope
185
     * @return array
186
     */
187 23
    public function loadTexts($lang, $scope = null)
188
    {
189 23
        if ($this->environment != 'production' || $this->config->get('cache.enabled', true) === false) {
190 20
            $texts = $this->repository->loadFromDatabase($lang, $scope);
191
192 20
            return $texts;
193
        }
194
195 4
        if ($this->repository->existsInCache($lang, $scope)) {
196 1
            $texts = $this->repository->loadFromCache($lang, $scope);
197
        } else {
198 4
            $texts = $this->repository->loadFromDatabase($lang, $scope);
199 4
            $this->repository->storeInCache($lang, $texts, $scope);
200
        }
201
202 4
        return $texts;
203
    }
204
205
    /**
206
     * Get translated text
207
     *
208
     * @param  string $key
209
     * @param  array $replace
210
     * @return string
211
     */
212 9
    public function get($key, array $replace = [])
213
    {
214
215 9
        if (empty($key)) {
216 1
            throw new InvalidArgumentException('String key not provided');
217
        }
218
219 8
        if (! $this->lang) {
220 1
            return $key;
221
        }
222
223 7
        if (! isset($this->texts[$key])) {
224 4
            $this->queueToSave($key);
225
226 4
            return $this->replaceMarkers($key, $replace);
227
        }
228
229 3
        $text = $this->texts[$key];
230
231 3
        return $this->replaceMarkers($text, $replace);
232
    }
233
234
    /**
235
     * Replace markers in text
236
     *
237
     * @param  string $text
238
     * @param  array $replace
239
     * @return string
240
     */
241 7
    protected function replaceMarkers($text, array $replace = [])
242
    {
243 7
        if (empty($replace)) {
244 6
            return $text;
245
        }
246
247 1
        return $this->makeReplacements($text, $replace);
248
    }
249
250
    /**
251
     * Make the place-holder replacements on a line.
252
     *
253
     * @param  string $text
254
     * @param  array $replace
255
     * @return string
256
     */
257 1
    protected function makeReplacements($text, array $replace)
258
    {
259 1
        $replace = $this->sortReplacements($replace);
260
261 1
        foreach ($replace as $key => $value) {
262 1
            $text = str_replace(
263 1
                [':' . $key, ':' . Str::upper($key), ':' . Str::ucfirst($key)],
264 1
                [$value, Str::upper($value), Str::ucfirst($value)],
265 1
                $text
266
            );
267
        }
268
269 1
        return $text;
270
    }
271
272
    /**
273
     * Sort the replacements array.
274
     *
275
     * @param  array $replace
276
     * @return \Illuminate\Support\Collection
277
     */
278
    protected function sortReplacements(array $replace)
279
    {
280 1
        return (new Collection($replace))->sortBy(function ($value, $key) {
281 1
            return mb_strlen($key) * -1;
282 1
        });
283
    }
284
285
    /**
286
     * Get redirect url in middleware
287
     *
288
     * @param \Illuminate\Http\Request $request
289
     * @return null|string
290
     */
291 5
    public function getRedirectUrl(Request $request)
292
    {
293 5
        $locale = $request->segment(1);
294 5
        $fallback_locale = $this->config->get('default_locale', 'en');
295 5
        $exclude_segments = $this->config->get('exclude_segments', []);
296 5
        if (in_array($locale, $exclude_segments)) {
297
            return null;
298
        }
299
300 5
        if (strlen($locale) == 2) {
301 4
            $locales = $this->config->get('locales', []);
302
303 4
            if (! isset($locales[$locale])) {
304 3
                $segments = $request->segments();
305 3
                $segments[0] = $fallback_locale;
306 3
                $url = implode('/', $segments);
307 3
                if ($query_string = $request->server->get('QUERY_STRING')) {
308 1
                    $url .= '?' . $query_string;
309
                }
310
311 4
                return $url;
312
            }
313
        } else {
314 1
            $segments = $request->segments();
315 1
            $url = $fallback_locale . '/' . implode('/', $segments);
316 1
            if ($query_string = $request->server->get('QUERY_STRING')) {
317
                $url .= '?' . $query_string;
318
            }
319
320 1
            return $url;
321
        }
322
323 1
        return null;
324
    }
325
326
    /**
327
     * Detect locale based on url segment
328
     *
329
     * @param \Illuminate\Http\Request $request
330
     * @return string
331
     */
332 2
    public function detectLocale(Request $request)
333
    {
334 2
        $locale = $request->segment(1);
335 2
        $locales = $this->config->get('locales');
336
337 2
        if (isset($locales[$locale])) {
338 1
            return isset($locales[$locale]['locale']) ? $locales[$locale]['locale'] : $locale;
339
        }
340
341 1
        return $this->config->get('default_locale', 'en');
342
    }
343
344
    /**
345
     * Wrap routes to available languages group
346
     *
347
     * @param \Closure $callback
348
     */
349
    public function routeGroup(Closure $callback)
350
    {
351
        $router = app('router');
352
353
        $locales = $this->config->get('locales', []);
354
355
        foreach ($locales as $locale => $val) {
356
            $router->group([
357
                'prefix' => $locale,
358
                'as'     => $locale . '.',
359
            ], $callback);
360
        }
361
    }
362
363
    /**
364
     *  Manage texts
365
     */
366
    public function manageTextsRoutes()
367
    {
368
        $router = app('router');
369
        $route = $this->config->get('text-route.route', 'texts');
370
        $controller = $this->config->get(
371
            'text-route.controller',
372
            '\Longman\LaravelMultiLang\Controllers\TextsController'
373
        );
374
375
        $router->get(
376
            $route,
377
            ['uses' => $controller . '@index']
378
        );
379
        $router->post(
380
            $route,
381
            ['uses' => $controller . '@save']
382
        );
383
    }
384
385
    /**
386
     * Get texts
387
     *
388
     * @return array
389
     */
390 4
    public function getTexts()
391
    {
392
393 4
        return $this->texts;
394
    }
395
396
    /**
397
     * Get all texts
398
     *
399
     * @param string $lang
400
     * @param string $scope
401
     * @return array
402
     */
403 1
    public function getAllTexts($lang = null, $scope = null)
404
    {
405 1
        return $this->repository->loadAllFromDatabase($lang, $scope);
406
    }
407
408
    /**
409
     * Set texts manually
410
     *
411
     * @param  array $texts_array
412
     * @return \Longman\LaravelMultiLang\MultiLang
413
     */
414 4
    public function setTexts(array $texts_array)
415
    {
416 4
        $texts = [];
417 4
        foreach ($texts_array as $key => $value) {
418 4
            $texts[$key] = $value;
419
        }
420
421 4
        $this->texts = $texts;
422
423 4
        return $this;
424
    }
425
426
    /**
427
     * Queue missing texts
428
     *
429
     * @param  string $key
430
     * @return void
431
     */
432 4
    protected function queueToSave($key)
433
    {
434 4
        $this->new_texts[$key] = $key;
435 4
    }
436
437
    /**
438
     * Get language prefixed url
439
     *
440
     * @param string $path
441
     * @param string $lang
442
     * @return string
443
     */
444 4
    public function getUrl($path, $lang = null)
445
    {
446 4
        $locale = $lang ? $lang : $this->getLocale();
447 4
        if ($locale) {
448 4
            $path = $locale . '/' . $this->removeLocaleFromPath($path);
449
        }
450
451 4
        return $path;
452
    }
453
454
    /**
455
     * Remove locale from the path
456
     *
457
     * @param string $path
458
     * @return string
459
     */
460 4
    private function removeLocaleFromPath($path)
461
    {
462 4
        $locales = $this->config->get('locales');
463 4
        $locale = mb_substr($path, 0, 2);
464 4
        if (isset($locales[$locale])) {
465 1
            return mb_substr($path, 3);
466
        }
467
468 4
        return $path;
469
    }
470
471
    /**
472
     * Get language prefixed route
473
     *
474
     * @param string $name
475
     * @return string
476
     */
477 2
    public function getRoute($name)
478
    {
479 2
        $locale = $this->getLocale();
480 2
        if ($locale) {
481 1
            $name = $locale . '.' . $name;
482
        }
483
484 2
        return $name;
485
    }
486
487
    /**
488
     * Check if autosave allowed
489
     *
490
     * @return bool
491
     */
492 7
    public function autoSaveIsAllowed()
493
    {
494 7
        if ($this->environment == 'local' && $this->config->get('db.autosave', true)) {
495 1
            return true;
496
        }
497
498 7
        return false;
499
    }
500
501
    /**
502
     * Get locale
503
     *
504
     * @return string
505
     */
506 25
    public function getLocale()
507
    {
508 25
        return $this->lang;
509
    }
510
511
    /**
512
     * Get available locales
513
     *
514
     * @return array
515
     */
516 1
    public function getLocales()
517
    {
518 1
        return $this->config->get('locales');
519
    }
520
521
    /**
522
     * Save missing texts
523
     *
524
     * @return bool
525
     */
526 3
    public function saveTexts()
527
    {
528 3
        if (empty($this->new_texts)) {
529 3
            return false;
530
        }
531
532 3
        $this->repository->save($this->new_texts, $this->scope);
533
534 3
        return true;
535
    }
536
}
537