Browse Source

Feature #306 - Fixing logic about encoding aliases recognition in the internationalization library.

Ivan Tcholakov 15 years ago
parent
commit
7409c475af

+ 46 - 10
main/inc/lib/internationalization.lib.php

@@ -2811,7 +2811,7 @@ function api_in_array_nocase($needle, $haystack, $strict = false, $encoding = nu
  */
 function api_refine_encoding_id($encoding) {
 	if (is_array($encoding)){
-		return array_map('strtoupper', $encoding);
+		return array_map('api_refine_encoding_id', $encoding);
 	}
 	return strtoupper($encoding);
 }
@@ -2820,13 +2820,14 @@ function api_refine_encoding_id($encoding) {
  * This function checks whether two $encoding are equal (same, equvalent).
  * @param string/array $encoding1		The first encoding
  * @param string/array $encoding2		The second encoding
+ * @param bool $strict					When this parameter is TRUE the comparison ignores aliases of encodings. When the parameter is FALSE, aliases are taken into account.
  * @return bool							Returns TRUE if the encodings are equal, FALSE otherwise.
  */
-function api_equal_encodings($encoding1, $encoding2) {
+function api_equal_encodings($encoding1, $encoding2, $strict = false) {
 	static $equal_encodings = array();
 	if (is_array($encoding1)) {
 		foreach ($encoding1 as $encoding) {
-			if (api_equal_encodings($encoding, $encoding2)) {
+			if (api_equal_encodings($encoding, $encoding2, $strict)) {
 				return true;
 			}
 		}
@@ -2834,25 +2835,29 @@ function api_equal_encodings($encoding1, $encoding2) {
 	}
 	elseif (is_array($encoding2)) {
 		foreach ($encoding2 as $encoding) {
-			if (api_equal_encodings($encoding1, $encoding)) {
+			if (api_equal_encodings($encoding1, $encoding, $strict)) {
 				return true;
 			}
 		}
 		return false;
 	}
-	if (!isset($equal_encodings[$encoding1][$encoding2])) {
+	if (!isset($equal_encodings[$encoding1][$encoding2][$strict])) {
 		$encoding_1 = api_refine_encoding_id($encoding1);
 		$encoding_2 = api_refine_encoding_id($encoding2);
 		if ($encoding_1 == $encoding_2) {
 			$result = true;
 		} else {
-			$alias1 = _api_get_character_map_name($encoding_1);
-			$alias2 = _api_get_character_map_name($encoding_2);
-			$result = !empty($alias1) && !empty($alias2) && $alias1 == $alias2;
+			if ($strict) {
+				$result = false;
+			} else {
+				$alias1 = _api_get_character_map_name($encoding_1);
+				$alias2 = _api_get_character_map_name($encoding_2);
+				$result = !empty($alias1) && !empty($alias2) && $alias1 == $alias2;
+			}
 		}
-		$equal_encodings[$encoding1][$encoding2] = $result;
+		$equal_encodings[$encoding1][$encoding2][$strict] = $result;
 	}
-	return $equal_encodings[$encoding1][$encoding2];
+	return $equal_encodings[$encoding1][$encoding2][$strict];
 }
 
 /**
@@ -2983,6 +2988,37 @@ function api_get_non_utf8_encoding($language = null) {
 	return 'ISO-8859-15';
 }
 
+/**
+ * Return a list of valid encodings for setting platform character set.
+ * @return array	List of valid encodings, preferably IANA-registared.
+ */
+function api_get_valid_encodings() {
+	$encodings = & _api_non_utf8_encodings();
+	if (!is_array($encodings)) {
+		$encodings = array('english', array('ISO-8859-15'));
+	}
+	$result1 = array(); $result2 = array(); $result3 = array();
+	foreach ($encodings as $value) {
+		$encoding = api_refine_encoding_id(trim($value[0]));
+		if (!empty($encoding)) {
+			if (strpos($encoding, 'ISO-') === 0) {
+				$result1[] = $encoding;
+			} elseif (strpos($encoding, 'WINDOWS-') === 0) {
+				$result2[] = $encoding;
+			} else {
+				$result3[] = $encoding;
+			}
+		}
+	}
+	$result1 = array_unique($result1);
+	$result2 = array_unique($result2);
+	$result3 = array_unique($result3);
+	natsort($result1);
+	natsort($result2);
+	natsort($result3);
+	return array_merge(array('UTF-8'), $result1, $result2, $result3);
+}
+
 /**
  * Detects encoding of xml-formatted text.
  * @param string $string				The input xml-formatted text.

+ 1 - 1
main/inc/lib/internationalization_internal.lib.php

@@ -1027,7 +1027,7 @@ function _api_mb_supports($encoding) {
 	static $supported = array();
 	if (!isset($supported[$encoding])) {
 		if (MBSTRING_INSTALLED) {
-			$supported[$encoding] = api_equal_encodings($encoding, mb_list_encodings());
+			$supported[$encoding] = api_equal_encodings($encoding, mb_list_encodings(), true);
 		} else {
 			$supported[$encoding] = false;
 		}

+ 28 - 4
tests/main/inc/lib/internationalization.lib.test.php

@@ -77,13 +77,13 @@ class TestInternationalization extends UnitTestCase {
 	}
 
 	public function test_api_to_system_encoding() {
-		$string = '!?/\áéíóú@€'; // UTF-8
+		$string = api_utf8_encode(get_lang('Title'), api_get_system_encoding());
 		$from_encoding = 'UTF-8';
 		$check_utf8_validity = false;
 		$res = api_to_system_encoding($string, $from_encoding, $check_utf8_validity);
 		$this->assertTrue(is_string($res));
 		$this->assertTrue(api_convert_encoding($res, $from_encoding, api_get_system_encoding()) == $string);
-		//var_dump($res);
+		//var_dump(api_utf8_encode($res, api_get_system_encoding()));
 	}
 
 	public function test_api_htmlentities() {
@@ -727,15 +727,26 @@ class TestInternationalization extends UnitTestCase {
 	public function test_api_equal_encodings() {
 		$encoding1 = 'cp65001';
 		$encoding2 = 'utf-8';
-		$res1 = api_equal_encodings($encoding1, $encoding2);
 		$encoding3 = 'WINDOWS-1251';
 		$encoding4 = 'WINDOWS-1252';
+		$encoding5 = 'win-1250';
+		$encoding6 = 'windows-1250';
+		$res1 = api_equal_encodings($encoding1, $encoding2);
 		$res2 = api_equal_encodings($encoding3, $encoding4);
+		$res3 = api_equal_encodings($encoding5, $encoding6);
+		$res4 = api_equal_encodings($encoding5, $encoding6, true);
 		$this->assertTrue(is_bool($res1));
 		$this->assertTrue(is_bool($res2));
-		$this->assertTrue($res1 && !$res2);
+		$this->assertTrue(is_bool($res3));
+		$this->assertTrue(is_bool($res4));
+		$this->assertTrue($res1);
+		$this->assertTrue(!$res2);
+		$this->assertTrue($res3);
+		$this->assertTrue(!$res4);
 		//var_dump($res1);
 		//var_dump($res2);
+		//var_dump($res3);
+		//var_dump($res4);
 	}
 
 	public function test_api_is_utf8() {
@@ -789,6 +800,19 @@ class TestInternationalization extends UnitTestCase {
 		//var_dump($res);
 	}
 
+	public function test_api_get_valid_encodings() {
+		$res = api_get_valid_encodings();
+		$ok = is_array($res) && !empty($res);
+		$this->assertTrue($ok);
+		if ($ok) {
+			foreach ($res as $value) {
+				$ok = $ok && is_string($value);
+			}
+			$this->assertTrue($ok);
+		}
+		//var_dump($res);
+	}
+
 	public function test_api_detect_encoding_xml() {
 		$xml1 = '
 			<Users>