Completed
Push — master ( f0cb91...c4f1d3 )
by Ivan
02:22
created

BrowserLocale::getLocales()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace CodeZero\BrowserLocale;
4
5
use CodeZero\BrowserLocale\Filters\Filter;
6
7
class BrowserLocale
8
{
9
    /**
10
     * Array of \CodeZero\BrowserLocale\Locale instances.
11
     *
12
     * @var array
13
     */
14
    protected $locales = [];
15
16
    /**
17
     * Create a new BrowserLocale instance.
18
     *
19
     * @param string $httpAcceptLanguages
20
     */
21 10
    public function __construct($httpAcceptLanguages)
22
    {
23 10
        $this->parseHttpAcceptLanguages($httpAcceptLanguages);
24 10
    }
25
26
    /**
27
     * Get the most preferred locale.
28
     *
29
     * @return \CodeZero\BrowserLocale\Locale|null
30
     */
31 4
    public function getLocale()
32
    {
33 4
        return $this->locales[0] ?? null;
34
    }
35
36
    /**
37
     * Get an array of Locale objects in descending order of preference.
38
     *
39
     * @return array
40
     */
41 3
    public function getLocales()
42
    {
43 3
        return $this->locales;
44
    }
45
46
    /**
47
     * Filter the locales using the given Filter.
48
     *
49
     * @param \CodeZero\BrowserLocale\Filters\Filter $filter
50
     *
51
     * @return array
52
     */
53 5
    public function filter(Filter $filter)
54
    {
55 5
        return $filter->filter($this->locales);
56
    }
57
58
    /**
59
     * Parse all HTTP Accept Languages.
60
     *
61
     * @param string $httpAcceptLanguages
62
     *
63
     * @return void
64
     */
65 10
    protected function parseHttpAcceptLanguages($httpAcceptLanguages)
66
    {
67 10
        $locales = $this->split($httpAcceptLanguages, ',');
68
69 10
        foreach ($locales as $httpAcceptLanguage) {
70 10
            $this->makeLocale($httpAcceptLanguage);
71
        }
72
73 10
        $this->sortLocales();
74 10
    }
75
76
    /**
77
     * Convert the given HTTP Accept Language to a Locale object.
78
     *
79
     * @param string $httpAcceptLanguage
80
     *
81
     * @return void
82
     */
83 10
    protected function makeLocale($httpAcceptLanguage)
84
    {
85 10
        $parts = $this->split($httpAcceptLanguage, ';');
86
87 10
        $locale = $parts[0];
88 10
        $weight = $parts[1] ?? null;
89
90 10
        if (empty($locale)) {
91 2
            return;
92
        }
93
94 8
        $this->locales[] = new Locale(
95 8
            $locale,
96 8
            $this->getLanguage($locale),
97 8
            $this->getCountry($locale),
98 8
            $this->getWeight($weight)
99
        );
100 8
    }
101
102
    /**
103
     * Split the given string by the delimiter.
104
     *
105
     * @param string $string
106
     * @param string $delimiter
107
     *
108
     * @return array
109
     */
110 10
    protected function split($string, $delimiter)
111
    {
112 10
        return explode($delimiter, trim($string)) ?: [];
113
    }
114
115
    /**
116
     * Get the 2-letter language code from the locale.
117
     *
118
     * @param string $locale
119
     *
120
     * @return string
121
     */
122 8
    protected function getLanguage($locale)
123
    {
124 8
        return substr($locale, 0, 2) ?: '';
125
    }
126
127
    /**
128
     * Get the 2-letter country code from the locale.
129
     *
130
     * @param string $locale
131
     *
132
     * @return string
133
     */
134 8
    protected function getCountry($locale)
135
    {
136 8
        return substr($locale, 3, 2) ?: '';
137
    }
138
139
    /**
140
     * Parse the relative quality factor and return its value.
141
     *
142
     * @param string $q
143
     *
144
     * @return float
145
     */
146 8
    protected function getWeight($q)
147
    {
148 8
        $parts = $this->split($q, '=');
149
150 8
        $weight = $parts[1] ?? 1.0;
151
152 8
        return (float) $weight;
153
    }
154
155
    /**
156
     * Sort the array of locales in descending order of preference.
157
     *
158
     * @return void
159
     */
160
    protected function sortLocales()
161
    {
162 10
        usort($this->locales, function ($a, $b) {
163 8
            if ($a->weight === $b->weight) {
164 1
                return 0;
165
            }
166
167 8
            return ($a->weight > $b->weight) ? -1 : 1;
168 10
        });
169 10
    }
170
}
171