Skip to content

Instantly share code, notes, and snippets.

@Indigo744
Forked from christianseel/LanguageMatch
Created February 19, 2018 15:27
Show Gist options
  • Save Indigo744/0ef52f95525b32b9da5dda738be55374 to your computer and use it in GitHub Desktop.
Save Indigo744/0ef52f95525b32b9da5dda738be55374 to your computer and use it in GitHub Desktop.
LanguageMatch MODX Snippet – Redirects the visitor based on it's browser language
<?php
/**
* LanguageMatch
* Based on https://gist.github.com/christianseel/504302ce8ddfcde009c0
* Original code by http://stackoverflow.com/a/3771447
*
* Udated by Indigo74 for prefix/suffix and default context
*/
define('CONTEXT_PREFIX', 'web-');
define('CONTEXT_SUFFIX', '');
define('DEFAULT_CONTEXT', 'web-fr');
// 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(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;
@sebastian-marinescu
Copy link

Hi, I've updated the script to it trims the prefix/suffix from provided contextKeys and matches then:
https://gist.github.com/sebastian-marinescu/4b2991bc40dbbc405257ba5846adb1ef

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment