Completed
Push — master ( 9d6651...260952 )
by
unknown
12:18
created

Locale::getDefault()   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 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Locale;
4
5
use Illuminate\Http\Request;
6
7
class Locale
8
{
9
    private $request;
10
    private $available_locales;
11
    private $hidden_locale;
12
    private $fallback_locale;
13
    private $query_key;
14
15 59
    public function __construct(Request $request, $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...
16
    {
17 59
        $this->request = $request;
18
19 59
        $this->available_locales = (array) $config['available_locales'];
20 59
        $this->hidden_locale = isset($config['hidden_locale']) ? $config['hidden_locale'] : null;
21 59
        $this->fallback_locale = (isset($config['fallback_locale']) && $config['fallback_locale']) ? $config['fallback_locale'] : config('app.fallback_locale');
22 59
        $this->query_key = isset($config['query_key']) ? $config['query_key'] : null;
23 59
    }
24
25
    /**
26
     * Define the list of available locales.
27
     * This way the developer can set his own curated list of locales.
28
     *
29
     * @param array $locales
30
     * @return $this
31
     */
32 1
    public function setAvailables(array $locales)
33
    {
34 1
        $this->available_locales = $locales;
35
36 1
        return $this;
37
    }
38
39
    /**
40
     * Setup the locale for current request and
41
     * get the locale slug for the route.
42
     *
43
     * @param null $locale
44
     *
45
     * @return null|string
46
     */
47 13
    public function set($locale = null)
48
    {
49 13
        $this->store($locale);
50
51 13
        return $this->getSlug();
52
    }
53
54
    /**
55
     * Get the current locale.
56
     *
57
     * @param null $locale
58
     *
59
     * @return null|string
60
     */
61 52
    public function get($locale = null)
62
    {
63 52
        return $this->validateLocale($locale) ? $locale : app()->getLocale();
64
    }
65
66
    /**
67
     * @return null|string
68
     */
69
    public static function getDefault() :? string
70
    {
71
        return config('app.locale');
72
    }
73 51
74
    /**
75 51
     * Retrieve the url slug for current or passed locale.
76
     *
77 51
     * @param null $locale
78 36
     *
79
     * @return null|string
80
     */
81 44
    public function getSlug($locale = null)
82
    {
83
        $locale = $this->get($locale);
84
85
        if ($this->hidden_locale == $locale) {
86
            return;
87
        }
88
89
        return $locale;
90
    }
91 43
92
    /**
93
     * Check if current or passed locale is set as hidden.
94 43
     *
95 40
     * @param null $locale
96
     *
97
     * @return bool
98 13
     */
99
    public function isHidden($locale = null)
100 13
    {
101
        // If a specific locale string is passed we first validate it represents a valid locale
102
        if ($locale && !$this->validateLocale($locale)) {
103
            return false;
104
        }
105
106
        $locale = $this->get($locale);
107
108
        return $this->hidden_locale == $locale;
109
    }
110
111
    /**
112
     * Set locale according to following priority:.
113
     *
114
     * 0) If locale is passed as parameter, this locale will be forced
115
     * 1) If locale is in request as query parameter e.g. ?lang=fr,
116 13
     * 2) If locale is in request url (subdomain, domain or segment) eg. nl.example.com, example.nl or example.com/nl
117
     * 3) Default: get locale from cookie
118 13
     * 4) Otherwise: set locale to our fallback language
119 5
     *
120
     * @param null $locale
121 5
     *
122 2
     * @return array|mixed|null|string
123
     */
124
    private function store($locale = null)
125 5
    {
126 3
        if (!$locale or !in_array($locale, $this->available_locales)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
127
            $locale = $this->fallback_locale;
128
129 5
            if ($this->validateLocale($this->request->cookie('locale'))) {
130 1
                $locale = $this->request->cookie('locale');
131
            }
132
133
            if ($locale_from_url = $this->getLocaleFromUrl()) {
134 13
                $locale = $locale_from_url;
135
            }
136 13
137
            if ($this->query_key && ($queryLocale = $this->request->get($this->query_key)) && $this->validateLocale($queryLocale)) {
138
                $locale = $queryLocale;
139
            }
140
        }
141
142 5
        app()->setlocale($locale);
143
144 5
        return $locale;
145 2
    }
146
147
    /**
148
     * @return bool|string
149
     */
150 3
    private function getLocaleFromUrl()
151 1
    {
152
        if ($locale = $this->getLocaleSegment()) {
153
            return $locale;
154 2
        }
155
156
        // At this point is means the url does not contain a specific locale so
157 5
        // it is assumed the hidden locale is in effect
158
        if ($locale = $this->hidden_locale) {
159 5
            return $locale;
160
        }
161 5
162
        return false;
163
    }
164
165
    private function getLocaleSegment()
166
    {
167
        $segment = $this->request->segment(1);
168
169 52
        return ($this->validateLocale($segment)) ? $segment : false;
0 ignored issues
show
Bug introduced by
It seems like $segment defined by $this->request->segment(1) on line 167 can also be of type string; however, Thinktomorrow\Locale\Locale::validateLocale() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
170
    }
171 52
172 37
    /**
173
     * @param null $locale
174
     *
175 50
     * @return bool
176
     */
177
    private function validateLocale($locale = null)
178
    {
179
        if (!$locale) {
180
            return false;
181
        }
182
183
        return in_array($locale, $this->available_locales);
184
    }
185
}
186