1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
You may not change or alter any portion of this comment or credits |
4
|
|
|
of supporting developers from this source code or any supporting source code |
5
|
|
|
which is considered copyrighted (c) material of the original comment or credit authors. |
6
|
|
|
|
7
|
|
|
This program is distributed in the hope that it will be useful, |
8
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
9
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Xoops; |
13
|
|
|
|
14
|
|
|
use Punic\Data; |
15
|
|
|
use Punic\Exception\InvalidLocale; |
16
|
|
|
use Xoops\Core\HttpRequest; |
17
|
|
|
use Xmf\Request; |
18
|
|
|
use Xoops\Core\Theme\XoopsTheme; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Locale |
22
|
|
|
* |
23
|
|
|
* @author trabis <[email protected]> |
24
|
|
|
* @copyright 2011-2015 XOOPS Project (http://xoops.org) |
25
|
|
|
* @license GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html) |
26
|
|
|
*/ |
27
|
|
|
class Locale |
28
|
|
|
{ |
29
|
|
|
const FALLBACK_LOCALE = 'en_US'; |
30
|
|
|
|
31
|
|
|
protected static $currentLocale = null; |
32
|
|
|
protected static $currentTimeZone = null; |
33
|
|
|
protected static $defaultTimeZone = null; |
34
|
|
|
protected static $systemTimeZone = null; |
35
|
|
|
protected static $userLocales = array(); |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* get the current active locale |
39
|
|
|
* |
40
|
|
|
* @return string current locale |
41
|
|
|
*/ |
42
|
24 |
|
public static function getCurrent() |
43
|
|
|
{ |
44
|
|
|
// if none set, take the top of the user locales |
45
|
24 |
|
if (null === static::$currentLocale) { |
46
|
1 |
|
$localeArray = static::getUserLocales(); |
47
|
1 |
|
static::$currentLocale = reset($localeArray); |
48
|
1 |
|
} |
49
|
24 |
|
return static::$currentLocale; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Set the current locale |
54
|
|
|
* |
55
|
|
|
* @param string $locale local code |
56
|
|
|
* |
57
|
|
|
* @return void |
58
|
|
|
* |
59
|
|
|
* @throws InvalidLocale |
60
|
|
|
*/ |
61
|
53 |
|
public static function setCurrent($locale) |
62
|
|
|
{ |
63
|
53 |
|
Data::setDefaultLocale($locale); |
64
|
53 |
|
static::$currentLocale = static::normalizeLocale($locale); |
65
|
53 |
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Get the current timezone |
69
|
|
|
* |
70
|
|
|
* @return \DateTimeZone current timezone |
71
|
|
|
*/ |
72
|
38 |
|
public static function getTimeZone() |
73
|
|
|
{ |
74
|
38 |
|
if (null === static::$currentTimeZone) { |
75
|
|
|
$xoops = \Xoops::getInstance(); |
76
|
|
|
static::$currentTimeZone = static::getDefaultTimeZone(); |
77
|
|
|
if ($xoops->isUser()) { |
78
|
|
|
$tz = $xoops->user->timezone(); |
79
|
|
|
if (is_a($tz, '\DateTimeZone')) { |
80
|
|
|
static::$currentTimeZone = $tz; |
81
|
|
|
} elseif (is_string($tz)) { |
82
|
|
|
static::$currentTimeZone = static::newDateTimeZone($tz); |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
} |
86
|
38 |
|
return static::$currentTimeZone; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Set the current timezone |
91
|
|
|
* |
92
|
|
|
* @param \DateTimeZone $timeZone |
93
|
|
|
* |
94
|
|
|
* @return void |
95
|
|
|
*/ |
96
|
53 |
|
public static function setTimeZone(\DateTimeZone $timeZone) |
97
|
|
|
{ |
98
|
53 |
|
static::$currentTimeZone = $timeZone; |
99
|
53 |
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Instantiate a new DateTimeZone object for a timezone name, with fallback to UTC on error |
103
|
|
|
* |
104
|
|
|
* @param string $timeZoneName name of timezone |
105
|
|
|
* |
106
|
|
|
* @return \DateTimeZone |
107
|
|
|
*/ |
108
|
|
|
protected static function newDateTimeZone($timeZoneName) |
109
|
|
|
{ |
110
|
|
|
try { |
111
|
|
|
$timeZone = new \DateTimeZone($timeZoneName); |
112
|
|
|
} catch (\Exception $e) { |
113
|
|
|
$timeZone = new \DateTimeZone('UTC'); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
return $timeZone; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Get the default timezone as set in default_TZ config |
121
|
|
|
* |
122
|
|
|
* @return \DateTimeZone |
123
|
|
|
*/ |
124
|
|
View Code Duplication |
public static function getDefaultTimeZone() |
125
|
|
|
{ |
126
|
|
|
if (null === static::$defaultTimeZone) { |
127
|
|
|
$tz = \Xoops::getInstance()->getConfig('default_TZ'); |
128
|
|
|
if (is_numeric($tz)) { |
129
|
|
|
$tz = 'UTC'; |
130
|
|
|
} |
131
|
|
|
static::$defaultTimeZone = static::newDateTimeZone($tz); |
132
|
|
|
} |
133
|
|
|
return static::$defaultTimeZone; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Get the server timezone as set in server_TZ config |
138
|
|
|
* |
139
|
|
|
* @return \DateTimeZone |
140
|
|
|
*/ |
141
|
|
View Code Duplication |
public static function getSystemTimeZone() |
142
|
|
|
{ |
143
|
|
|
if (null === static::$systemTimeZone) { |
144
|
|
|
$tz = \Xoops::getInstance()->getConfig('server_TZ'); |
145
|
|
|
if (is_numeric($tz)) { |
146
|
|
|
$tz = 'UTC'; |
147
|
|
|
} |
148
|
|
|
static::$systemTimeZone = static::newDateTimeZone($tz); |
149
|
|
|
} |
150
|
|
|
return static::$systemTimeZone; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* @param string $name Name of language file to be loaded, without extension |
155
|
|
|
* @param mixed $domain string: Module dirname; global language file will be loaded if |
156
|
|
|
* $domain is set to 'global' or not specified |
157
|
|
|
* array: example; array('Frameworks/moduleclasses/moduleadmin') |
158
|
|
|
* @param string $language Language to be loaded, current language content will be loaded if not specified |
159
|
|
|
* |
160
|
|
|
* @return boolean |
161
|
|
|
*/ |
162
|
1 |
|
public static function loadLanguage($name, $domain = '', $language = null) |
163
|
|
|
{ |
164
|
1 |
|
if (empty($name)) { |
165
|
1 |
|
return false; |
166
|
|
|
} |
167
|
1 |
|
$language = empty($language) ? \XoopsLocale::getLegacyLanguage() : $language; |
168
|
|
|
// expanded domain to multiple categories, e.g. module:system, framework:filter, etc. |
169
|
1 |
View Code Duplication |
if ((empty($domain) || 'global' === $domain)) { |
170
|
1 |
|
$path = ''; |
171
|
1 |
|
} else { |
172
|
|
|
$path = (is_array($domain)) ? array_shift($domain) : "modules/{$domain}"; |
173
|
|
|
} |
174
|
1 |
|
$xoops = \Xoops::getInstance(); |
175
|
1 |
|
$fullPath = $xoops->path("{$path}/language/{$language}/{$name}.php"); |
176
|
1 |
|
if (!$ret = \XoopsLoad::loadFile($fullPath)) { |
177
|
1 |
|
$fullPath2 = $xoops->path("{$path}/language/english/{$name}.php"); |
178
|
1 |
|
$ret = \XoopsLoad::loadFile($fullPath2); |
179
|
1 |
|
} |
180
|
1 |
|
return $ret; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* @param string $domain module dirname to load, if null will load global locale |
185
|
|
|
* @param string $forcedLocale Locale to be loaded, current language content will be loaded if not specified |
186
|
|
|
* |
187
|
|
|
* @return boolean |
188
|
|
|
*/ |
189
|
4 |
|
public static function loadLocale($domain = null, $forcedLocale = null) |
190
|
|
|
{ |
191
|
4 |
|
$xoops = \Xoops::getInstance(); |
192
|
|
|
// expanded domain to multiple categories, e.g. module:system, framework:filter, etc. |
193
|
4 |
View Code Duplication |
if ($domain === null) { |
194
|
1 |
|
$path = ''; |
195
|
1 |
|
$domain = 'xoops'; |
196
|
1 |
|
} else { |
197
|
3 |
|
$path = (is_array($domain)) ? array_shift($domain) : "modules/{$domain}"; |
198
|
|
|
} |
199
|
4 |
|
if (null !== $forcedLocale) { |
200
|
|
|
try { |
201
|
|
|
Data::setDefaultLocale($locale); |
202
|
|
|
} catch (InvalidLocale $e) { |
|
|
|
|
203
|
|
|
return false; |
204
|
|
|
} |
205
|
|
|
$locales = [$forcedLocale]; |
206
|
|
|
$locale = $forcedLocale; |
207
|
|
|
} else { |
208
|
4 |
|
$locales = self::getUserLocales(); |
209
|
4 |
|
$locale = reset($locales); |
210
|
|
|
try { |
211
|
4 |
|
Data::setDefaultLocale($locale); |
212
|
4 |
|
} catch (InvalidLocale $e) { |
|
|
|
|
213
|
|
|
$locale = static::FALLBACK_LOCALE; |
214
|
|
|
array_shift($locales); |
215
|
|
|
array_unshift($locales, $locale); |
216
|
|
|
Data::setDefaultLocale($locale); |
217
|
|
|
} |
218
|
|
|
} |
219
|
4 |
|
foreach ($locales as $locale) { |
220
|
4 |
|
$fullPath = $xoops->path("{$path}/locale/{$locale}/locale.php"); |
221
|
4 |
|
$fullPath2 = $xoops->path("{$path}/locale/{$locale}/{$locale}.php"); |
222
|
4 |
View Code Duplication |
if (\XoopsLoad::fileExists($fullPath)) { |
223
|
4 |
|
\XoopsLoad::addMap(array($domain . 'locale' => $fullPath)); |
224
|
4 |
|
if (\XoopsLoad::fileExists($fullPath2)) { |
225
|
4 |
|
\XoopsLoad::addMap(array(strtolower($domain . "locale{$locale}") => $fullPath2)); |
226
|
4 |
|
} |
227
|
4 |
|
return true; |
228
|
|
|
} |
229
|
4 |
|
} |
230
|
|
|
return false; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* load locale for theme |
235
|
|
|
* |
236
|
|
|
* @param XoopsTheme $theme |
237
|
|
|
* |
238
|
|
|
* @return bool |
239
|
|
|
*/ |
240
|
4 |
|
public static function loadThemeLocale(XoopsTheme $theme) |
241
|
|
|
{ |
242
|
4 |
|
$xoops = \Xoops::getInstance(); |
243
|
4 |
|
$locales = self::getUserLocales(); |
244
|
4 |
|
foreach ($locales as $locale) { |
245
|
4 |
|
$fullPath = $xoops->path($theme->resourcePath("locale/{$locale}/locale.php")); |
246
|
4 |
|
$fullPath2 = $xoops->path($theme->resourcePath("locale/{$locale}/{$locale}.php")); |
247
|
4 |
View Code Duplication |
if (\XoopsLoad::fileExists($fullPath)) { |
248
|
4 |
|
\XoopsLoad::addMap(array(strtolower($theme->folderName . 'ThemeLocale') => $fullPath)); |
249
|
4 |
|
if (\XoopsLoad::fileExists($fullPath2)) { |
250
|
4 |
|
\XoopsLoad::addMap(array(strtolower($theme->folderName . "ThemeLocale{$locale}") => $fullPath2)); |
251
|
4 |
|
} |
252
|
4 |
|
return true; |
253
|
|
|
} |
254
|
4 |
|
} |
255
|
|
|
return false; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* @return boolean |
260
|
|
|
*/ |
261
|
2 |
|
public static function loadMailerLocale() |
262
|
|
|
{ |
263
|
2 |
|
$xoops = \Xoops::getInstance(); |
264
|
2 |
|
$locales = self::getUserLocales(); |
265
|
2 |
|
foreach ($locales as $locale) { |
266
|
2 |
|
$fullPath = $xoops->path("locale/{$locale}/mailer.php"); |
267
|
2 |
|
if (\XoopsLoad::fileExists($fullPath)) { |
268
|
2 |
|
\XoopsLoad::addMap(array(strtolower('XoopsMailerLocale') => $fullPath)); |
269
|
2 |
|
return true; |
270
|
|
|
} |
271
|
2 |
|
} |
272
|
|
|
return false; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* @param string $key |
277
|
|
|
* @param string $dirname |
278
|
|
|
* |
279
|
|
|
* @return string |
280
|
|
|
*/ |
281
|
3 |
View Code Duplication |
public static function translate($key, $dirname = 'xoops') |
282
|
|
|
{ |
283
|
3 |
|
$class = self::getClassFromDirname($dirname); |
284
|
3 |
|
if (defined("$class::$key")) { |
285
|
1 |
|
return constant("$class::$key"); |
286
|
2 |
|
} elseif (defined($key)) { |
287
|
|
|
return constant($key); |
288
|
|
|
} |
289
|
2 |
|
return $key; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* @param string $key |
294
|
|
|
* @param string $dirname |
295
|
|
|
* |
296
|
|
|
* @return string |
297
|
|
|
*/ |
298
|
1 |
View Code Duplication |
public static function translateTheme($key, $dirname = '') |
299
|
|
|
{ |
300
|
1 |
|
$class = self::getThemeClassFromDirname($dirname); |
301
|
|
|
|
302
|
1 |
|
if (defined("$class::$key")) { |
303
|
|
|
return constant("$class::$key"); |
304
|
1 |
|
} elseif (defined($key)) { |
305
|
|
|
return constant($key); |
306
|
|
|
} |
307
|
1 |
|
return $key; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* @param string $dirname |
312
|
|
|
* |
313
|
|
|
* @return string |
314
|
|
|
*/ |
315
|
3 |
|
protected static function getClassFromDirname($dirname) |
316
|
|
|
{ |
317
|
3 |
|
return ucfirst($dirname) . 'Locale'; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* @param string $dirname |
322
|
|
|
* |
323
|
|
|
* @return string |
324
|
|
|
*/ |
325
|
1 |
|
protected static function getThemeClassFromDirname($dirname = '') |
326
|
|
|
{ |
327
|
1 |
|
if (!$dirname) { |
328
|
1 |
|
$dirname = \Xoops::getInstance()->theme()->folderName; |
329
|
1 |
|
} |
330
|
1 |
|
return ucfirst($dirname) . 'ThemeLocale'; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* getUserLocales() |
335
|
|
|
* Returns the user locales |
336
|
|
|
* Normally it returns an array like this: |
337
|
|
|
* 1. Forced language |
338
|
|
|
* 2. Language in $_GET['lang'] |
339
|
|
|
* 3. Language in $_SESSION['lang'] |
340
|
|
|
* 4. HTTP_ACCEPT_LANGUAGE |
341
|
|
|
* 5. Fallback language |
342
|
|
|
* Note: duplicate values are deleted. |
343
|
|
|
* |
344
|
|
|
* @return array with the user locales sorted by priority. Highest is best. |
345
|
|
|
*/ |
346
|
10 |
|
public static function getUserLocales() |
|
|
|
|
347
|
|
|
{ |
348
|
10 |
|
if (empty(self::$userLocales)) { |
349
|
|
|
// reset user_lang array |
350
|
|
|
$userLocales = array(); |
351
|
|
|
|
352
|
|
|
// Highest priority: forced language |
353
|
|
|
//if ($this->forcedLang != NULL) { |
354
|
|
|
// $userLocales[] = $this->forcedLang; |
355
|
|
|
//} |
356
|
|
|
|
357
|
|
|
// 2nd highest priority: GET parameter 'lang' |
358
|
|
|
$requestLocale = self::normalizeLocale(Request::getString('lang', '')); |
359
|
|
|
if (!empty($requestLocale)) { |
360
|
|
|
$userLocales[] = $requestLocale; |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
// 3rd highest priority: SESSION parameter 'lang' |
364
|
|
|
if (isset($_SESSION['lang']) && is_string($_SESSION['lang'])) { |
365
|
|
|
$userLocales[] = self::normalizeLocale($_SESSION['lang']); |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
// 4th highest priority: HTTP_ACCEPT_LANGUAGE |
369
|
|
|
$browserLocales = HttpRequest::getInstance()->getAcceptedLanguages(); |
370
|
|
|
$browserLocales = array_keys($browserLocales); |
371
|
|
|
foreach ($browserLocales as $bloc) { |
372
|
|
|
$userLocales[] = self::normalizeLocale($bloc); |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
$configLocale = \Xoops::getInstance()->getConfig('locale'); |
376
|
|
|
if (!empty($configLocale)) { |
377
|
|
|
$userLocales[] = $configLocale; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
// Lowest priority: fallback |
381
|
|
|
$userLocales[] = static::FALLBACK_LOCALE; |
382
|
|
|
|
383
|
|
|
static::$userLocales = array_unique($userLocales); |
384
|
|
|
} |
385
|
10 |
|
return static::$userLocales; |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
/** |
389
|
|
|
* Convert a locale designation to a normal form ll_Ssss_CC, where |
390
|
|
|
* ll is language code |
391
|
|
|
* Ssss is the script code, if specified |
392
|
|
|
* CC is the country code, if specified |
393
|
|
|
* |
394
|
|
|
* @param string $locale locale code |
395
|
|
|
* @param string $separator string to use to join locale parts |
396
|
|
|
* @param bool $withScript include script if specified, always remove if false |
397
|
|
|
* |
398
|
|
|
* @return string normalized locale, or empty string on error |
399
|
|
|
*/ |
400
|
68 |
|
public static function normalizeLocale($locale, $separator = '_', $withScript = true) |
401
|
|
|
{ |
402
|
|
|
try { |
403
|
68 |
|
$keys = Data::explodeLocale($locale); |
404
|
68 |
|
$key = strtolower($keys['language']); |
405
|
68 |
|
$key .= (empty($keys['script']) || false===$withScript) ? |
406
|
68 |
|
'' : $separator . ucfirst(strtolower($keys['script'])); |
407
|
68 |
|
$key .= empty($keys['territory']) ? '' : $separator . strtoupper($keys['territory']); |
408
|
68 |
|
} catch (InvalidLocale $e) { |
|
|
|
|
409
|
|
|
$key = ''; |
410
|
|
|
} |
411
|
|
|
|
412
|
68 |
|
return $key; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Return a normalized form of a resource domain. A resource domain is always lowercase. |
417
|
|
|
* |
418
|
|
|
* @param string $domain resource domain (usually a module dirname) |
419
|
|
|
* |
420
|
|
|
* @return string normalized resource domain |
421
|
|
|
*/ |
422
|
|
|
public static function normalizeDomain($domain) |
423
|
|
|
{ |
424
|
|
|
return strtolower($domain); |
425
|
|
|
} |
426
|
|
|
} |
427
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.