Passed
Push — master ( 09607c...0eceaa )
by Philippe
01:25
created

Locale::setAvailables()   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 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
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 60
    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 60
        $this->request = $request;
18
19 60
        $this->available_locales = (array) $config['available_locales'];
20 60
        $this->hidden_locale = isset($config['hidden_locale']) ? $config['hidden_locale'] : null;
21 60
        $this->fallback_locale = (isset($config['fallback_locale']) && $config['fallback_locale']) ? $config['fallback_locale'] : config('app.fallback_locale');
22 60
        $this->query_key = isset($config['query_key']) ? $config['query_key'] : null;
23 60
    }
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
     *
31
     * @return $this
32
     */
33 1
    public function setAvailables(array $locales)
34
    {
35 1
        $this->available_locales = $locales;
36
37 1
        return $this;
38
    }
39
40
    /**
41
     * Setup the locale for current request and
42
     * get the locale slug for the route.
43
     *
44
     * @param null $locale
45
     *
46
     * @return null|string
47
     */
48 13
    public function set($locale = null)
49
    {
50 13
        $this->store($locale);
51
52 13
        return $this->getSlug();
53
    }
54
55
    /**
56
     * Get the current locale.
57
     *
58
     * @param null $locale
59
     *
60
     * @return null|string
61
     */
62 52
    public function get($locale = null)
63
    {
64 52
        return $this->validateLocale($locale) ? $locale : app()->getLocale();
65
    }
66
67
    /**
68
     * Get default locale which is useful for providing locale fallback
69
     * TODO: change fallback locale so that it uses the app.locale instead.
70
     *
71
     * @return null|string
72
     */
73 1
    public static function getDefault()
74
    {
75 1
        return config('app.locale');
76
    }
77
78
    /**
79
     * Retrieve the url slug for current or passed locale.
80
     *
81
     * @param null $locale
82
     *
83
     * @return null|string
84
     */
85 51
    public function getSlug($locale = null)
86
    {
87 51
        $locale = $this->get($locale);
88
89 51
        if ($this->hidden_locale == $locale) {
90 36
            return;
91
        }
92
93 44
        return $locale;
94
    }
95
96
    /**
97
     * Check if current or passed locale is set as hidden.
98
     *
99
     * @param null $locale
100
     *
101
     * @return bool
102
     */
103 43
    public function isHidden($locale = null)
104
    {
105
        // If a specific locale string is passed we first validate it represents a valid locale
106 43
        if ($locale && !$this->validateLocale($locale)) {
107 40
            return false;
108
        }
109
110 13
        $locale = $this->get($locale);
111
112 13
        return $this->hidden_locale == $locale;
113
    }
114
115
    /**
116
     * Set locale according to following priority:.
117
     *
118
     * 0) If locale is passed as parameter, this locale will be forced
119
     * 1) If locale is in request as query parameter e.g. ?lang=fr,
120
     * 2) If locale is in request url (subdomain, domain or segment) eg. nl.example.com, example.nl or example.com/nl
121
     * 3) Default: get locale from cookie
122
     * 4) Otherwise: set locale to our fallback language
123
     *
124
     * @param null $locale
125
     *
126
     * @return array|mixed|null|string
127
     */
128 13
    private function store($locale = null)
129
    {
130 13
        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...
131 5
            $locale = $this->fallback_locale;
132
133 5
            if ($this->validateLocale($this->request->cookie('locale'))) {
134 2
                $locale = $this->request->cookie('locale');
135
            }
136
137 5
            if ($locale_from_url = $this->getLocaleFromUrl()) {
138 3
                $locale = $locale_from_url;
139
            }
140
141 5
            if ($this->query_key && ($queryLocale = $this->request->get($this->query_key)) && $this->validateLocale($queryLocale)) {
142 1
                $locale = $queryLocale;
143
            }
144
        }
145
146 13
        app()->setlocale($locale);
147
148 13
        return $locale;
149
    }
150
151
    /**
152
     * @return bool|string
153
     */
154 5
    private function getLocaleFromUrl()
155
    {
156 5
        if ($locale = $this->getLocaleSegment()) {
157 2
            return $locale;
158
        }
159
160
        // At this point is means the url does not contain a specific locale so
161
        // it is assumed the hidden locale is in effect
162 3
        if ($locale = $this->hidden_locale) {
163 1
            return $locale;
164
        }
165
166 2
        return false;
167
    }
168
169 5
    private function getLocaleSegment()
170
    {
171 5
        $segment = $this->request->segment(1);
172
173 5
        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 171 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...
174
    }
175
176
    /**
177
     * @param null $locale
178
     *
179
     * @return bool
180
     */
181 52
    private function validateLocale($locale = null)
182
    {
183 52
        if (!$locale) {
184 37
            return false;
185
        }
186
187 50
        return in_array($locale, $this->available_locales);
188
    }
189
}
190