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