Completed
Push — master ( aee3a6...824acf )
by Ben
23:56
created

Detect::setApplicationLocale()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 5
nop 0
dl 0
loc 23
ccs 12
cts 12
cp 1
crap 5
rs 8.5906
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Locale;
4
5
use Illuminate\Http\Request;
6
use Thinktomorrow\Locale\Detectors\FallbackDetector;
7
use Thinktomorrow\Locale\Detectors\HiddenSegmentDetector;
8
use Thinktomorrow\Locale\Detectors\QueryDetector;
9
use Thinktomorrow\Locale\Detectors\SegmentDetector;
10
use Thinktomorrow\Locale\Values\Config;
11
use Thinktomorrow\Locale\Values\Locale;
12
13
final class Detect
14
{
15
    /**
16
     * @var Request
17
     */
18
    private $request;
19
20
    /**
21
     * @var Config
22
     */
23
    private $config;
24
25
    /**
26
     * @var Locale
27
     */
28
    private $locale;
29
30
    /**
31
     * Current scope of locales.
32
     *
33
     * @var Scope
34
     */
35
    private $scope;
36
37 67
    public function __construct(Request $request, Config $config)
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
38
    {
39 67
        $this->request = $request;
40 67
        $this->config = $config;
41 67
    }
42
43
    /**
44
     * Detect the locale from current request url.
45
     * Once the locale has been determined, it will be set as the application locale.
46
     * A locale is only validated if it is present within the current locale scope.
47
     *
48
     * Detection honours following priority:
49
     * 1) If locale is found in request as query parameter e.g. ?locale=fr,
50
     * 2) If locale is found in request url, either from host or segment eg. nl.example.com, example.nl or example.com/nl
51
     * 3) Otherwise set locale to our fallback language (app.locale)
52
     */
53 67
    public function detectLocale(): self
54
    {
55 67
        $locale = null;
56
57
        $detectors = [
58 67
            FallbackDetector::class,
59
            HiddenSegmentDetector::class,
60
            SegmentDetector::class,
61
            QueryDetector::class,
62
        ];
63
64 67
        foreach ($detectors as $detector) {
65 67
            $locale = app($detector)->get($this->getScope(), $this->config) ?? $locale;
66
        }
67
68 67
        $this->locale = $locale;
69
70 67
        $this->setApplicationLocale();
71
72 67
        return $this;
73
    }
74
75 67
    public function getLocale(): Locale
76
    {
77 67
        if (!$this->locale) {
78 67
            $this->detectLocale();
79
        }
80
81 67
        return $this->locale;
82
    }
83
84 67
    public function getScope(): Scope
85
    {
86 67
        if (!$this->scope) {
87 66
            $this->detectScope();
88
        }
89
90 67
        return $this->scope;
91
    }
92
93
    /**
94
     * This is handy for setting allowed scope via other source than config file.
95
     * this can be configurable from a cms.
96
     *
97
     * @param Scope|null $scope
98
     *
99
     * @return $this
100
     */
101 2
    public function setScope(Scope $scope = null)
102
    {
103 2
        if ($scope) {
104 2
            $this->scope = $scope;
105
        }
106
107 2
        return $this;
108
    }
109
110 66
    private function detectScope()
111
    {
112 66
        $this->scope = ScopeCollection::fromConfig($this->config)->findByRoot($this->request->root());
113 66
    }
114
115 67
    private function setApplicationLocale()
116
    {
117 67
        $locale = $this->locale;
118
119 67
        $conversions = $this->config->get('convert_locales_to', []);
120
121 67
        if('auto' === $this->config->get('convert_locales'))
122
        {
123 2
            if(isset($conversions[$locale->get()])){
124 1
                $locale = Locale::from($conversions[$locale->get()]);
125
            }else{
126 2
                $locale = $locale->withoutRegion();
127
            }
128
        }
129 65
        else if(true === $this->config->get('convert_locales'))
130
        {
131 1
            if(isset($conversions[$locale->get()])){
132 1
                $locale = Locale::from($conversions[$locale->get()]);
133
            }
134
        }
135
136 67
        app()->setLocale($locale->get());
137 67
    }
138
}
139