LanguageMatch MODX Snippet – Redirects the visitor based on it's browser language (this snippets expects that your context_key is similar to the cultureKey)
<?php | |
// code by http://stackoverflow.com/a/3771447 | |
// parse list of comma separated language tags and sort it by the quality value | |
function parseLanguageList($languageList) { | |
if (is_null($languageList)) { | |
if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { | |
return array(); | |
} | |
$languageList = $_SERVER['HTTP_ACCEPT_LANGUAGE']; | |
} | |
$languages = array(); | |
$languageRanges = explode(',', trim($languageList)); | |
foreach ($languageRanges as $languageRange) { | |
if (preg_match('/(\*|[a-zA-Z0-9]{1,8}(?:-[a-zA-Z0-9]{1,8})*)(?:\s*;\s*q\s*=\s*(0(?:\.\d{0,3})|1(?:\.0{0,3})))?/', trim($languageRange), $match)) { | |
if (!isset($match[2])) { | |
$match[2] = '1.0'; | |
} else { | |
$match[2] = (string) floatval($match[2]); | |
} | |
if (!isset($languages[$match[2]])) { | |
$languages[$match[2]] = array(); | |
} | |
$languages[$match[2]][] = strtolower($match[1]); | |
} | |
} | |
krsort($languages); | |
return $languages; | |
} | |
// compare two parsed arrays of language tags and find the matches | |
function findMatches($accepted, $available) { | |
$matches = array(); | |
$any = false; | |
foreach ($accepted as $acceptedQuality => $acceptedValues) { | |
$acceptedQuality = floatval($acceptedQuality); | |
if ($acceptedQuality === 0.0) continue; | |
foreach ($available as $availableQuality => $availableValues) { | |
$availableQuality = floatval($availableQuality); | |
if ($availableQuality === 0.0) continue; | |
foreach ($acceptedValues as $acceptedValue) { | |
if ($acceptedValue === '*') { | |
$any = true; | |
} | |
foreach ($availableValues as $availableValue) { | |
$matchingGrade = matchLanguage($acceptedValue, $availableValue); | |
if ($matchingGrade > 0) { | |
$q = (string) ($acceptedQuality * $availableQuality * $matchingGrade); | |
if (!isset($matches[$q])) { | |
$matches[$q] = array(); | |
} | |
if (!in_array($availableValue, $matches[$q])) { | |
$matches[$q][] = $availableValue; | |
} | |
} | |
} | |
} | |
} | |
} | |
if (count($matches) === 0 && $any) { | |
$matches = $available; | |
} | |
krsort($matches); | |
return $matches; | |
} | |
// compare two language tags and distinguish the degree of matching | |
function matchLanguage($a, $b) { | |
$a = explode('-', $a); | |
$b = explode('-', $b); | |
for ($i=0, $n=min(count($a), count($b)); $i<$n; $i++) { | |
if ($a[$i] !== $b[$i]) break; | |
} | |
return $i === 0 ? 0 : (float) $i / count($a); | |
} | |
//echo '<pre>'; | |
$accepted = parseLanguageList($_SERVER['HTTP_ACCEPT_LANGUAGE']); | |
//print_r($accepted); | |
$available = parseLanguageList($modx->getOption('babel.contextKeys',null,'en')); | |
//print_r($available); | |
$matches = findMatches($accepted, $available); | |
//print_r($matches); | |
if (!empty($matches)) { | |
$matched_lang = array_shift(array_values($matches)); | |
$matched_lang = $matched_lang[0]; | |
} else { | |
$matched_lang = 'en'; | |
} | |
$context = $modx->getContext($matched_lang); | |
if (!$context) return 'CONTEXT NOT FOUND. (ERROR IN LANGUAGEMATCH SNIPPET)'; | |
$site_start = $context->getOption('site_start',null,$modx->getOption('site_start',null,1)); | |
$url = $modx->makeUrl($site_start); | |
$modx->sendRedirect($url, array('responseCode' => 'HTTP/1.1 302 Found')); | |
return; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
My fork: https://gist.github.com/Indigo744/0ef52f95525b32b9da5dda738be55374
With context prefix/suffix and default context support.