Test Setup Failed
Push — master ( 8387ac...36193c )
by Avtandil
03:03
created

MultiLang::setConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
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;
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 24
    public function __construct($environment, array $config, Cache $cache, Database $db)
81
    {
82 24
        $this->environment = $environment;
83 24
        $this->cache       = $cache;
0 ignored issues
show
Bug introduced by
The property cache does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
84 24
        $this->db          = $db;
0 ignored issues
show
Bug introduced by
The property db does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
85
86 24
        $this->setConfig($config);
87
88 24
        $this->setRepository(new Repository($this->config, $cache, $db));
89 24
    }
90
91
    /**
92
     * Set multilang config
93
     *
94
     * @param array $config
95
     * @return $this
96
     */
97 24
    public function setConfig(array $config)
98
    {
99 24
        $this->config = new Config($config);
100 24
        return $this;
101
    }
102
103
    /**
104
     * Set repository object
105
     *
106
     * @param \Longman\LaravelMultiLang\Repository $repository
107
     * @return $this
108
     */
109 24
    public function setRepository(Repository $repository)
110
    {
111 24
        $this->repository = $repository;
112 24
        return $this;
113
    }
114
115
    /**
116
     * Get repository object
117
     *
118
     * @return \Longman\LaravelMultiLang\Repository
119
     */
120 2
    public function getRepository()
121
    {
122 2
        return $this->repository;
123
    }
124
125
    /**
126
     * Set application scope
127
     *
128
     * @param $scope
129
     * @return $this
130
     */
131
    public function setScope($scope)
132
    {
133
        $this->scope = $scope;
134
        return $this;
135
    }
136
137
    /**
138
     * Get application scope
139
     *
140
     * @return string
141
     */
142
    public function getScope()
143
    {
144
        return $this->scope;
145
    }
146
147
    /**
148
     * Set locale and load texts
149
     *
150
     * @param  string $lang
151
     * @param  array  $texts
152
     * @return void
153
     */
154 22
    public function setLocale($lang, array $texts = null)
155
    {
156 22
        if (!$lang) {
157 1
            throw new InvalidArgumentException('Locale is empty');
158
        }
159 21
        $this->lang = $lang;
160
161 21
        if (!is_array($texts)) {
162 18
            $texts = $this->loadTexts($this->getLocale(), $this->scope);
163
        }
164
165 21
        $this->texts = $texts;
166 21
    }
167
168
    /**
169
     * Load texts
170
     *
171
     * @param  string $lang
172
     * @param  string $scope
173
     * @return array
174
     */
175 18
    public function loadTexts($lang, $scope = null)
176
    {
177 18
        if ($this->environment != 'production' || $this->config->get('cache.enabled', true) === false) {
178 16
            $texts = $this->repository->loadFromDatabase($lang, $scope);
179 16
            return $texts;
180
        }
181
182 3
        if ($this->repository->existsInCache($lang)) {
183
            $texts = $this->repository->loadFromCache($lang, $scope);
184
        } else {
185 3
            $texts = $this->repository->loadFromDatabase($lang, $scope);
186 3
            $this->repository->storeInCache($lang, $texts, $scope);
187
        }
188
189 3
        return $texts;
190
    }
191
192
    /**
193
     * Get translated text
194
     *
195
     * @param  string $key
196
     * @param  array  $replace
197
     * @return string
198
     */
199 9
    public function get($key, array $replace = [])
200
    {
201
202 9
        if (empty($key)) {
203 1
            throw new InvalidArgumentException('String key not provided');
204
        }
205
206 8
        if (!$this->lang) {
207 1
            return $key;
208
        }
209
210 7
        if (!isset($this->texts[$key])) {
211 4
            $this->queueToSave($key);
212 4
            return $this->replaceMarkers($key, $replace);
213
        }
214
215 3
        $text = $this->texts[$key];
216
217 3
        return $this->replaceMarkers($text, $replace);
218
    }
219
220
    /**
221
     * Replace markers in text
222
     *
223
     * @param  string $text
224
     * @param  array  $replace
225
     * @return string
226
     */
227 7
    protected function replaceMarkers($text, array $replace = [])
228
    {
229 7
        if (empty($replace)) {
230 6
            return $text;
231
        }
232
233 1
        return $this->makeReplacements($text, $replace);
234
    }
235
236
    /**
237
     * Make the place-holder replacements on a line.
238
     *
239
     * @param  string $text
240
     * @param  array  $replace
241
     * @return string
242
     */
243 1
    protected function makeReplacements($text, array $replace)
244
    {
245 1
        $replace = $this->sortReplacements($replace);
246
247 1
        foreach ($replace as $key => $value) {
248 1
            $text = str_replace(
249 1
                [':' . $key, ':' . Str::upper($key), ':' . Str::ucfirst($key)],
250 1
                [$value, Str::upper($value), Str::ucfirst($value)],
251 1
                $text
252
            );
253
        }
254
255 1
        return $text;
256
    }
257
258
    /**
259
     * Sort the replacements array.
260
     *
261
     * @param  array $replace
262
     * @return \Illuminate\Support\Collection
263
     */
264
    protected function sortReplacements(array $replace)
265
    {
266 1
        return (new Collection($replace))->sortBy(function ($value, $key) {
267 1
            return mb_strlen($key) * -1;
268 1
        });
269
    }
270
271
    /**
272
     * Get redirect url in middleware
273
     *
274
     * @param \Illuminate\Http\Request $request
275
     * @return null|string
276
     */
