Browse Source

Remove langs /w duplicates having lower rank

- Remove locale/lang duplicates with lower rank/quality
- Use variable names for pattern matches

### Before
```php
$httpAcceptLanguages = 'en-US,en;q=0.1,de-AT;q=0.7,fr;q=0.5,de;q=0.3,DE-DE;q=0.3,en-US,en;q=0.8,de-AT;q=1.0,fr;q=0.5,de;q=0.3,de-DE;q=0.1,SE';
$prefLocales = Language::parseLanguageList($httpAcceptLanguages);
debug($prefLocales);
```

```php
 /plugins/FlexiCms/src/Routing/Proxy/CmsLinksRoutingProxy.php (line 66)
[
	'1.0' => [
		(int) 0 => 'de-at',
		(int) 1 => 'se'
	],
	'0.8' => [
		(int) 0 => 'en'
	],
	'0.7' => [
		(int) 0 => 'de-at'
	],
	'0.5' => [
		(int) 0 => 'fr',
		(int) 1 => 'fr'
	],
	'0.3' => [
		(int) 0 => 'de',
		(int) 1 => 'de-de',
		(int) 2 => 'de'
	],
	'0.1' => [
		(int) 0 => 'en',
		(int) 1 => 'de-de'
	]
]
```


### After
```php
$httpAcceptLanguages = 'en-US,en;q=0.1,de-AT;q=0.7,fr;q=0.5,de;q=0.3,DE-DE;q=0.3,en-US,en;q=0.8,de-AT;q=1.0,fr;q=0.5,de;q=0.3,de-DE;q=0.1,SE';
$prefLocales = Language::parseLanguageList($httpAcceptLanguages, false, false);
debug($prefLocales);
```

```php
 /plugins/FlexiCms/src/Routing/Proxy/CmsLinksRoutingProxy.php (line 66)
[
	'1.0' => [
		(int) 0 => 'de-AT',
		(int) 1 => 'se'
	],
	'0.8' => [
		(int) 0 => 'en'
	],
	'0.7' => [
		(int) 0 => 'de-AT'
	],
	'0.5' => [
		(int) 0 => 'fr'
	],
	'0.3' => [
		(int) 0 => 'de',
		(int) 1 => 'de-DE'
	],
	'0.1' => [
		(int) 0 => 'en'
	]
]
```
inoas 8 years ago
parent
commit
69937b5e07
1 changed files with 33 additions and 10 deletions
  1. 33 10
      src/Utility/Language.php

+ 33 - 10
src/Utility/Language.php

@@ -13,7 +13,7 @@ class Language {
 	 *
 	 * @return array
 	 */
-	public static function parseLanguageList($languageList = null, $forceLowerCase = true) {
+	public static function parseLanguageList($languageList = null, $forceAllLowerCase = true, $keepDuplicates = true) {
 		if ($languageList === null) {
 			if (empty(env('HTTP_ACCEPT_LANGUAGE'))) {
 				return [];
@@ -21,25 +21,48 @@ class Language {
 			$languageList = env('HTTP_ACCEPT_LANGUAGE');
 		}
 		$languages = [];
+		$languagesRanks = [];
 		$languageRanges = explode(',', trim($languageList));
 		foreach ($languageRanges as $languageRange) {
 			$pattern = '/(\*|[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})))?/';
 			if (preg_match($pattern, trim($languageRange), $match)) {
 				if (!isset($match[2])) {
-					$match[2] = '1.0';
+					$rank = '1.0';
 				} else {
-					$match[2] = (string)(float)($match[2]);
+					$rank = (string)(float)($match[2]);
 				}
-				if (!isset($languages[$match[2]])) {
-					if ($match[2] === '1') {
-						$match[2] = '1.0';
+				if (!isset($languages[$rank])) {
+					if ($rank === '1') {
+						$rank = '1.0';
 					}
-					$languages[$match[2]] = [];
+					$languages[$rank] = [];
 				}
-				if ($forceLowerCase) {
-					$languages[$match[2]][] = strtolower($match[1]);
+
+				$language = $match[1];
+				if ($forceAllLowerCase) {
+					$language = strtolower($language);
+				} else {
+					$language = substr_replace($language, strtolower(substr($language, 0, 2)), 0, 2);
+				}
+
+				if ($keepDuplicates) {
+					$languages[$rank][] = $language;
 				} else {
-					$languages[$match[2]][] = $match[1];
+					if (array_key_exists($language, $languagesRanks) === false) {
+						$languages[$rank][] = $language;
+						$languagesRanks[$language] = $rank;
+					} elseif ($rank > $languagesRanks[$language]) {
+						foreach ($languages as $existRank => $existLangs) {
+							if (($key = array_search($existLangs, $languages)) !== false) {
+								unset($languages[$existRank][$key]);
+								if (empty($languages[$existRank])) {
+									unset($languages[$existRank]);
+								}
+							}
+						}
+						$languages[$rank][] = $language;
+						$languagesRanks[$language] = $rank;
+					}
 				}
 			}
 		}