I have two languages on my site:
English — http://adsoftheworld.com
Chinese — http://adsoftheworld.com/zh

I have set "Path prefix with language fallback" under Languages.

I tried downloading a Chinese version of Firefox and test if the Chinese site comes up when typing "adsoftheworld.com" in the url bar, but only the English comes up. How is automatic language detection supposed to work? How can I test it?

Thanks!

Comments

toemaz’s picture

I encountered the same problem for Chinese, but also with other languages which have a dash in the iso code like pt-pt, pt-br, zh-hans, ... Looking for an answer as well.

toemaz’s picture

Backport from D7 patch to D6

/**
 * Identify language from the Accept-language HTTP header we got.
 */
function language_from_browser() {
  // Get enabled language and create an array of valid language objects.
  $languages = language_list('enabled');
  $languages = $languages['1'];
  
  if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
    return;
  }

  // RFC 2616 (section 14.4) defines the Accept-Language header as followed:
  //   Accept-Language = "Accept-Language" ":"
  //                  1#( language-range [ ";" "q" "=" qvalue ] )
  //   language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
  // Samples: "hu, en-us;q=0.66, en;q=0.33", "hu,en-us;q=0.5"
  $browser_langs = array();
  if (preg_match_all('@([a-zA-Z-]+|\*)(?:;q=([0-9.]+))?(?:$|\s*,\s*)@', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches, PREG_SET_ORDER)) {
    foreach ($matches as $match) {
      // We can safely use strtolower() here, tags are ASCII.
      // RFC2616 mandates that the decimal part is no more than three digits,
      // so we multiply the qvalue by 1000 to avoid floating point comparisons.
      $langcode = strtolower($match[1]);
      $qvalue = isset($match[2]) ? (float) $match[2] : 1;
      $browser_langs[$langcode] = (int) ($qvalue * 1000);
    }
  }

  // Find the enabled language with the greatest qvalue, following the rules
  // of RFC 2616 (section 14.4). If several languages have the same qvalue,
  // prefer the one with the greatest weight.
  $best_match = NULL;
  $max_qvalue = 0;
  foreach ($languages as $langcode => $language) {
    // Language tags are case insensitive (RFC2616, sec 3.10).
    $langcode = strtolower($langcode);

    // If nothing matches below, the default qvalue is the one of the wildcard
    // language, if set, or is 0 (which will never match).
    $qvalue = isset($browser_langs['*']) ? $browser_langs['*'] : 0;

    // Find the longest possible prefix of the browser-supplied language
    // ('the language-range') that matches this site language ('the language tag').
    $prefix = $langcode;
    do {
      if (isset($browser_langs[$prefix])) {
        $qvalue = $browser_langs[$prefix];
        break;
      }
    }
    while ($prefix = substr($prefix, 0, strrpos($prefix, '-')));

    // Find the best match.
    if ($qvalue > $max_qvalue) {
      $best_match = $language->language;
      $max_qvalue = $qvalue;
    }
  }
  
  return $languages[$best_match];
}
kwud’s picture

I was having this problem with zh-hans / zh-CN.

The patch needs to be applied to includes/language.inc, by the way.

I had thought there must be a problem with firefox or the quick locale switcher extension rather than what turns out to be a longstanding problem in Drupal 6.