Completed
Push — master ( 5f83dd...427d1b )
by Avtandil
03:09
created

MultiLang::getConfig()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

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