277 4
    public function getRedirectUrl(Request $request)
278
    {
279 4
        $locale           = $request->segment(1);
280 4
        $fallback_locale  = $this->config->get('default_locale', 'en');
281 4
        $exclude_segments = $this->config->get('exclude_segments', []);
282 4
        if (in_array($locale, $exclude_segments)) {
283
            return null;
284
        }
285
286 4
        if (strlen($locale) == 2) {
287 3
            $locales = $this->config->get('locales', []);
288
289 3
            if (!isset($locales[$locale])) {
290 2
                $segments    = $request->segments();
291 2
                $segments[0] = $fallback_locale;
292 2
                $url         = implode('/', $segments);
293 2
                if ($query_string = $request->server->get('QUERY_STRING')) {
294 1
                    $url .= '?' . $query_string;
295
                }
296
297 3
                return $url;
298
            }
299
        } else {
300 1
            $segments = $request->segments();
301 1
            $url      = $fallback_locale . '/' . implode('/', $segments);
302 1
            if ($query_string = $request->server->get('QUERY_STRING')) {
303
                $url .= '?' . $query_string;
304
            }
305 1
            return $url;
306
        }
307
308 1
        return null;
309
    }
310
311
    /**
312
     * Detect locale based on url segment
313
     *
314
     * @param \Illuminate\Http\Request $request
315
     * @return string
316
     */
317 1
    public function detectLocale(Request $request)
318
    {
319 1
        $locale  = $request->segment(1);
320 1
        $locales = $this->config->get('locales');
321
322 1
        if (isset($locales[$locale])) {
323 1
            return isset($locales[$locale]['locale']) ? $locales[$locale]['locale'] : $locale;
324
        }
325
326
        return $this->config->get('default_locale', 'en');
327
    }
328
329
    /**
330
     * Wrap routes to available languages group
331
     *
332
     * @param \Closure $callback
333
     */
334
    public function routeGroup(Closure $callback)
335
    {
336
        $router = app('router');
337
338
        $locales = $this->config->get('locales', []);
339
340
        foreach ($locales as $locale => $val) {
341
            $router->group([
342
                               'prefix' => $locale,
343
                               'as'     => $locale . '.',
344
                           ], $callback);
345
        }
346
    }
347
348
    /**
349
     *  Manage texts
350
     */
351
    public function manageTextsRoutes()
352
    {
353
        $router     = app('router');
354
        $route      = $this->config->get('text-route.route', 'texts');
355
        $controller = $this->config->get(
356
            'text-route.controller',
357
            '\Longman\LaravelMultiLang\Controllers\TextsController'
358
        );
359
360
        $router->get(
361
            $route,
362
            ['uses' => $controller . '@index']
363
        );
364
        $router->post(
365
            $route,
366
            ['uses' => $controller . '@save']
367
        );
368
    }
369
370
    /**
371
     * Get texts
372
     *
373
     * @return array
374
     */
375 4
    public function getTexts()
376
    {
377
378 4
        return $this->texts;
379
    }
380
381
    /**
382
     * Get all texts
383
     *
384
     * @param string $lang
385
     * @param string $scope
386
     * @return array
387
     */
388
    public function getAllTexts($lang = null, $scope = null)
389
    {
390
        return $this->repository->loadAllFromDatabase($lang, $scope);
391
    }
392
393
    /**
394
     * Set texts manually
395
     *
396
     * @param  array $texts_array
397
     * @return \Longman\LaravelMultiLang\MultiLang
398
     */
399 4
    public function setTexts(array $texts_array)
400
    {
401 4
        $texts = [];
402 4
        foreach ($texts_array as $key => $value) {
403 4
            $texts[$key] = $value;
404
        }
405
406 4
        $this->texts = $texts;
407
408 4
        return $this;
409
    }
410
411
    /**
412
     * Queue missing texts
413
     *
414
     * @param  string $key
415
     * @return void
416
     */
417 4
    protected function queueToSave($key)
418
    {
419 4
        $this->new_texts[$key] = $key;
420 4
    }
421
422
    /**
423
     * Get language prefixed url
424
     *
425
     * @param $path
426
     * @return string
427
     */
428 2
    public function getUrl($path)
429
    {
430 2
        $locale = $this->getLocale();
431 2
        if ($locale) {
432 2
            $path = $locale . '/' . $path;
433
        }
434 2
        return $path;
435
    }
436
437
    /**
438
     * Check if autosave allowed
439
     *
440
     * @return bool
441
     */
442 4
    public function autoSaveIsAllowed()
443
    {
444 4
        if ($this->environment == 'local' && $this->config->get('db.autosave', true)) {
445 1
            return true;
446
        }
447 4
        return false;
448
    }
449
450
    /**
451
     * Get locale
452
     *
453
     * @return string
454
     */
455 19
    public function getLocale()
456
    {
457 19
        return $this->lang;
458
    }
459
460
    /**
461
     * Get available locales
462
     *
463
     * @return array
464
     */
465 1
    public function getLocales()
466
    {
467 1
        return $this->config->get('locales');
468
    }
469
470
    /**
471
     * Save missing texts
472
     *
473
     * @return bool
474
     */
475 3
    public function saveTexts()
476
    {
477 3
        if (empty($this->new_texts)) {
478 3
            return false;
479
        }
480
481 3
        $this->repository->save($this->new_texts, $this->scope);
482 3
        return true;
483
    }
484
}
485