Fractaliste
Fractaliste

Reputation: 5957

How to use Locale::lookup with locale from $_SERVER['HTTP_ACCEPT_LANGUAGE']?

I create a function, which should return the best translation depending of user's locale.

The input is an array (from the BDD) of translation of the same text in many languages, the language is stored as the key like following:

$textes = array(2) {
    ["fr-fr"]=> string(24) "Editer l'item" 
    ["en-en"]=> string(22) "Edit the item"
} 

The function returns the item when $textescontains only one item, else it should returns the best translation; I try to deal with intl's Locale function but it always return an empty string:

private static function getMeilleureTraduction(array $textes) {
    if (count($textes) === 1) {
        return array_pop($textes);
    }

    // Returns "fr,en;q=0.8,fr-fr;q=0.5,en-us;q=0.3"
    $a = $_SERVER['HTTP_ACCEPT_LANGUAGE']; 

    // Returns "fr"
    $b = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    // Returns ""
    $c = Locale::lookup(array_keys($textes), $a, true);

    // Returns ""
    $d = Locale::lookup(array_keys($textes), $b, true);

    // return $textes[$bestLocale];
}

So the lookup function doesn't help me because it is not able to make a decision. Do I use it wrong? Or maybe I do not understand php-intl's function's aim, and I should code it my myself?

Upvotes: 1

Views: 722

Answers (1)

Fractaliste
Fractaliste

Reputation: 5957

Finally found a working function HERE.

The function:

<?php 
/* 
  determine which language out of an available set the user prefers most 

  $available_languages        array with language-tag-strings (must be lowercase) that are available 
  $http_accept_language    a HTTP_ACCEPT_LANGUAGE string (read from $_SERVER['HTTP_ACCEPT_LANGUAGE'] if left out) 
*/ 
function prefered_language ($available_languages,$http_accept_language="auto") { 
    // if $http_accept_language was left out, read it from the HTTP-Header 
    if ($http_accept_language == "auto") $http_accept_language = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : ''; 

    // standard  for HTTP_ACCEPT_LANGUAGE is defined under 
    // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 
    // pattern to find is therefore something like this: 
    //    1#( language-range [ ";" "q" "=" qvalue ] ) 
    // where: 
    //    language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) 
    //    qvalue         = ( "0" [ "." 0*3DIGIT ] ) 
    //            | ( "1" [ "." 0*3("0") ] ) 
    preg_match_all("/([[:alpha:]]{1,8})(-([[:alpha:]|-]{1,8}))?" . 
                   "(\s*;\s*q\s*=\s*(1\.0{0,3}|0\.\d{0,3}))?\s*(,|$)/i", 
                   $http_accept_language, $hits, PREG_SET_ORDER); 

    // default language (in case of no hits) is the first in the array 
    $bestlang = $available_languages[0]; 
    $bestqval = 0; 

    foreach ($hits as $arr) { 
        // read data from the array of this hit 
        $langprefix = strtolower ($arr[1]); 
        if (!empty($arr[3])) { 
            $langrange = strtolower ($arr[3]); 
            $language = $langprefix . "-" . $langrange; 
        } 
        else $language = $langprefix; 
        $qvalue = 1.0; 
        if (!empty($arr[5])) $qvalue = floatval($arr[5]); 

        // find q-maximal language  
        if (in_array($language,$available_languages) && ($qvalue > $bestqval)) { 
            $bestlang = $language; 
            $bestqval = $qvalue; 
        } 
        // if no direct hit, try the prefix only but decrease q-value by 10% (as http_negotiate_language does) 
        else if (in_array($langprefix,$available_languages) && (($qvalue*0.9) > $bestqval)) { 
            $bestlang = $langprefix; 
            $bestqval = $qvalue*0.9; 
        } 
    } 
    return $bestlang; 
} 
?>

Upvotes: 1

Related Questions