Completed
Push — master ( 20bb8b...e297f9 )
by Avtandil
09:09
created

MultiLang::getScope()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 4
ccs 1
cts 1
cp 1
crap 1
rs 10
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 Closure;
14
use Illuminate\Cache\CacheManager as Cache;
15
use Illuminate\Database\DatabaseManager as Database;
16
use Illuminate\Http\Request;
17
use Illuminate\Routing\Router;
18
use InvalidArgumentException;
19
use Longman\LaravelMultiLang\Config;
20
use Longman\LaravelMultiLang\Repository;
21
22
class MultiLang
23
{
24
    /**
25
     * Language/Locale.
26
     *
27
     * @var string
28
     */
29
    protected $lang;
30
31
    /**
32
     * System environment
33
     *
34
     * @var string
35
     */
36
    protected $environment;
37
38
    /**
39
     * Config.
40
     *
41
     * @var \Longman\LaravelMultiLang\Config
42
     */
43
    protected $config;
44
45
    /**
46
     * Repository
47
     *
48
     * @var \Longman\LaravelMultiLang\Repository
49
     */
50
    protected $repository;
51
52
    /**
53
     * Texts.
54
     *
55
     * @var array
56
     */
57
    protected $texts;
58
59
    /**
60
     * Missing texts.
61
     *
62
     * @var array
63
     */
64
    protected $new_texts;
65
66
    /**
67
     * Application scope.
68
     *
69
     * @var string
70
     */
71
    protected $scope;
72
73
    /**
74 23
     * Create a new MultiLang instance.
75
     *
76 23
     * @param string                               $environment
77 23
     * @param array                                $config
78 23
     * @param \Illuminate\Cache\CacheManager       $cache
79
     * @param \Illuminate\Database\DatabaseManager $db
80 23
     */
81
    public function __construct($environment, array $config, Cache $cache, Database $db)
82 23
    {
83 23
        $this->environment = $environment;
84
        $this->cache       = $cache;
0 ignored issues
show
Bug introduced by
The property cache 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...
85 23
        $this->db          = $db;
0 ignored issues
show
Bug introduced by
The property db 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...
86
87 23
        $this->setConfig($config);
88 23
89
        $this->setRepository(new Repository($this->config, $cache, $db));
90
    }
91 23
92
    /**
93 23
     * Set multilang config
94 23
     *
95
     * @param array $config
96
     * @return $this
97 2
     */
98
    public function setConfig(array $config)
99 2
    {
100
        $this->config = new Config($config);
101
        return $this;
102
    }
103
104
    /**
105
     * Set repository object
106
     *
107
     * @param \Longman\LaravelMultiLang\Repository $repository
108
     * @return $this
109 21
     */
110
    public function setRepository(Repository $repository)
111 21
    {
112 1
        $this->repository = $repository;
113
        return $this;
114 20
    }
115
116 20
    /**
117 17
     * Get repository object
118 17
     *
119
     * @return \Longman\LaravelMultiLang\Repository
120 20
     */
121 20
    public function getRepository()
122
    {
123
        return $this->repository;
124
    }
125
126
    /**
127
     * Set application scope
128
     *
129 17
     * @param $scope
130
     * @return $this
131 17
     */
132 15
    public function setScope($scope)
133 15
    {
134
        $this->scope = $scope;
135
        return $this;
136 3
    }
137
138
    /**
139 3
     * Get application scope
140 3
     *
141
     * @return string
142
     */
143 3
    public function getScope()
144
    {
145
        return $this->scope;
146
    }
147
148
    /**
149
     * Set locale and load texts
150
     *
151
     * @param  string $lang
152 8
     * @param  array  $texts
153
     * @return void
154
     */
155 8
    public function setLocale($lang, array $texts = null)
156 1
    {
157
        if (!$lang) {
158
            throw new InvalidArgumentException('Locale is empty');
159 7
        }
160 1
        $this->lang = $lang;
161
162
        if (!is_array($texts)) {
163 6
            $texts = $this->loadTexts($this->getLocale(), $this->scope);
164 4
        }
165 4
166
        $this->texts = $texts;
167
    }
168 2
169
    /**
170 2
     * Load texts
171
     *
172
     * @param  string $lang
173
     * @param  string $scope
174
     * @return array
175
     */
176
    public function loadTexts($lang, $scope = null)
177
    {
178 4
        if ($this->environment != 'production' || $this->config->get('cache.enabled', true) === false) {
179
            $texts = $this->repository->loadFromDatabase($lang, $scope);
0 ignored issues
show
Bug introduced by
It seems like $scope defined by parameter $scope on line 176 can also be of type string; however, Longman\LaravelMultiLang...ory::loadFromDatabase() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
180 4
            return $texts;
181 4
        }
182 4
183 4
        if ($this->repository->existsInCache($lang)) {
184
            $texts = $this->repository->loadFromCache($lang, $scope);
0 ignored issues
show
Bug introduced by
It seems like $scope defined by parameter $scope on line 176 can also be of type string; however, Longman\LaravelMultiLang...sitory::loadFromCache() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
185
        } else {
186
            $texts = $this->repository->loadFromDatabase($lang, $scope);
0 ignored issues
show
Bug introduced by
It seems like $scope defined by parameter $scope on line 176 can also be of type string; however, Longman\LaravelMultiLang...ory::loadFromDatabase() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
187 4
            $this->repository->storeInCache($lang, $texts, $scope);
0 ignored issues
show
Bug introduced by
It seems like $scope defined by parameter $scope on line 176 can also be of type string; however, Longman\LaravelMultiLang...ository::storeInCache() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
188 3
        }
189
190 3
        return $texts;
191 2
    }
192 2
193 2
    /**
194 2
     * Get translated text
195 1
     *
196 1
     * @param  string $key
197
     * @return string
198 2
     */
199
    public function get($key)
200 1
    {
201 1
202 1
        if (empty($key)) {
203 1
            throw new InvalidArgumentException('String key not provided');
204
        }
205
206 1
        if (!$this->lang) {
207
            return $key;
208
        }
209 1
210
        if (!isset($this->texts[$key])) {
211
            $this->queueToSave($key);
212 1
            return $key;
213
        }
214 1
215 1
        $text = $this->texts[$key];
216
217 1
        return $text;
218 1
    }
219
220
    /**
221
     * Get redirect url in middleware
222
     *
223
     * @param \Illuminate\Http\Request $request
224
     * @return null|string
225
     */
226
    public function getRedirectUrl(Request $request)
227
    {
228
        $locale           = $request->segment(1);
229
        $fallback_locale  = $this->config->get('default_locale', 'en');
230
        $exclude_segments = $this->config->get('exclude_segments', []);
231
        if (in_array($locale, $exclude_segments)) {
232
            return null;
233
        }
234
235
        if (strlen($locale) == 2) {
236
            $locales = $this->config->get('locales', []);
237
238
            if (!isset($locales[$locale])) {
239
                $segments    = $request->segments();
240
                $segments[0] = $fallback_locale;
241
                $url         = implode('/', $segments);
242
                if ($query_string = $request->server->get('QUERY_STRING')) {
243
                    $url .= '?' . $query_string;
244
                }
245
246
                return $url;
247
            }
248
        } else {
249
            $segments = $request->segments();
250
            $url      = $fallback_locale . '/' . implode('/', $segments);
251
            if ($query_string = $request->server->get('QUERY_STRING')) {
252
                $url .= '?' . $query_string;
253
            }
254
            return $url;
255
        }
256
257
        return null;
258
    }
259
260 4
    /**
261
     * Detect locale based on url segment
262
     *
263 4
     * @param \Illuminate\Http\Request $request
264
     * @return string
265
     */
266
    public function detectLocale(Request $request)
267
    {
268
        $locale  = $request->segment(1);
269
        $locales = $this->config->get('locales');
270
271
        if (isset($locales[$locale])) {
272 3
            return isset($locales[$locale]['locale']) ? $locales[$locale]['locale'] : $locale;
273
        }
274 3
275 3
        return $this->config->get('default_locale', 'en');
276 3
    }
277 3
278
    /**
279 3
     * Wrap routes to available languages group
280
     *
281 3
     * @param \Closure $callback
282
     */
283
    public function routeGroup(Closure $callback)
284
    {
285
        $router = app('router');
286
287
        $locales = $this->config->get('locales', []);
288
289
        foreach ($locales as $locale => $val) {
290 4
            $router->group([
291
                               'prefix' => $locale,
292 4
                               'as'     => $locale . '.',
293 4
                           ], $callback);
294
        }
295 2
296
    }
297 2
298 2
    /**
299 2
     *  Manage texts
300 2
     */
301 2
    public function manageTextsRoutes()
302
    {
303
        $router     = app('router');
304 5
        $route      = $this->config->get('text-route.route', 'texts');
305
        $controller = $this->config->get(
306 5
            'text-route.controller',
307 1
            '\Longman\LaravelMultiLang\Controllers\TextsController'
308
        );
309 5
310
        $router->get(
311
            $route,
312 18
            ['uses' => $controller . '@index']
313
        );
314 18
        $router->post(
315
            $route,
316
            ['uses' => $controller . '@save']
317 1
        );
318
    }
319 1
320
    /**
321
     * Get texts
322 3
     *
323
     * @return array
324 3
     */
325 3
    public function getTexts()
326
    {
327
328 3
        return $this->texts;
329 3
    }
330
331
    /**
332
     * Set texts manually
333
     *
334
     * @param  array $texts_array
335
     * @return \Longman\LaravelMultiLang\MultiLang
336
     */
337
    public function setTexts(array $texts_array)
338
    {
339
        $texts = [];
340
        foreach ($texts_array as $key => $value) {
341
            $texts[$key] = $value;
342
        }
343
344
        $this->texts = $texts;
345
346
        return $this;
347
    }
348
349
    /**
350
     * Queue missing texts
351
     *
352
     * @param  string $key
353
     * @return void
354
     */
355
    protected function queueToSave($key)
356
    {
357
        $this->new_texts[$key] = $key;
358
    }
359
360
    /**
361
     * Get language prefixed url
362
     *
363
     * @param $path
364
     * @return string
365
     */
366
    public function getUrl($path)
367
    {
368
        $locale = $this->getLocale();
369
        if ($locale) {
370
            $path = $locale . '/' . $path;
371
        }
372
        return $path;
373
    }
374
375
    /**
376
     * Check if autosave allowed
377
     *
378
     * @return bool
379
     */
380
    public function autoSaveIsAllowed()
381
    {
382
        if ($this->environment == 'local' && $this->config->get('db.autosave', true)) {
383
            return true;
384
        }
385
        return false;
386
    }
387
388
    /**
389
     * Get locale
390
     *
391
     * @return string
392
     */
393
    public function getLocale()
394
    {
395
        return $this->lang;
396
    }
397
398
    /**
399
     * Get available locales
400
     *
401
     * @return array
402
     */
403
    public function getLocales()
404
    {
405
        return $this->config->get('locales');
406
    }
407
408
    /**
409
     * Save missing texts
410
     *
411
     * @return bool
412
     */
413
    public function saveTexts()
414
    {
415
        if (empty($this->new_texts)) {
416
            return false;
417
        }
418
419
        $this->repository->save($this->new_texts, $this->scope);
420
        return true;
421
    }
422
}
423