log(modX::LOG_LEVEL_ERROR, '['.$snippetName.'] is missing required property &ctxDefault!'); return; } // Store parameters define('CONTEXT_PREFIX', $modx->getOption('ctxPrefix', $scriptProperties, '')); define('CONTEXT_SUFFIX', $modx->getOption('ctxSuffix', $scriptProperties, '')); define('DEFAULT_CONTEXT', $modx->getOption('ctxDefault', $scriptProperties, 'web')); // 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 '
';
$accepted = parseLanguageList($_SERVER['HTTP_ACCEPT_LANGUAGE']);
//print_r($accepted);
$babelKeys = $modx->getOption('babel.contextKeys',null,'en');
$patternCtx = '/' . CONTEXT_PREFIX . '(\w+)' . CONTEXT_SUFFIX . '/i';
$languageKeys = preg_replace($patternCtx, '$1', $babelKeys);
$available = parseLanguageList($languageKeys);
//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(CONTEXT_PREFIX . $matched_lang . CONTEXT_SUFFIX);
if (!$context) {
$context = $modx->getContext(DEFAULT_CONTEXT);
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;