7 * Figure out which of $langs is the closest to $lang.
9 * @param string $preferredLang
10 * The user's preferred language.
11 * Ex: `en`, `fr`, or `fr_CA`.
12 * @param array $availLangs
13 * List of available languages.
14 * Ex: ['en_US' => 'English (US)', 'fr_CA' => 'French (Canadian)'].
15 * @param string $default
16 * The locale to use if none other can be determined.
21 public static function pickClosest($preferredLang, $availLangs, $default = 'en_US') {
22 if ($preferredLang === NULL ||
$preferredLang === '') {
26 // Perhaps we have this exact language?
27 if (isset($availLangs[$preferredLang])) {
28 return $preferredLang;
31 list ($first) = explode('_', $preferredLang);
33 // Do we have a hard-coded preference? Use this for real oddballs.
37 if (isset($overrides[$preferredLang]) && isset($availLangs[$overrides[$preferredLang]])) {
38 return $overrides[$preferredLang];
41 // Perhaps we have the canonical variant (e.g. `fr` => `fr_FR`)?
42 $canon = $first . '_' . strtoupper($first);
43 if (isset($availLangs[$canon])) {
47 // Is there anything else that looks remotely close? (e.g. `cy` => `cy_GB`)
49 foreach ($availLangs as $availLang => $availLabel) {
50 if (strpos($availLang, $first) === 0) {