12 private static $currentLang =
null;
13 private static $messages = array();
14 private static $customMessages = array();
15 private static $userMessages = array();
16 private static $includedFiles = array();
17 private static $lazyLoadFiles = array();
18 private static $triedFiles = array();
29 public static function getMessage($code, $replace =
null, $language =
null)
31 if($language ===
null)
34 if(self::$currentLang ===
null)
40 $language = self::$currentLang;
44 if(!isset(self::$messages[$language][$code]))
46 self::loadLazy($code, $language);
49 $s = self::$messages[$language][$code] ??
null;
51 if (is_array($replace) && $s !==
null)
53 $s = strtr($s, $replace);
66 if(($realPath = realpath($file)) !==
false)
70 $file = Path::normalize($file);
72 self::$lazyLoadFiles[$file] = $file;
80 if(self::$currentLang ===
null)
85 $language = $context->getLanguage();
86 if($language !==
null)
88 self::$currentLang = $language;
92 return (self::$currentLang !==
null? self::$currentLang :
'en');
97 self::$currentLang = $language;
109 private static function includeLangFiles($file, $language, &$loadedLangFile)
111 static $langDirCache = array();
114 static $openBasedir = [], $openBasedirRestriction;
115 if ($openBasedirRestriction ===
null)
117 $openBasedirTmp = ini_get(
'open_basedir');
118 if (!empty($openBasedirTmp))
122 $openBasedirTmp = explode(
123 (strncasecmp(PHP_OS,
'WIN', 3) == 0 ?
';' :
':'),
126 foreach ($openBasedirTmp as $testDir)
128 if (!empty($testDir))
130 $testDir = Path::normalize($testDir);
131 if (is_dir($testDir))
133 $openBasedir[] = $testDir;
138 $openBasedirRestriction = !empty($openBasedir);
141 $path = Path::getDirectory($file);
143 if(isset($langDirCache[$path]))
145 $langDir = $langDirCache[$path];
146 $fileName = mb_substr($file, (mb_strlen($langDir) - 5));
151 $langDir = $fileName =
'';
153 while (($slashPos = mb_strrpos($filePath,
'/')) !==
false)
155 $filePath = mb_substr($filePath, 0, $slashPos);
156 if ($openBasedirRestriction ===
true)
158 $withinOpenBasedir =
false;
159 foreach ($openBasedir as $testDir)
161 if (stripos($filePath, $testDir) === 0)
163 $withinOpenBasedir =
true;
167 if (!$withinOpenBasedir)
172 $langPath = $filePath.
'/lang';
173 if (is_dir($langPath))
175 $langDir = $langPath;
176 $fileName = mb_substr($file, $slashPos);
177 $langDirCache[$path] = $langDir;
188 if($defaultLang <> $language)
190 $langFile = $langDir.
'/'. $defaultLang. $fileName;
194 if(file_exists($langFile))
196 $mess = self::includeFile($langFile);
197 $loadedLangFile = $langFile;
202 $langFile = $langDir.
'/'. $language. $fileName;
206 if(file_exists($langFile))
208 $mess = array_merge($mess, self::includeFile($langFile));
209 $loadedLangFile = $langFile;
226 if($language ===
null)
233 $file = Path::normalize($file);
236 if(!isset(self::$messages[$language]))
238 self::$messages[$language] = array();
242 if(!isset(self::$userMessages[$language]))
244 self::$userMessages[$language] = self::loadUserMessages($language);
248 $mess = self::includeLangFiles($file, $language, $langFile);
254 foreach ($mess as $key => $val)
256 if (isset(self::$customMessages[$language][$key]))
258 self::$messages[$language][$key] = $mess[$key] = self::$customMessages[$language][$key];
262 if ($convertEncoding)
264 if ($targetEncoding !==
'utf-8' || !preg_match(
'//u', $val))
266 $val = Encoding::convertEncoding($val, $sourceEncoding, $targetEncoding);
271 self::$messages[$language][$key] = $val;
287 if($language ===
null)
292 if(!isset(self::$customMessages[$language]))
294 self::$customMessages[$language] = array();
298 $mess = self::includeLangFiles(Path::normalize($file), $language, $langFile);
304 foreach ($mess as $key => $val)
306 if ($convertEncoding)
308 if ($targetEncoding !==
'utf-8' || !preg_match(
'//u', $val))
310 $val = Encoding::convertEncoding($val, $sourceEncoding, $targetEncoding);
315 self::$customMessages[$language][$key] = $val;
320 private static function loadLazy($code, $language)
328 if(!isset(self::$triedFiles[$language]))
330 self::$triedFiles[$language] = [];
333 $trace = Main\Diag\Helper::getBackTrace(4, DEBUG_BACKTRACE_IGNORE_ARGS);
336 for($i = 3; $i >= 1; $i--)
338 if (isset($trace[$i]) && stripos($trace[$i][
"function"],
"GetMessage") === 0)
340 $currentFile = Path::normalize($trace[$i][
"file"]);
343 self::$lazyLoadFiles[$currentFile] = $currentFile;
348 if($currentFile !==
null && isset(self::$lazyLoadFiles[$currentFile]))
351 if(!isset(self::$triedFiles[$language][$currentFile]))
354 self::$triedFiles[$language][$currentFile] =
true;
356 unset(self::$lazyLoadFiles[$currentFile]);
359 if(!isset(self::$messages[$language][$code]))
363 if(($file = end(self::$lazyLoadFiles)) !==
false)
367 if(!isset(self::$triedFiles[$language][$file]))
370 self::$triedFiles[$language][$file] =
true;
374 if(isset(self::$messages[$language][$code]))
376 if(defined(
"BX_MESS_LOG") && $currentFile !==
null)
378 file_put_contents(BX_MESS_LOG,
'CTranslateUtils::CopyMessage("'.$code.
'", "'.$file.
'", "'.$currentFile.
'");'.
"\n", FILE_APPEND);
383 while(($file = prev(self::$lazyLoadFiles)) !==
false);
385 foreach($unset as $file)
387 unset(self::$lazyLoadFiles[$file]);
391 if(!isset(self::$messages[$language][$code]) && defined(
"BX_MESS_LOG"))
393 file_put_contents(BX_MESS_LOG, $code.
": not found for ".$currentFile.
"\n", FILE_APPEND);
403 private static function loadUserMessages($lang)
406 $documentRoot = Main\Application::getDocumentRoot();
407 if(($fname = Main\
Loader::getLocal(
"php_interface/user_lang/".$lang.
"/lang.php", $documentRoot)) !==
false)
409 $mess = self::includeFile($fname);
413 foreach($mess as $key => $val)
414 $userMess[str_replace(
"\\",
"/", realpath($documentRoot.$key))] = $val;
425 private static function includeFile($path)
427 self::$includedFiles[$path] = $path;
434 if(!empty(self::$userMessages))
436 $path = str_replace(
"\\",
"/", realpath($path));
439 foreach(self::$userMessages as $messages)
441 if(isset($messages[$path]) && is_array($messages[$path]))
443 foreach($messages[$path] as $key => $val)
462 static $subst = [
'ua' =>
'en',
'kz' =>
'ru',
'by' =>
'ru',
'ru' =>
'ru',
'en' =>
'en',
'de' =>
'en'];
463 if(isset($subst[$lang]))
465 return $subst[$lang];
468 $options = Configuration::getValue(
"default_language");
469 if(isset($options[$lang]))
471 return $options[$lang];
483 return self::$includedFiles;
504 public static function getMessagePlural(
string $code,
int $value, array $replace =
null,
string $language =
null): ?string
506 $language = (string)$language;
507 if ($language ===
'')
509 $language = LANGUAGE_ID;
512 $result =
self::getMessage($code .
'_PLURAL_' . self::getPluralForm($value, $language), $replace);
513 if ($result ===
null)
530 $value = (int)$value;
531 $language = (string)$language;
532 if ($language ===
'')
534 $language = LANGUAGE_ID;
539 $value = (-1) * $value;
545 $pluralForm = (($value !== 1) ? 1 : 0);
580 $pluralForm = (($value > 1) ? 1 : 0);
588 $pluralForm = (($value !== 1) ? 1 : 0);
595 && ($value % 100 !== 11)
602 && ($value % 10 <= 4)
605 || ($value % 100 >= 20)
627 || $value % 100 >= 20
static getLocal($path, $root=null)
static loadLanguageFile($file, $language=null, $normalize=true)
static getPluralForm($value, $language='')
static loadCustomMessages($file, $language=null)
static getMessagePlural(string $code, int $value, array $replace=null, string $language=null)
static getMessage($code, $replace=null, $language=null)