Completed
Push — master ( 49cc2f...b2199f )
by
unknown
02:53
created

MultiLang::detectLocale()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 2
Bugs 2 Features 0
Metric Value
c 2
b 2
f 0
dl 0
loc 11
ccs 5
cts 6
cp 0.8333
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
crap 3.0416
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 InvalidArgumentException;
17
18
class MultiLang
19
{
20
    /**
21
     * Language/Locale.
22
     *
23
     * @var string
24
     */
25
    protected $lang;
26
27
    /**
28
     * System environment
29
     *
30
     * @var string
31
     */
32
    protected $environment;
33
34
    /**
35
     * The instance of the cache.
36
     *
37
     * @var \Illuminate\Cache\CacheManager
38
     */
39
    protected $cache;
40
41
    /**
42
     * Config.
43
     *
44
     * @var array
45
     */
46
    protected $config;
47
48
    /**
49
     * The instance of the database.
50
     *
51
     * @var \Illuminate\Database\DatabaseManager
52
     */
53
    protected $db;
54
55
    /**
56
     * Name of the cache.
57
     *
58
     * @var string
59
     */
60
    protected $cache_name;
61
62
    /**
63
     * Texts.
64
     *
65
     * @var array
66
     */
67
    protected $texts;
68
69
    /**
70
     * Missing texts.
71
     *
72
     * @var array
73
     */
74
    protected $new_texts;
75
76
    /**
77
     * Create a new MultiLang instance.
78
     *
79
     * @param string                               $environment
80
     * @param array                                $config
81
     * @param \Illuminate\Cache\CacheManager       $cache
82
     * @param \Illuminate\Database\DatabaseManager $db
83
     */
84 24
    public function __construct($environment, array $config, Cache $cache, Database $db)
85
    {
86 24
        $this->environment = $environment;
87 24
        $this->cache       = $cache;
88 24
        $this->db          = $db;
89
90 24
        $this->setConfig($config);
91 24
    }
92
93 24
    public function setConfig(array $config)
94
    {
95 24
        $this->config = $config;
96 24
        return $this;
97
    }
98
99 21
    public function getConfig($key = null, $default = null)
100
    {
101 21
        $array = $this->config;
102
103 21
        if ($key === null) {
104
            return $array;
105
        }
106
107 21
        if (array_key_exists($key, $array)) {
108 7
            return $array[$key];
109
        }
110
111 21
        foreach (explode('.', $key) as $segment) {
112 21
            if (is_array($array) && array_key_exists($segment, $array)) {
113 21
                $array = $array[$segment];
114 21
            } else {
115
                return $default;
116
            }
117 21
        }
118
119 21
        return $array;
120
    }
121
122
    /**
123
     * Get a cache driver instance.
124
     *
125
     * @return \Illuminate\Contracts\Cache\Repository
126
     */
127 18
    public function getCache()
128
    {
129 18
        if ($this->getConfig('cache.enabled', true) === false) {
130 1
            return null;
131
        }
132 17
        $store = $this->getConfig('cache.store', 'default');
133 17
        if ($store == 'default') {
134
            return $this->cache->store();
135
        }
136 17
        return $this->cache->store($store);
137
    }
138
139
    /**
140
     * Get a database connection instance.
141
     *
142
     * @return \Illuminate\Database\Connection
143
     */
144 18
    public function getDb()
145
    {
146 18
        $connection = $this->getConfig('db.connection');
147 18
        if ($connection == 'default') {
148 18
            return $this->db->connection();
149
        }
150
        return $this->db->connection($connection);
151
    }
152
153
    /**
154
     * Set locale and load texts
155
     *
156
     * @param  string $lang
157
     * @param  array  $texts
158
     * @return void
159
     */
160 22
    public function setLocale($lang, array $texts = null)
161
    {
162 22
        if (!$lang) {
163 1
            throw new InvalidArgumentException('Locale is empty');
164
        }
165 21
        $this->lang = $lang;
166
167 21
        $this->setCacheName($lang);
168
169 21
        if (!is_array($texts)) {
170 18
            $texts = $this->loadTexts($this->getLocale());
171 18
        }
172
173 21
        $this->texts = $texts;
174 21
    }
175
176
    /**
177
     * Load texts
178
     *
179
     * @param  string  $lang
180
     * @return array
181
     */
182 18
    public function loadTexts($lang = null)
183
    {
184 18
        if ($this->getCache() === null || $this->environment != 'production') {
185 15
            $texts = $this->loadTextsFromDatabase($lang);
186 15
            return $texts;
187
        }
188
189 4
        if ($this->mustLoadFromCache()) {
190
            $texts = $this->loadTextsFromCache();
191
        } else {
192 4
            $texts = $this->loadTextsFromDatabase($lang);
193 4
            $this->storeTextsInCache($texts);
194
        }
195
196 4
        return $texts;
197
    }
198
199
    /**
200
     * Get translated text
201
     *
202
     * @param  string   $key
203
     * @return string
204
     */
205 8
    public function get($key)
206
    {
207
208 8
        if (empty($key)) {
209 1
            throw new InvalidArgumentException('String key not provided');
210
        }
211
212 7
        if (!$this->lang) {
213 1
            return $key;
214
        }
215
216 6
        if (!isset($this->texts[$key])) {
217 4
            $this->queueToSave($key);
218 4
            return $key;
219
        }
220
221 2
        $text = $this->texts[$key];
222
223 2
        return $text;
224
    }
225
226
    /**
227
     * Get texts
228
     *
229
     * @return array
230
     */
231 4
    public function getRedirectUrl(Request $request)
232
    {
233 4
        $locale          = $request->segment(1);
234 4
        $fallback_locale = $this->getConfig('default_locale');
235
236 4
        if (strlen($locale) == 2) {
237 3
            $locales = $this->getConfig('locales');
238
239 3
            if (!isset($locales[$locale])) {
240 2
                $segments    = $request->segments();
241 2
                $segments[0] = $fallback_locale;
242 2
                $url         = implode('/', $segments);
243 2
                if ($query_string = $request->server->get('QUERY_STRING')) {
244 1
                    $url .= '?' . $query_string;
245 1
                }
246
247 2
                return $url;
248
            }
249 1
        } else {
250 1
            $segments = $request->segments();
251 1
            $url      = $fallback_locale . '/' . implode('/', $segments);
252 1
            if ($query_string = $request->server->get('QUERY_STRING')) {
253
                $url .= '?' . $query_string;
254
            }
255 1
            return $url;
256
        }
257
258 1
        return null;
259
    }
260
261 1
    public function detectLocale(Request $request)
262
    {
263 1
        $locale  = $request->segment(1);
264 1
        $locales = $this->getConfig('locales');
265
266 1
        if (isset($locales[$locale])) {
267 1
            return isset($locales[$locale]['locale']) ? $locales[$locale]['locale'] : $locale;
268
        }
269
270
        return $this->getConfig('default_locale', 'en');
271
    }
272
273
    /**
274
     * Get texts
275
     *
276
     * @return array
277
     */
278 4
    public function getTexts()
279
    {
280
281 4
        return $this->texts;
282
    }
283
284
    /**
285
     * Set texts manually
286
     *
287
     * @param  array                                 $texts_array
288
     * @return \Longman\LaravelMultiLang\MultiLang
289
     */
290 3
    public function setTexts(array $texts_array)
291
    {
292 3
        $texts = [];
293 3
        foreach ($texts_array as $key => $value) {
294 3
            $texts[$key] = $value;
295 3
        }
296
297 3
        $this->texts = $texts;
298
299 3
        return $this;
300
    }
301
302
    /**
303
     * Queue missing texts
304
     *
305
     * @param  string $key
306
     * @return void
307
     */
308 4
    protected function queueToSave($key)
309
    {
310 4
        $this->new_texts[$key] = $key;
311 4
    }
312
313
    /**
314
     * Check if we must load texts from cache
315
     *
316
     * @return bool
317
     */
318 4
    public function mustLoadFromCache()
319
    {
320 4
        return $this->getCache()->has($this->getCacheName());
321
    }
322
323 4
    protected function storeTextsInCache(array $texts)
324
    {
325 4
        $this->getCache()->put($this->getCacheName(), $texts, $this->getConfig('cache.lifetime', 1440));
326 4
        return $this;
327
    }
328
329 18
    public function loadTextsFromDatabase($lang)
330
    {
331 18
        $texts = $lang ? $this->getDb()->table($this->getTableName())
332 18
            ->where('lang', $lang)
333 18
            ->get(['key', 'value', 'lang', 'scope']) : $this->getDb()->table($this->getTableName())->get(['key', 'value', 'lang', 'scope']);
334
335 18
        $array = [];
336 18
        foreach ($texts as $row) {
337 13
            $array[$row->key] = $row->value;
338 18
        }
339 18
        return $array;
340
    }
341
342 1
    public function loadTextsFromCache()
343
    {
344 1
        $texts = $this->getCache()->get($this->getCacheName());
345
346 1
        return $texts;
347
    }
348
349 21
    public function setCacheName($lang)
350
    {
351 21
        $this->cache_name = $this->getConfig('db.texts_table') . '_' . $lang;
352 21
    }
353
354 4
    public function getCacheName()
355
    {
356 4
        return $this->cache_name;
357
    }
358
359 2
    public function getUrl($path)
360
    {
361 2
        $locale = $this->getLocale();
362 2
        if ($locale) {
363 2
            $path = $locale . '/' . $path;
364 2
        }
365 2
        return $path;
366
    }
367
368 5
    public function autoSaveIsAllowed()
369
    {
370 5
        if ($this->environment == 'local' && $this->getConfig('db.autosave', true) && $this->getDb() !== null) {
371 1
            return true;
372
        }
373 5
        return false;
374
    }
375
376 19
    public function getLocale()
377
    {
378 19
        return $this->lang;
379
    }
380
381 3
    public function saveTexts()
382
    {
383 3
        if (empty($this->new_texts)) {
384 3
            return false;
385
        }
386
387 3
        $table   = $this->getTableName();
388 3
        $locales = $this->getConfig('locales');
389
390 3
        foreach ($this->new_texts as $k => $v) {
391 3
            foreach ($locales as $lang => $locale_data) {
392 3
                $exists = $this->getDb()->table($table)->where([
393 3
                    'key'  => $k,
394 3
                    'lang' => $lang,
395 3
                ])->first();
396
397 3
                if ($exists) {
398 1
                    continue;
399
                }
400
401 3
                $this->getDb()->table($table)->insert([
402 3
                    'key'   => $k,
403 3
                    'lang'  => $lang,
404 3
                    'value' => $v,
405 3
                ]);
406 3
            }
407 3
        }
408 3
        return true;
409
    }
410
411 18
    protected function getTableName()
412
    {
413 18
        $table = $this->getConfig('db.texts_table', 'texts');
414 18
        return $table;
415
    }
416
}
417