Completed
Push — master ( ed3a76...9562f4 )
by Avtandil
02:54
created

MultiLang::getDb()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

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