mirror of
https://github.com/GuduleLapointe/opensim-helpers.git
synced 2026-08-14 08:52:11 +00:00
98 lines
3.3 KiB
PHP
98 lines
3.3 KiB
PHP
<?php
|
|
class OpenSim_Locale {
|
|
const HTTP_ACCEPT_LANGUAGE_HEADER_KEY = 'HTTP_ACCEPT_LANGUAGE';
|
|
private static $detected = array();
|
|
// private static $lang;
|
|
// private static $locale;
|
|
|
|
public static function detect() {
|
|
if( !empty( self::$detected ) ) {
|
|
return self::$detected;
|
|
}
|
|
$httpAcceptLanguageHeader = static::getHttpAcceptLanguageHeader();
|
|
if ($httpAcceptLanguageHeader == null) {
|
|
return [];
|
|
}
|
|
$locales = static::getWeightedLocales($httpAcceptLanguageHeader);
|
|
$sortedLocales = static::sortLocalesByWeight($locales);
|
|
|
|
self::$detected = array_map(function ($weightedLocale) {
|
|
return $weightedLocale['locale'];
|
|
}, $sortedLocales);
|
|
|
|
if( empty( self::$detected ) ) {
|
|
self::$detected = ['en_US', 'en'];
|
|
}
|
|
|
|
return self::$detected;
|
|
}
|
|
|
|
public static function locale() {
|
|
$detected = self::detect();
|
|
return $detected[0] ?? 'en_US';
|
|
}
|
|
|
|
public static function lang() {
|
|
$detected = self::detect();
|
|
return $detected[1] ?? substr( self::locale(), 0, 2 ) ?? 'en';
|
|
}
|
|
|
|
private static function getHttpAcceptLanguageHeader() {
|
|
if (isset($_SERVER[static::HTTP_ACCEPT_LANGUAGE_HEADER_KEY])) {
|
|
return trim($_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static function getWeightedLocales($httpAcceptLanguageHeader) {
|
|
if (strlen($httpAcceptLanguageHeader) == 0) {
|
|
return [];
|
|
}
|
|
|
|
$weightedLocales = [];
|
|
|
|
// We break up the string 'en-CA,ar-EG;q=0.5' along the commas,
|
|
// and iterate over the resulting array of individual locales. Once
|
|
// we're done, $weightedLocales should look like
|
|
// [['locale' => 'en-CA', 'q' => 1.0], ['locale' => 'ar-EG', 'q' => 0.5]]
|
|
foreach (explode(',', $httpAcceptLanguageHeader) as $locale) {
|
|
// separate the locale key ("ar-EG") from its weight ("q=0.5")
|
|
$localeParts = explode(';', $locale);
|
|
$weightedLocale = ['locale' => $localeParts[0]];
|
|
if (count($localeParts) == 2) {
|
|
// explicit weight e.g. 'q=0.5'
|
|
$weightParts = explode('=', $localeParts[1]);
|
|
// grab the '0.5' bit and parse it to a float
|
|
$weightedLocale['q'] = floatval($weightParts[1]);
|
|
} else {
|
|
// no weight given in string, ie. implicit weight of 'q=1.0'
|
|
$weightedLocale['q'] = 1.0;
|
|
}
|
|
$weightedLocales[] = $weightedLocale;
|
|
}
|
|
return $weightedLocales;
|
|
}
|
|
|
|
/**
|
|
* Sort by high to low `q` value
|
|
*/
|
|
private static function sortLocalesByWeight($locales) {
|
|
usort($locales, function ($a, $b) {
|
|
// usort will cast float values that we return here into integers,
|
|
// which can mess up our sorting. So instead of subtracting the `q`,
|
|
// values and returning the difference, we compare the `q` values and
|
|
// explicitly return integer values.
|
|
if ($a['q'] == $b['q']) {
|
|
return 0;
|
|
}
|
|
if ($a['q'] > $b['q']) {
|
|
return -1;
|
|
}
|
|
return 1;
|
|
});
|
|
|
|
return $locales;
|
|
}
|
|
}
|