Index: includes/language.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/language.inc,v retrieving revision 1.16 diff -u -p -r1.16 language.inc --- includes/language.inc 14 Apr 2008 17:48:33 -0000 1.16 +++ includes/language.inc 3 Sep 2008 10:30:28 -0000 @@ -70,32 +70,43 @@ function language_initialize() { * Identify language from the Accept-language HTTP header we got. */ function language_from_browser() { - // Specified by the user via the browser's Accept Language setting - // Samples: "hu, en-us;q=0.66, en;q=0.33", "hu,en-us;q=0.5" - $browser_langs = array(); - - if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $browser_accept = explode(",", $_SERVER['HTTP_ACCEPT_LANGUAGE']); - for ($i = 0; $i < count($browser_accept); $i++) { - // The language part is either a code or a code with a quality. - // We cannot do anything with a * code, so it is skipped. - // If the quality is missing, it is assumed to be 1 according to the RFC. - if (preg_match("!([a-z-]+)(;q=([0-9\\.]+))?!", trim($browser_accept[$i]), $found)) { - $browser_langs[$found[1]] = (isset($found[3]) ? (float) $found[3] : 1.0); - } - } + if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + return; } - // Order the codes by quality - arsort($browser_langs); + $browser_langs = array(); + if (preg_match_all('@([a-zA-Z]{1,8}(?:-[a-zA-Z]{1,8})?|\*)(?:;q=(1(?:\.000)?|0(?:\.[0-9]{0,3})?))?\s*,?\s*@', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $browser_langs[$match[1]] = isset($match[2]) ? (int)((float) $match[2] * 1000) : 1000; + } + } - // Try to find the first preferred language we have + // Find the enabled language with the greatest qvalue, following the rules + // of RFC2616 (section 14.4). If several languages have the same qvalue, + // prefer the one with the greatest weight. $languages = language_list('enabled'); - foreach ($browser_langs as $langcode => $q) { - if (isset($languages['1'][$langcode])) { - return $languages['1'][$langcode]; + $best_match = NULL; + $max_qvalue = 0; + foreach ($languages['1'] as $langcode => $language) { + $qvalue = NULL; + if (isset($browser_langs[$langcode])) { + $qvalue = $browser_langs[$langcode]; + } + else if ((($prefix = strtok($langcode, '-')) != $langcode) && isset($browser_langs[$prefix])) { + $qvalue = $browser_langs[$prefix]; + } + else if (isset($browser_langs['*'])) { + $qvalue = $browser_langs['*']; + } + + if (!is_null($qvalue)) { + if ($qvalue > $max_qvalue) { + $best_match = $language; + $max_qvalue = $qvalue; + } } } + return $best_match; } /**