| 1 | <?php |
| 2 | namespace Civi\Setup; |
| 3 | |
| 4 | class LocaleUtil { |
| 5 | |
| 6 | /** |
| 7 | * Figure out which of $langs is the closest to $lang. |
| 8 | * |
| 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. |
| 17 | * Ex: 'en_US'. |
| 18 | * @return string |
| 19 | * Ex: 'en_US'. |
| 20 | */ |
| 21 | public static function pickClosest($preferredLang, $availLangs, $default = 'en_US') { |
| 22 | // Perhaps we have this exact language? |
| 23 | if (isset($availLangs[$preferredLang])) { |
| 24 | return $preferredLang; |
| 25 | } |
| 26 | |
| 27 | list ($first) = explode('_', $preferredLang); |
| 28 | |
| 29 | // Do we have a hard-coded preference? Use this for real oddballs. |
| 30 | $overrides = array( |
| 31 | 'en' => 'en_US', |
| 32 | ); |
| 33 | if (isset($overrides[$preferredLang]) && isset($availLangs[$overrides[$preferredLang]])) { |
| 34 | return $overrides[$preferredLang]; |
| 35 | } |
| 36 | |
| 37 | // Perhaps we have the canonical variant (e.g. `fr` => `fr_FR`)? |
| 38 | $canon = $first . '_' . strtoupper($first); |
| 39 | if (isset($availLangs[$canon])) { |
| 40 | return $canon; |
| 41 | } |
| 42 | |
| 43 | // Is there anything else that looks remotely close? (e.g. `cy` => `cy_GB`) |
| 44 | ksort($availLangs); |
| 45 | foreach ($availLangs as $availLang => $availLabel) { |
| 46 | if (strpos($availLang, $first) === 0) { |
| 47 | return $availLang; |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | // Nothing worked. |
| 52 | return $default; |
| 53 | } |
| 54 | |
| 55 | } |