/** * 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 = ''; $filesystem = new File(array()); $allFiles = $filesystem->directoryFiles($baseName, $languageStruct[1] . '\\-.*', false, true); 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'; }