1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Xoops;
13:
14: use Punic\Data;
15: use Punic\Exception\InvalidLocale;
16: use Xoops\Core\HttpRequest;
17: use Xoops\Core\Request;
18: use Xoops\Core\Theme\XoopsTheme;
19:
20: 21: 22: 23: 24: 25: 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: 39: 40: 41:
42: public static function getCurrent()
43: {
44:
45: if (null === static::$currentLocale) {
46: $localeArray = static::getUserLocales();
47: static::$currentLocale = reset($localeArray);
48: }
49: return static::$currentLocale;
50: }
51:
52: 53: 54: 55: 56: 57: 58: 59: 60:
61: public static function setCurrent($locale)
62: {
63: Data::setDefaultLocale($locale);
64: static::$currentLocale = static::normalizeLocale($locale);
65: }
66:
67: 68: 69: 70: 71:
72: public static function getTimeZone()
73: {
74: 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: return static::$currentTimeZone;
87: }
88:
89: 90: 91: 92: 93: 94: 95:
96: public static function setTimeZone(\DateTimeZone $timeZone)
97: {
98: static::$currentTimeZone = $timeZone;
99: }
100:
101: 102: 103: 104: 105: 106: 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: 121: 122: 123:
124: 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: 138: 139: 140:
141: 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: 155: 156: 157: 158: 159: 160: 161:
162: public static function loadLanguage($name, $domain = '', $language = null)
163: {
164: if (empty($name)) {
165: return false;
166: }
167: $language = empty($language) ? \XoopsLocale::getLegacyLanguage() : $language;
168:
169: if ((empty($domain) || 'global' === $domain)) {
170: $path = '';
171: } else {
172: $path = (is_array($domain)) ? array_shift($domain) : "modules/{$domain}";
173: }
174: $xoops = \Xoops::getInstance();
175: $fullPath = $xoops->path("{$path}/language/{$language}/{$name}.php");
176: if (!$ret = \XoopsLoad::loadFile($fullPath)) {
177: $fullPath2 = $xoops->path("{$path}/language/english/{$name}.php");
178: $ret = \XoopsLoad::loadFile($fullPath2);
179: }
180: return $ret;
181: }
182:
183: 184: 185: 186: 187: 188:
189: public static function loadLocale($domain = null, $forcedLocale = null)
190: {
191: $xoops = \Xoops::getInstance();
192:
193: if ($domain === null) {
194: $path = '';
195: $domain = 'xoops';
196: } else {
197: $path = (is_array($domain)) ? array_shift($domain) : "modules/{$domain}";
198: }
199: 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: $locales = self::getUserLocales();
209: $locale = reset($locales);
210: try {
211: Data::setDefaultLocale($locale);
212: } catch (InvalidLocale $e) {
213: $locale = static::FALLBACK_LOCALE;
214: array_shift($locales);
215: array_unshift($locales, $locale);
216: Data::setDefaultLocale($locale);
217: }
218: }
219: foreach ($locales as $locale) {
220: $fullPath = $xoops->path("{$path}/locale/{$locale}/locale.php");
221: $fullPath2 = $xoops->path("{$path}/locale/{$locale}/{$locale}.php");
222: if (\XoopsLoad::fileExists($fullPath)) {
223: \XoopsLoad::addMap(array($domain . 'locale' => $fullPath));
224: if (\XoopsLoad::fileExists($fullPath2)) {
225: \XoopsLoad::addMap(array(strtolower($domain . "locale{$locale}") => $fullPath2));
226: }
227: return true;
228: }
229: }
230: return false;
231: }
232:
233: 234: 235: 236: 237: 238: 239:
240: public static function loadThemeLocale(XoopsTheme $theme)
241: {
242: $xoops = \Xoops::getInstance();
243: $locales = self::getUserLocales();
244: foreach ($locales as $locale) {
245: $fullPath = $xoops->path($theme->resourcePath("locale/{$locale}/locale.php"));
246: $fullPath2 = $xoops->path($theme->resourcePath("locale/{$locale}/{$locale}.php"));
247: if (\XoopsLoad::fileExists($fullPath)) {
248: \XoopsLoad::addMap(array(strtolower($theme->folderName . 'ThemeLocale') => $fullPath));
249: if (\XoopsLoad::fileExists($fullPath2)) {
250: \XoopsLoad::addMap(array(strtolower($theme->folderName . "ThemeLocale{$locale}") => $fullPath2));
251: }
252: return true;
253: }
254: }
255: return false;
256: }
257:
258: 259: 260:
261: public static function loadMailerLocale()
262: {
263: $xoops = \Xoops::getInstance();
264: $locales = self::getUserLocales();
265: foreach ($locales as $locale) {
266: $fullPath = $xoops->path("locale/{$locale}/mailer.php");
267: if (\XoopsLoad::fileExists($fullPath)) {
268: \XoopsLoad::addMap(array(strtolower('XoopsMailerLocale') => $fullPath));
269: return true;
270: }
271: }
272: return false;
273: }
274:
275: 276: 277: 278: 279: 280:
281: public static function translate($key, $dirname = 'xoops')
282: {
283: $class = self::getClassFromDirname($dirname);
284: if (defined("$class::$key")) {
285: return constant("$class::$key");
286: } elseif (defined($key)) {
287: return constant($key);
288: }
289: return $key;
290: }
291:
292: 293: 294: 295: 296: 297:
298: public static function translateTheme($key, $dirname = '')
299: {
300: $class = self::getThemeClassFromDirname($dirname);
301:
302: if (defined("$class::$key")) {
303: return constant("$class::$key");
304: } elseif (defined($key)) {
305: return constant($key);
306: }
307: return $key;
308: }
309:
310: 311: 312: 313: 314:
315: protected static function getClassFromDirname($dirname)
316: {
317: return ucfirst($dirname) . 'Locale';
318: }
319:
320: 321: 322: 323: 324:
325: protected static function getThemeClassFromDirname($dirname = '')
326: {
327: if (!$dirname) {
328: $dirname = \Xoops::getInstance()->theme()->folderName;
329: }
330: return ucfirst($dirname) . 'ThemeLocale';
331: }
332:
333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345:
346: public static function getUserLocales()
347: {
348: if (empty(self::$userLocales)) {
349:
350: $userLocales = array();
351:
352:
353:
354:
355:
356:
357:
358: $requestLocale = self::normalizeLocale(Request::getString('lang', ''));
359: if (!empty($requestLocale)) {
360: $userLocales[] = $requestLocale;
361: }
362:
363:
364: if (isset($_SESSION['lang']) && is_string($_SESSION['lang'])) {
365: $userLocales[] = self::normalizeLocale($_SESSION['lang']);
366: }
367:
368:
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:
381: $userLocales[] = static::FALLBACK_LOCALE;
382:
383: static::$userLocales = array_unique($userLocales);
384: }
385: return static::$userLocales;
386: }
387:
388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399:
400: public static function normalizeLocale($locale, $separator = '_', $withScript = true)
401: {
402: try {
403: $keys = Data::explodeLocale($locale);
404: $key = strtolower($keys['language']);
405: $key .= (empty($keys['script']) || false===$withScript) ?
406: '' : $separator . ucfirst(strtolower($keys['script']));
407: $key .= empty($keys['territory']) ? '' : $separator . strtoupper($keys['territory']);
408: } catch (InvalidLocale $e) {
409: $key = '';
410: }
411:
412: return $key;
413: }
414: }
415: