read())) { if (preg_match('/^([a-z]{2}).json$/', $file, $match) === 1) { $availableLanguages[] = $match[1]; } } $match = self::_getMatchingLanguage( self::getBrowserLanguages(), $availableLanguages ); // load translations if ($match != 'en') { self::$_translations = json_decode( file_get_contents($path . DIRECTORY_SEPARATOR . $match . '.json'), true ); } } /** * detect the clients supported languages and return them ordered by preference * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * * @return array */ public static function getBrowserLanguages() { $languages = array(); if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) { $languageRanges = explode(',', trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])); foreach ($languageRanges as $languageRange) { if (preg_match( '/(\*|[a-zA-Z0-9]{1,8}(?:-[a-zA-Z0-9]{1,8})*)(?:\s*;\s*q\s*=\s*(0(?:\.\d{0,3})|1(?:\.0{0,3})))?/', trim($languageRange), $match )) { if (!isset($match[2])) { $match[2] = '1.0'; } else { $match[2] = (string) floatval($match[2]); } if (!isset($languages[$match[2]])) { $languages[$match[2]] = array(); } $languages[$match[2]][] = strtolower($match[1]); } } krsort($languages); } return $languages; } /** * compares two language preference arrays and returns the preferred match * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * * @param array $acceptedLanguages * @param array $availableLanguages * @return string */ protected static function _getMatchingLanguage($acceptedLanguages, $availableLanguages) { $matches = array(); $any = false; foreach ($acceptedLanguages as $acceptedQuality => $acceptedValues) { $acceptedQuality = floatval($acceptedQuality); if ($acceptedQuality === 0.0) continue; foreach ($availableLanguages as $availableValue) { $availableQuality = 1.0; foreach ($acceptedValues as $acceptedValue) { if ($acceptedValue === '*') { $any = true; } $matchingGrade = self::_matchLanguage($acceptedValue, $availableValue); if ($matchingGrade > 0) { $q = (string) ($acceptedQuality * $availableQuality * $matchingGrade); if (!isset($matches[$q])) { $matches[$q] = array(); } if (!in_array($availableValue, $matches[$q])) { $matches[$q][] = $availableValue; } } } } } if (count($matches) === 0 && $any) { if (count($availableLanguages) > 0) { $matches['1.0'] = $availableLanguages; } } if (count($matches) === 0) { return 'en'; } krsort($matches); $topmatches = current($matches); return current($topmatches); } /** * compare two language IDs and return the degree they match * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * * @param string $a * @param string $b * @return float */ protected static function _matchLanguage($a, $b) { $a = explode('-', $a); $b = explode('-', $b); for ($i=0, $n=min(count($a), count($b)); $i<$n; $i++) { if ($a[$i] !== $b[$i]) break; } return $i === 0 ? 0 : (float) $i / count($a); } }