Completed
Push — master ( 2b1500...ed3a76 )
by Avtandil
02:41
created

MultiLang::detectLocale()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.3332

Importance

Changes 2
Bugs 2 Features 0
Metric Value
c 2
b 2
f 0
dl 0
loc 14
ccs 6
cts 9
cp 0.6667
rs 9.4285
cc 3
eloc 9
nc 3
nop 1
crap 3.3332
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 Illuminate\Cache\CacheManager as Cache;
14
use Illuminate\Database\DatabaseManager as Database;
15
use Illuminate\Http\Request;
16
use Illuminate\Support\Collection;
17
use InvalidArgumentException;
18
19
class MultiLang
20
{
21
    /**
22
     * Language/Locale.
23
     *
24
     * @var string
25
     */
26
    protected $lang;
27
28
    /**
29
     * System environment
30
     *
31
     * @var string
32
     */
33
    protected $environment;
34
35
    /**
36
     * The instance of the cache.
37
     *
38
     * @var \Illuminate\Cache\CacheManager
39
     */
40
    protected $cache;
41
42
    /**
43
     * Config.
44
     *
45
     * @var array
46
     */
47
    protected $config;
48
49
    /**
50
     * The instance of the database.
51
     *
52
     * @var \Illuminate\Database\DatabaseManager
53
     */
54
    protected $db;
55
56
    /**
57
     * Name of the cache.
58
     *
59
     * @var string
60
     */
61
    protected $cache_name;
62
63
    /**
64
     * Texts collection.
65
     *
66
     * @var \Illuminate\Support\Collection
67
     */
68
    protected $texts;
69
70
    /**
71
     * Missing texts.
72
     *
73
     * @var array
74
     */
75
    protected $new_texts;
76
77
    /**
78
     * Create a new MultiLang instance.
79
     *
80
     * @param string                               $environment
81
     * @param array                                $config
82
     * @param \Illuminate\Cache\CacheManager       $cache
83
     * @param \Illuminate\Database\DatabaseManager $db
84
     */
85 25
    public function __construct($environment, array $config, Cache $cache, Database $db)
86
    {
87 25
        $this->environment = $environment;
88 25
        $this->cache       = $cache;
89 25
        $this->db          = $db;
90
91 25
        $this->setConfig($config);
92 25
    }
93
94 25
    public function setConfig(array $config)
95
    {
96 25
        $this->config = $this->getDefaultConfig();
97
98 25
        foreach ($config as $k => $v) {
99 5
            $this->config[$k] = $v;
100 25
        }
101 25
    }
102
103 25
    public function getDefaultConfig()
104
    {
105
        $config = [
106
            'locales'        => [
107
                'en' => [
108 25
                    'name'        => 'English',
109 25
                    'native_name' => 'English',
110 25
                    'flag'        => 'gb.svg',
111 25
                    'locale'      => 'en',
112 25
                ],
113 25
            ],
114 25
            'default_locale' => 'en',
115 25
            'autosave'       => true,
116 25
            'cache'          => true,
117 25
            'cache_lifetime' => 1440,
118 25
            'texts_table'    => 'texts',
119 25
        ];
120 25
        return $config;
121
    }
122
123 22
    public function getConfig($key = null)
124
    {
125 22
        if ($key === null) {
126 1
            return $this->config;
127
        }
128
129 22
        return isset($this->config[$key]) ? $this->config[$key] : null;
130
    }
131
132
    /**
133
     * Set locale and load texts
134
     *
135
     * @param  string $lang
136
     * @param  string $default_lang
0 ignored issues
show
Bug introduced by
There is no parameter named $default_lang. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

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

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

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

Loading history...
137
     * @param  array  $texts
138
     * @return void
139
     */
140 23
    public function setLocale($lang, $texts = null)
141
    {
142 23
        if (!$lang) {
143 1
            throw new InvalidArgumentException('Locale is empty');
144
        }
145 22
        $this->lang = $lang;
146
147 22
        $this->setCacheName($lang);
148
149 22
        if (is_array($texts)) {
150 3
            $texts = new Collection($texts);
151 3
        } else {
152 19
            $texts = $this->loadTexts($this->getLocale());
153
        }
154
155 22
        $this->texts = new Collection($texts);
156 22
    }
157
158
    /**
159
     * Load texts
160
     *
161
     * @param  string  $lang
162
     * @return array
163
     */
164 19
    public function loadTexts($lang = null)
165
    {
166 19
        $cache = $this->getConfig('cache');
167
168 19
        if (!$cache || $this->cache === null || $this->environment != 'production') {
169 16
            $texts = $this->loadTextsFromDatabase($lang);
170 16
            return $texts;
171
        }
172
173 4
        if ($this->mustLoadFromCache()) {
174
            $texts = $this->loadTextsFromCache();
175
        } else {
176 4
            $texts = $this->loadTextsFromDatabase($lang);
177 4
            $this->storeTextsInCache($texts);
178
        }
179
180 4
        return $texts;
181
    }
182
183
    /**
184
     * Get translated text
185
     *
186
     * @param  string   $key
187
     * @return string
188
     */
189 8
    public function get($key)
190
    {
191
192 8
        if (empty($key)) {
193 1
            throw new InvalidArgumentException('String key not provided');
194
        }
195
196 7
        if (!$this->lang) {
197 1
            return $key;
198
        }
199
200 6
        if (!$this->texts->has($key)) {
201 4
            $this->queueToSave($key);
202 4
            return $key;
203
        }
204
205 2
        $text = $this->texts->get($key);
206
207 2
        return $text;
208
    }
209
210
    /**
211
     * Get texts
212
     *
213
     * @return array
214
     */
215 4
    public function getRedirectUrl(Request $request)
216
    {
217 4
        $locale          = $request->segment(1);
218 4
        $fallback_locale = $this->getConfig('default_locale');
219
220 4
        if (strlen($locale) == 2) {
221 3
            $locales = $this->getConfig('locales');
222
223 3
            if (!isset($locales[$locale])) {
224 2
                $segments    = $request->segments();
225 2
                $segments[0] = $fallback_locale;
226 2
                $url         = implode('/', $segments);
227 2
                if ($query_string = $request->server->get('QUERY_STRING')) {
228 1
                    $url .= '?' . $query_string;
229 1
                }
230
231 2
                return $url;
232
            }
233 1
        } else {
234 1
            $segments = $request->segments();
235 1
            $url      = $fallback_locale . '/' . implode('/', $segments);
236 1
            if ($query_string = $request->server->get('QUERY_STRING')) {
237
                $url .= '?' . $query_string;
238
            }
239 1
            return $url;
240
        }
241
242 1
        return null;
243
    }
244
245 1
    public function detectLocale(Request $request)
246
    {
247 1
        $locale  = $request->segment(1);
248 1
        $locales = $this->getConfig('locales');
249
250 1
        if (isset($locales[$locale])) {
251 1
            $this->setLocale($locale);
252 1
            return isset($locales[$locale]['locale']) ? $locales[$locale]['locale'] : $locale;
253
        }
254
255
        $fallback_locale = $this->getConfig('default_locale');
256
        $this->setLocale($fallback_locale);
257
        return $locale;
258
    }
259
260
    /**
261
     * Get texts
262
     *
263
     * @return array
264
     */
265 4
    public function getTexts()
266
    {
267
268 4
        return $this->texts->toArray();
269
    }
270
271
    /**
272
     * Set texts manually
273
     *
274
     * @param  array                                 $texts_array
275
     * @return \Longman\LaravelMultiLang\MultiLang
276
     */
277 3
    public function setTexts(array $texts_array)
278
    {
279 3
        $texts = [];
280 3
        foreach ($texts_array as $key => $value) {
281 3
            $texts[$key] = $value;
282 3
        }
283
284 3
        $this->texts = new Collection($texts);
285
286 3
        return $this;
287
    }
288
289
    /**
290
     * Queue missing texts
291
     *
292
     * @param  string $key
293
     * @return void
294
     */
295 4
    protected function queueToSave($key)
296
    {
297 4
        $this->new_texts[$key] = $key;
298 4
    }
299
300
    /**
301
     * Check if we must load texts from cache
302
     *
303
     * @return bool
304
     */
305 4
    public function mustLoadFromCache()
306
    {
307 4
        return $this->cache->has($this->getCacheName());
308
    }
309
310 4
    protected function storeTextsInCache(array $texts)
311
    {
312 4
        $cache_lifetime = $this->getConfig('cache_lifetime');
313 4
        $this->cache->put($this->getCacheName(), $texts, $cache_lifetime);
314 4
        return $this;
315
    }
316
317 19
    public function loadTextsFromDatabase($lang)
318
    {
319 19
        $texts = $lang ? $this->db->table($this->getTableName())
320 19
            ->where('lang', $lang)
321 19
            ->get(['key', 'value', 'lang', 'scope']) : $this->db->table($this->getTableName())->get(['key', 'value', 'lang', 'scope']);
322
323 19
        $array = [];
324 19
        foreach ($texts as $row) {
325 14
            $array[$row->key] = $row->value;
326 19
        }
327 19
        return $array;
328
    }
329
330 1
    public function loadTextsFromCache()
331
    {
332 1
        $texts = $this->cache->get($this->getCacheName());
0 ignored issues
show
Bug introduced by
The method get() cannot be called from this context as it is declared protected in class Illuminate\Cache\CacheManager.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
333
334 1
        return $texts;
335
    }
336
337 22
    public function setCacheName($lang)
338
    {
339 22
        $this->cache_name = $this->getConfig('texts_table') . '_' . $lang;
340 22
    }
341
342 4
    public function getCacheName()
343
    {
344 4
        return $this->cache_name;
345
    }
346
347 2
    public function getUrl($path)
348
    {
349 2
        $locale = $this->getLocale();
350 2
        if ($locale) {
351 2
            $path = $locale . '/' . $path;
352 2
        }
353 2
        return $path;
354
    }
355
356 4
    public function autoSaveIsAllowed()
357
    {
358 4
        if ($this->environment == 'local' && $this->getConfig('autosave') && $this->db !== null) {
359 1
            return true;
360
        }
361 4
        return false;
362
    }
363
364 20
    public function getLocale()
365
    {
366 20
        return $this->lang;
367
    }
368
369 3
    public function saveTexts()
370
    {
371 3
        if (empty($this->new_texts)) {
372 3
            return false;
373
        }
374
375 3
        $table   = $this->getTableName();
376 3
        $locales = $this->getConfig('locales');
377 3
        foreach ($this->new_texts as $k => $v) {
378 3
            foreach ($locales as $lang => $locale_data) {
379 3
                $exists = $this->db->table($table)->where([
380 3
                    'key'  => $k,
381 3
                    'lang' => $lang,
382 3
                ])->first();
383
384 3
                if ($exists) {
385 1
                    continue;
386
                }
387
388 3
                $this->db->table($table)->insert([
389 3
                    'key'   => $k,
390 3
                    'lang'  => $lang,
391 3
                    'value' => $v,
392 3
                ]);
393 3
            }
394 3
        }
395 3
        return true;
396
    }
397
398 19
    protected function getTableName()
399
    {
400 19
        $table = $this->getConfig('texts_table');
401 19
        return $table;
402
    }
403
}
404