Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
80.56% |
29 / 36 |
|
69.23% |
9 / 13 |
CRAP | |
0.00% |
0 / 1 |
LocaleSettings | |
80.56% |
29 / 36 |
|
69.23% |
9 / 13 |
21.65 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
browserLanguageDetectionEnabled | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isRightToLeftLocale | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getUserLocale | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getDefaultLocale | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getEnabledLocales | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFallbackLocales | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRightToLeftLocales | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
parseDefaultLocale | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
parseFallbackLocales | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
parseRightToLeftLocales | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
markLocaleInitialized | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isLocaleInitialized | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | /** |
4 | * VuFind Locale Settings |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2018, |
9 | * Copyright (C) Leipzig University Library <info@ub.uni-leipzig.de> 2018. |
10 | * Copyright (C) The National Library of Finland 2023. |
11 | * |
12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2, |
14 | * as published by the Free Software Foundation. |
15 | * |
16 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. |
20 | * |
21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
24 | * |
25 | * @category VuFind |
26 | * @package I18n\Locale |
27 | * @author Demian Katz <demian.katz@villanova.edu> |
28 | * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> |
29 | * @author Ere Maijala <ere.maijala@helsinki.fi> |
30 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
31 | * @link https://vufind.org Main Site |
32 | */ |
33 | |
34 | namespace VuFind\I18n\Locale; |
35 | |
36 | use Laminas\Config\Config; |
37 | |
38 | use function array_key_exists; |
39 | use function in_array; |
40 | |
41 | /** |
42 | * VuFind Locale Settings |
43 | * |
44 | * @category VuFind |
45 | * @package I18n\Locale |
46 | * @author Demian Katz <demian.katz@villanova.edu> |
47 | * @author Sebastian Kehr <kehr@ub.uni-leipzig.de> |
48 | * @author Ere Maijala <ere.maijala@helsinki.fi> |
49 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
50 | * @link https://vufind.org Main Site |
51 | */ |
52 | class LocaleSettings |
53 | { |
54 | /** |
55 | * Default locale (code) |
56 | * |
57 | * @var string |
58 | */ |
59 | protected $defaultLocale; |
60 | |
61 | /** |
62 | * Associative (code => description) array of enabled locales. |
63 | * |
64 | * @var array |
65 | */ |
66 | protected $enabledLocales; |
67 | |
68 | /** |
69 | * Prioritized array of locales to use when strings are missing from the |
70 | * primary language file. |
71 | * |
72 | * @var string[] |
73 | */ |
74 | protected $fallbackLocales; |
75 | |
76 | /** |
77 | * Array of locales that use right-to-left formatting. |
78 | * |
79 | * @var string[] |
80 | */ |
81 | protected $rightToLeftLocales; |
82 | |
83 | /** |
84 | * Array of locales that have been initialized. |
85 | * |
86 | * @var string[] |
87 | */ |
88 | protected $initializedLocales = []; |
89 | |
90 | /** |
91 | * Should we use auto-detect language based on browser settings? |
92 | * |
93 | * @var bool |
94 | */ |
95 | protected $browserDetectLanguage; |
96 | |
97 | /** |
98 | * Constructor |
99 | * |
100 | * @param Config $config Configuration object |
101 | */ |
102 | public function __construct(Config $config) |
103 | { |
104 | $this->enabledLocales = $config->Languages ? $config->Languages->toArray() |
105 | : []; |
106 | $this->browserDetectLanguage |
107 | = (bool)($config->Site->browserDetectLanguage ?? true); |
108 | $this->defaultLocale = $this->parseDefaultLocale($config); |
109 | $this->fallbackLocales = $this->parseFallbackLocales($config); |
110 | $this->rightToLeftLocales = $this->parseRightToLeftLocales($config); |
111 | } |
112 | |
113 | /** |
114 | * Should we use auto-detect language based on browser settings? |
115 | * |
116 | * @return bool |
117 | */ |
118 | public function browserLanguageDetectionEnabled(): bool |
119 | { |
120 | return $this->browserDetectLanguage; |
121 | } |
122 | |
123 | /** |
124 | * Identify whether a particular locale uses right-to-left layout. |
125 | * |
126 | * @param string $locale Locale to check |
127 | * |
128 | * @return bool |
129 | */ |
130 | public function isRightToLeftLocale(string $locale): bool |
131 | { |
132 | return in_array($locale, $this->rightToLeftLocales); |
133 | } |
134 | |
135 | /** |
136 | * Get the current active locale. |
137 | * |
138 | * @return string |
139 | */ |
140 | public function getUserLocale(): string |
141 | { |
142 | if (!class_exists(\Locale::class)) { |
143 | error_log('Locale class is missing; please enable intl extension.'); |
144 | return $this->getDefaultLocale(); |
145 | } |
146 | return \Locale::getDefault(); |
147 | } |
148 | |
149 | /** |
150 | * Get default locale. |
151 | * |
152 | * @return string |
153 | */ |
154 | public function getDefaultLocale(): string |
155 | { |
156 | return $this->defaultLocale; |
157 | } |
158 | |
159 | /** |
160 | * Get an associative (code => description) array of enabled locales. |
161 | * |
162 | * @return array |
163 | */ |
164 | public function getEnabledLocales(): array |
165 | { |
166 | return $this->enabledLocales; |
167 | } |
168 | |
169 | /** |
170 | * Get a prioritized array of locales to use when strings are missing from the |
171 | * primary language file. |
172 | * |
173 | * @return string[] |
174 | */ |
175 | public function getFallbackLocales(): array |
176 | { |
177 | return $this->fallbackLocales; |
178 | } |
179 | |
180 | /** |
181 | * Get an array of locales that use right-to-left formatting. |
182 | * |
183 | * @return string[] |
184 | */ |
185 | public function getRightToLeftLocales(): array |
186 | { |
187 | return $this->rightToLeftLocales; |
188 | } |
189 | |
190 | /** |
191 | * Extract and validate default locale from configuration. |
192 | * |
193 | * @param Config $config Configuration |
194 | * |
195 | * @return string |
196 | * @throws \Exception |
197 | */ |
198 | protected function parseDefaultLocale(Config $config): string |
199 | { |
200 | $locale = $config->Site->language ?? null; |
201 | if (empty($locale)) { |
202 | throw new \Exception('Default locale not configured!'); |
203 | } |
204 | if (!array_key_exists($locale, $this->enabledLocales)) { |
205 | throw new \Exception("Configured default locale '$locale' not enabled!"); |
206 | } |
207 | return $locale; |
208 | } |
209 | |
210 | /** |
211 | * Parses the configured language fallbacks. |
212 | * |
213 | * @param Config $config Configuration |
214 | * |
215 | * @return string[] |
216 | */ |
217 | protected function parseFallbackLocales(Config $config): array |
218 | { |
219 | $value = trim($config->Site->fallback_languages ?? '', ','); |
220 | $languages = $value ? array_map('trim', explode(',', $value)) : []; |
221 | return array_unique( |
222 | [ |
223 | ...$languages, |
224 | $config->Site->language, |
225 | 'en', |
226 | ] |
227 | ); |
228 | } |
229 | |
230 | /** |
231 | * Parses the right-to-left language configuration. |
232 | * |
233 | * @param Config $config Configuration |
234 | * |
235 | * @return string[] |
236 | */ |
237 | protected function parseRightToLeftLocales(Config $config): array |
238 | { |
239 | $value = trim($config->LanguageSettings->rtl_langs ?? '', ','); |
240 | return $value ? array_map('trim', explode(',', $value)) : []; |
241 | } |
242 | |
243 | /** |
244 | * Mark a locale as initialized. |
245 | * |
246 | * @param string $locale Locale code |
247 | * |
248 | * @return void |
249 | */ |
250 | public function markLocaleInitialized($locale) |
251 | { |
252 | $this->initializedLocales[] = $locale; |
253 | } |
254 | |
255 | /** |
256 | * Is the locale already initialized? |
257 | * |
258 | * @param string $locale Locale code |
259 | * |
260 | * @return bool |
261 | */ |
262 | public function isLocaleInitialized($locale) |
263 | { |
264 | return in_array($locale, $this->initializedLocales); |
265 | } |
266 | } |