Completed
Push — master ( f7bd00...f5f6c6 )
by Avtandil
03:36
created

MultiLang::loadTextsFromCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
crap 1
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\Contracts\Cache\Factory as CacheContract;
14
use Illuminate\Database\DatabaseManager as DatabaseContract;
15
use Illuminate\Support\Collection;
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 collection.
64
     *
65
     * @var \Illuminate\Support\Collection
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
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
84
     */
85 13
    public function __construct($environment, array $config, CacheContract $cache, DatabaseContract $db)
86
    {
87 13
        $this->environment = $environment;
88 13
        $this->cache       = $cache;
0 ignored issues
show
Documentation Bug introduced by
$cache is of type object<Illuminate\Contracts\Cache\Factory>, but the property $cache was declared to be of type object<Illuminate\Cache\CacheManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
89 13
        $this->db          = $db;
90
91 13
        $this->setConfig($config);
92 13
    }
93
94 13
    public function setConfig(array $config)
95
    {
96 13
        $this->config = [
97 13
            'enabled'        => true,
98
            'locales'        => [
99
                'en' => [
100 13
                    'name'        => 'English',
101 13
                    'native_name' => 'English',
102 13
                    'default'     => true,
103 13
                ],
104 13
            ],
105 13
            'autosave'       => true,
106 13
            'cache'          => true,
107 13
            'cache_lifetime' => 1440,
108 13
            'texts_table'    => 'texts',
109
        ];
110
111 13
        foreach ($config as $k => $v) {
112 1
            $this->config[$k] = $v;
113 13
        }
114 13
    }
115
116 12
    public function getConfig($key = null)
117
    {
118 12
        if ($key === null) {
119
            return $this->config;
120
        }
121
122 12
        return isset($this->config[$key]) ? $this->config[$key] : null;
123
    }
124
125
    /**
126
     * Set locale and load texts
127
     *
128
     * @param  string $lang
129
     * @param  array  $text
0 ignored issues
show
Bug introduced by
There is no parameter named $text. 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...
130
     * @return void
131
     */
132 13
    public function setLocale($lang, $texts = null)
133
    {
134 13
        if (!$lang) {
135 1
            throw new InvalidArgumentException('Locale is empty');
136
        }
137 12
        $this->lang = $lang;
138
139 12
        $this->setCacheName($lang);
140
141 12
        if (is_array($texts)) {
142
            $texts = new Collection($texts);
143
        }
144
145 12
        if ($texts === null) {
146 12
            $texts = $this->loadTexts($this->getLocale());
147 12
        }
148
149 12
        $this->texts = new Collection($texts);
150 12
    }
151
152
    /**
153
     * Load texts
154
     *
155
     * @param  string  $lang
156
     * @return array
157
     */
158 12
    public function loadTexts($lang = null)
159
    {
160 12
        $cache = $this->getConfig('cache');
161
162 12
        if (!$cache || $this->cache === null || $this->environment != 'production') {
163 9
            $texts = $this->loadTextsFromDatabase($lang);
164 9
            return $texts;
165
        }
166
167 4
        if ($this->mustLoadFromCache()) {
168
            $texts = $this->loadTextsFromCache();
169
        } else {
170 4
            $texts = $this->loadTextsFromDatabase($lang);
171 4
            $this->storeTextsInCache($texts);
172
        }
173
174 4
        return $texts;
175
    }
176
177
    /**
178
     * Get translated text
179
     *
180
     * @param  string   $key
181
     * @param  string   $default
0 ignored issues
show
Bug introduced by
There is no parameter named $default. 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...
182
     * @return string
183
     */
184 4
    public function get($key)
185
    {
186
187 4
        if (empty($key)) {
188 1
            throw new InvalidArgumentException('String key not provided');
189
        }
190
191 3
        if (!$this->lang) {
192
            return $key;
193
        }
194
195 3
        if (!$this->texts->has($key)) {
196 2
            $this->queueToSave($key);
197 2
            return $key;
198
        }
199
200 1
        $text = $this->texts->get($key);
201
202 1
        return $text;
203
    }
204
205
    /**
206
     * Get texts
207
     *
208
     * @return array
209
     */
210 2
    public function getTexts()
211
    {
212
213 2
        return $this->texts->toArray();
214
    }
215
216
    /**
217
     * Set texts manually
218
     *
219
     * @param  array                                 $texts_array
220
     * @return \Longman\LaravelMultiLang\MultiLang
221
     */
222 3
    public function setTexts(array $texts_array)
223
    {
224 3
        $texts = [];
225 3
        foreach ($texts_array as $key => $value) {
226 3
            $texts[$key] = $value;
227 3
        }
228
229 3
        $this->texts = new Collection($texts);
230
231 3
        return $this;
232
    }
233
234
    /**
235
     * Queue missing texts
236
     *
237
     * @param  string $key
238
     * @return void
239
     */
240 2
    protected function queueToSave($key)
241
    {
242 2
        $this->new_texts[$key] = $key;
243 2
    }
244
245
    /**
246
     * Check if we must load texts from cache
247
     *
248
     * @return bool
249
     */
250 4
    public function mustLoadFromCache()
251
    {
252 4
        return $this->cache->has($this->getCacheName());
253
    }
254
255 4
    protected function storeTextsInCache(array $texts)
256
    {
257 4
        $cache_lifetime = $this->getConfig('cache_lifetime', 1440);
0 ignored issues
show
Unused Code introduced by
The call to MultiLang::getConfig() has too many arguments starting with 1440.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
258 4
        $status         = $this->cache->put($this->getCacheName(), $texts, $cache_lifetime);
259 4
        return $status;
260
    }
261
262 12
    public function loadTextsFromDatabase($lang)
263
    {
264 12
        $texts = $lang ? $this->db->table($this->getTableName())
265 12
            ->where('lang', $lang)
266 12
            ->get(['key', 'value', 'lang', 'scope']) : $this->db->table($this->getTableName())->get(['key', 'value', 'lang', 'scope']);
267
268 12
        $array = [];
269 12
        foreach ($texts as $row) {
270 12
            $array[$row->key] = $row->value;
271 12
        }
272 12
        return $array;
273
    }
274
275 1
    public function loadTextsFromCache()
276
    {
277 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...
278
279 1
        return $texts;
280
    }
281
282 12
    public function setCacheName($lang)
283
    {
284 12
        $this->cache_name = $this->getConfig('texts_table') . '_' . $lang;
285 12
    }
286
287 4
    public function getCacheName()
288
    {
289 4
        return $this->cache_name;
290
    }
291
292 1
    public function getUrl($path)
293
    {
294 1
        $locale = $this->getLocale();
295 1
        if ($locale) {
296 1
            $path = $locale . '/' . $path;
297 1
        }
298 1
        return $path;
299
    }
300
301 1
    public function autoSaveIsAllowed()
302
    {
303 1
        if ($this->environment == 'local' && $this->getConfig('autosave') && $this->db !== null) {
304 1
            return true;
305
        }
306 1
        return false;
307
    }
308
309 12
    public function getLocale()
310
    {
311 12
        return $this->lang;
312
    }
313
314 1
    public function saveTexts()
315
    {
316 1
        if (empty($this->new_texts)) {
317 1
            return false;
318
        }
319
320 1
        $lang  = $this->lang;
321 1
        $table = $this->getTableName();
322 1
        foreach ($this->new_texts as $k => $v) {
323 1
            $exists = $this->db->table($table)->where([
324 1
                'key'  => $k,
325 1
                'lang' => $lang,
326 1
            ])->first();
327
328 1
            if ($exists) {
329
                continue;
330
            }
331
332 1
            $this->db->table($table)->insert([
333 1
                'key'   => $k,
334 1
                'lang'  => $lang,
335 1
                'value' => $v,
336 1
            ]);
337 1
        }
338 1
        return true;
339
    }
340
341 12
    protected function getTableName()
342
    {
343 12
        $table = $this->getConfig('texts_table');
344 12
        return $table;
345
    }
346
}
347