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 $val = Encoding::convertEncoding($val, $sourceEncoding, $targetEncoding);
268 self::$messages[$language][$key] = $val;
284 if($language ===
null)
289 if(!isset(self::$customMessages[$language]))
291 self::$customMessages[$language] = array();
295 $mess = self::includeLangFiles(Path::normalize($file), $language, $langFile);
301 foreach ($mess as $key => $val)
303 if ($convertEncoding)
305 $val = $mess[$key] = Encoding::convertEncoding($val, $sourceEncoding, $targetEncoding);
308 self::$customMessages[$language][$key] = $val;
313 private static function loadLazy($code, $language)
321 if(!isset(self::$triedFiles[$language]))
323 self::$triedFiles[$language] = [];
326 $trace = Main\Diag\Helper::getBackTrace(4, DEBUG_BACKTRACE_IGNORE_ARGS);
329 for($i = 3; $i >= 1; $i--)
331 if (isset($trace[$i]) && stripos($trace[$i][
"function"],
"GetMessage") === 0)
333 $currentFile = Path::normalize($trace[$i][
"file"]);
336 self::$lazyLoadFiles[$currentFile] = $currentFile;
341 if($currentFile !==
null && isset(self::$lazyLoadFiles[$currentFile]))
344 if(!isset(self::$triedFiles[$language][$currentFile]))
347 self::$triedFiles[$language][$currentFile] =
true;
349 unset(self::$lazyLoadFiles[$currentFile]);
352 if(!isset(self::$messages[$language][$code]))
356 if(($file = end(self::$lazyLoadFiles)) !==
false)
360 if(!isset(self::$triedFiles[$language][$file]))
363 self::$triedFiles[$language][$file] =
true;
367 if(isset(self::$messages[$language][$code]))
369 if(defined(
"BX_MESS_LOG") && $currentFile !==
null)
371 file_put_contents(BX_MESS_LOG,
'CTranslateUtils::CopyMessage("'.$code.
'", "'.$file.
'", "'.$currentFile.
'");'.
"\n", FILE_APPEND);
376 while(($file = prev(self::$lazyLoadFiles)) !==
false);
378 foreach($unset as $file)
380 unset(self::$lazyLoadFiles[$file]);
384 if(!isset(self::$messages[$language][$code]) && defined(
"BX_MESS_LOG"))
386 file_put_contents(BX_MESS_LOG, $code.
": not found for ".$currentFile.
"\n", FILE_APPEND);
396 private static function loadUserMessages($lang)
399 $documentRoot = Main\Application::getDocumentRoot();
400 if(($fname = Main\
Loader::getLocal(
"php_interface/user_lang/".$lang.
"/lang.php", $documentRoot)) !==
false)
402 $mess = self::includeFile($fname);
406 foreach($mess as $key => $val)
407 $userMess[str_replace(
"\\",
"/", realpath($documentRoot.$key))] = $val;
418 private static function includeFile($path)
420 self::$includedFiles[$path] = $path;
427 if(!empty(self::$userMessages))
429 $path = str_replace(
"\\",
"/", realpath($path));
432 foreach(self::$userMessages as $messages)
434 if(isset($messages[$path]) && is_array($messages[$path]))
436 foreach($messages[$path] as $key => $val)
455 static $subst = [
'ua' =>
'en',
'kz' =>
'ru',
'by' =>
'ru',
'ru' =>
'ru',
'en' =>
'en',
'de' =>
'en'];
456 if(isset($subst[$lang]))
458 return $subst[$lang];
461 $options = Configuration::getValue(
"default_language");
462 if(isset($options[$lang]))
464 return $options[$lang];
476 return self::$includedFiles;
497 public static function getMessagePlural(
string $code,
int $value, array $replace =
null,
string $language =
null): ?string
499 $language = (string)$language;
500 if ($language ===
'')
502 $language = LANGUAGE_ID;
505 $result =
self::getMessage($code .
'_PLURAL_' . self::getPluralForm($value, $language), $replace);
506 if ($result ===
null)
523 $value = (int)$value;
524 $language = (string)$language;
525 if ($language ===
'')
527 $language = LANGUAGE_ID;
532 $value = (-1) * $value;
538 $pluralForm = (($value !== 1) ? 1 : 0);
573 $pluralForm = (($value > 1) ? 1 : 0);
581 $pluralForm = (($value !== 1) ? 1 : 0);
588 && ($value % 100 !== 11)
595 && ($value % 10 <= 4)
598 || ($value % 100 >= 20)
620 || $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 getIncludedFiles()
static loadMessages($file)
static setCurrentLang($language)
static getDefaultLang($lang)
static getMessage($code, $replace=null, $language=null)
static convertLangPath($langFile, $language)
static getEncodings($language, $langFile)