Completed
Push — master ( 427d1b...7d660e )
by Avtandil
03:12
created

MultiLang::mustLoadFromCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 5
Bugs 2 Features 2
Metric Value
c 5
b 2
f 2
dl 0
loc 4
rs 10
ccs 0
cts 2
cp 0
cc 1
eloc 2
nc 1
nop 0
crap 2
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
use Longman\LaravelMultiLang\Config;
18
use Longman\LaravelMultiLang\Repository;
19
20
class MultiLang
21
{
22
    /**
23
     * Language/Locale.
24
     *
25
     * @var string
26
     */
27
    protected $lang;
28
29
    /**
30
     * System environment
31
     *
32
     * @var string
33
     */
34
    protected $environment;
35
36
    /**
37
     * The instance of the cache.
38
     *
39
     * @var \Illuminate\Cache\CacheManager
40
     */
41
    protected $cache;
42
43
    /**
44
     * Config.
45
     *
46
     * @var \Longman\LaravelMultiLang\Config
47
     */
48
    protected $config;
49
50
    /**
51
     * The instance of the database.
52
     *
53
     * @var \Illuminate\Database\DatabaseManager
54
     */
55
    protected $db;
56
57
    /**
58
     * Name of the cache.
59
     *
60
     * @var string
61
     */
62
    protected $cache_name;
63
64
    /**
65
     * Texts.
66
     *
67
     * @var array
68
     */
69
    protected $texts;
70
71
    /**
72
     * Missing texts.
73
     *
74
     * @var array
75
     */
76
    protected $new_texts;
77
78
    /**
79
     * Create a new MultiLang instance.
80
     *
81
     * @param string                               $environment
82
     * @param array                                $config
83
     * @param \Illuminate\Cache\CacheManager       $cache
84
     * @param \Illuminate\Database\DatabaseManager $db
85
     */
86
    public function __construct($environment, array $config, Cache $cache, Database $db)
87
    {
88
        $this->environment = $environment;
89
        $this->cache       = $cache;
90
        $this->db          = $db;
91
92
        $this->setConfig($config);
93
94
        //$this->setRepository(new Repository($this->config, $cache, $db));
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
95
96
    }
97
98
    public function setConfig(array $config)
99
    {
100
        $this->config = new Config($config);
101
        return $this;
102
    }
103
104
    public function setRepository(Repository $repository)
105
    {
106
        $this->repository = $repository;
0 ignored issues
show
Bug introduced by
The property repository 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...
107
        return $this;
108
    }
109
110
    /**
111
     * Get a cache driver instance.
112
     *
113
     * @return \Illuminate\Contracts\Cache\Repository
114
     */
115 View Code Duplication
    public function getCache()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
    {
117
        if ($this->config->get('cache.enabled', true) === false) {
118
            return null;
119
        }
120
        $store = $this->config->get('cache.store', 'default');
121
        if ($store == 'default') {
122
            return $this->cache->store();
123
        }
124
        return $this->cache->store($store);
125
    }
126
127
    /**
128
     * Get a database connection instance.
129
     *
130
     * @return \Illuminate\Database\Connection
131
     */
132 View Code Duplication
    public function getDb()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
    {
319
        $texts = $lang ? $this->getDb()->table($this->getTableName())
320
            ->where('lang', $lang)
321
            ->get(['key', 'value', 'lang', 'scope']) : $this->getDb()->table($this->getTableName())->get(['key', 'value', 'lang', 'scope']);
322
323
        $array = [];
324
        foreach ($texts as $row) {
325
            $array[$row->key] = $row->value;
326
        }
327
        return $array;
328
    }
329
330
    public function loadTextsFromCache()
331
    {
332
        $texts = $this->getCache()->get($this->getCacheName());
333
334
        return $texts;
335
    }
336
337
    public function setCacheName($lang)
338
    {
339
        $this->cache_name = $this->config->get('db.texts_table') . '_' . $lang;
340
    }
341
342
    public function getCacheName()
343
    {
344
        return $this->cache_name;
345
    }
346
347
    public function getUrl($path)
348
    {
349
        $locale = $this->getLocale();
350
        if ($locale) {
351
            $path = $locale . '/' . $path;
352
        }
353
        return $path;
354
    }
355
356
    public function autoSaveIsAllowed()
357
    {
358
        if ($this->environment == 'local' && $this->config->get('db.autosave', true) && $this->getDb() !== null) {
359
            return true;
360
        }
361
        return false;
362
    }
363
364
    public function getLocale()
365
    {
366
        return $this->lang;
367
    }
368
369
    public function getLocales()
370
    {
371
        return $this->config->get('locales');
372
    }
373
374
    public function saveTexts()
375
    {
376
        if (empty($this->new_texts)) {
377
            return false;
378
        }
379
380
        $table   = $this->getTableName();
381
        $locales = $this->getLocales();
382
383 View Code Duplication
        foreach ($this->new_texts as $k => $v) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
384
            foreach ($locales as $lang => $locale_data) {
385
                $exists = $this->getDb()->table($table)->where([
386
                    'key'  => $k,
387
                    'lang' => $lang,
388
                ])->first();
389
390
                if ($exists) {
391
                    continue;
392
                }
393
394
                $this->getDb()->table($table)->insert([
395
                    'key'   => $k,
396
                    'lang'  => $lang,
397
                    'value' => $v,
398
                ]);
399
            }
400
        }
401
        return true;
402
    }
403
404
    protected function getTableName()
405
    {
406
        $table = $this->config->get('db.texts_table', 'texts');
407
        return $table;
408
    }
409
}
410