getName(); } if (empty($languagePath)) { $languagePath = Application::getInstance($appName)->getContainer()->languagePath; } $fileNames = array( // langPath/MyApp/en-GB.ini $languagePath . '/' . strtolower($appName) . '/' . $langCode . $suffix, // langPath/MyApp/en-GB/en-GB.ini $languagePath . '/' . strtolower($appName) . '/' . $langCode . '/' . $langCode . $suffix, // langPath/en-GB.ini $languagePath . '/' . $langCode . $suffix, // langPath/en-GB/en-GB.ini $languagePath . '/' . $langCode . '/' . $langCode . $suffix, ); $filename = null; foreach ($fileNames as $file) { if (@file_exists($file)) { $filename = $file; break; } } if (is_null($filename)) { return; } // Suppress the warning message when error reporting is enabled $strings = @parse_ini_file($filename); // Compatibility with Joomla! translation files and Transifex' broken way to conforming to a broken standard. if ($strings === false) { $rawText = @file_get_contents($filename); $rawText = str_replace('\\"_QQ_\\"', '"', $rawText); $rawText = str_replace('\\"_QQ_"', '"', $rawText); $rawText = str_replace('"_QQ_\\"', '"', $rawText); $rawText = str_replace('"_QQ_"', '"', $rawText); $strings = parse_ini_string($rawText); } if (!empty(static::$iniProcessCallbacks) && !empty($strings)) { foreach (static::$iniProcessCallbacks as $callback) { $ret = call_user_func($callback, $filename, $strings); if ($ret === false) { return; } elseif (is_array($ret)) { $strings = $ret; } } } if ($overwrite) { self::$strings = array_merge(self::$strings, $strings); } else { self::$strings = array_merge($strings, self::$strings); } } /** * Automatically detect the language preferences from the browser, choosing * the best fit language that exists on our system or falling back to en-GB * when no preferred language exists. * * @param string $appName The application's name to load language strings for * @param string $suffix The suffix of the language file, by default it's .ini * @param string $languagePath The base path to the language files (optional) * * @return string The language code */ public static function detectLanguage($appName = null, $suffix = '.ini', $languagePath = null) { if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $languages = strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]); // $languages = ' fr-ch;q=0.3, da, en-us;q=0.8, en;q=0.5, fr;q=0.3'; // need to remove spaces from strings to avoid error $languages = str_replace(' ', '', $languages); $languages = explode(",", $languages); // First we need to sort languages by their weight $temp = array(); foreach ($languages as $lang) { $parts = explode(';', $lang); $q = 1; if ((count($parts) > 1) && (substr($parts[1], 0, 2) == 'q=')) { $q = floatval(substr($parts[1], 2)); } $temp[$parts[0]] = $q; } arsort($temp); $languages = $temp; foreach ($languages as $language => $weight) { // pull out the language, place languages into array of full and primary // string structure: $temp_array = array(); // slice out the part before the dash, place into array $temp_array[0] = $language; //full language $parts = explode('-', $language); $temp_array[1] = $parts[0]; // cut out primary language if ((strlen($temp_array[0]) == 5) && ((substr($temp_array[0], 2, 1) == '-') || (substr($temp_array[0], 2, 1) == '_'))) { $langLocation = strtoupper(substr($temp_array[0], 3, 2)); $temp_array[0] = $temp_array[1] . '-' . $langLocation; } //place this array into main $user_languages language array $user_languages[] = $temp_array; } if (!isset($user_languages)) { return 'en-GB'; } if (empty($appName)) { $appName = Application::getInstance()->getName(); } if (empty($languagePath)) { $languagePath = Application::getInstance($appName)->getContainer()->languagePath; } $baseName = $languagePath . '/' . strtolower($appName) . '/'; if (!@is_dir($baseName)) { $baseName = $languagePath . '/'; } if (!@is_dir($baseName)) { return 'en-GB'; } // Look for classic file layout foreach ($user_languages as $languageStruct) { // Search for exact language $langFilename = $baseName . $languageStruct[0] . $suffix; if (!file_exists($langFilename)) { $langFilename = ''; if (function_exists('glob')) { $allFiles = glob($baseName . $languageStruct[1] . '-*' . $suffix); if (count($allFiles)) { $langFilename = array_shift($allFiles); } } } if (!empty($langFilename) && file_exists($langFilename)) { return basename($langFilename, $suffix); } } // Look for subdirectory layout $allFolders = array(); try { $di = new \DirectoryIterator($baseName); } catch (\Exception $e) { return 'en-GB'; } /** @var \DirectoryIterator $file */ foreach ($di as $file) { if ($di->isDot()) { continue; } if (!$di->isDir()) { continue; } $allFolders[] = $file->getFilename(); } foreach ($user_languages as $languageStruct) { if (array_key_exists($languageStruct[0], $allFolders)) { return $languageStruct[0]; } foreach ($allFolders as $folder) { if (strpos($folder, $languageStruct[1]) === 0) { return $folder; } } } } return 'en-GB'; } /** * Translate a string * * @param string $key Language key * * @return string Translation */ public static function _($key) { if (empty(self::$strings)) { self::loadLanguage('en-GB'); self::loadLanguage(); } $key = strtoupper($key); if (array_key_exists($key, self::$strings)) { return self::$strings[$key]; } else { return $key; } } /** * Passes a string through a sprintf. * * Note that this method can take a mixed number of arguments as for the sprintf function. * * @param string $string The format string. * * @return string The translated strings */ public static function sprintf($string) { $args = func_get_args(); $count = count($args); if ($count > 0) { $args[0] = self::_($string); return call_user_func_array('sprintf', $args); } return ''; } /** * Does a translation key exist? * * @param string $key The key to check * * @return boolean */ public static function hasKey($key) { if (empty(self::$strings)) { self::loadLanguage('en-GB'); self::loadLanguage(); } $key = strtoupper($key); return array_key_exists($key, self::$strings); } }