Browse Source

Changed to accept language do not return the qualifiers and order the values by the qualifier. Also, making the test case insensitive

Juan Basso 13 years ago
parent
commit
fd2f3aed46
2 changed files with 64 additions and 28 deletions
  1. 41 27
      lib/Cake/Network/CakeRequest.php
  2. 23 1
      lib/Cake/Test/Case/Network/CakeRequestTest.php

+ 41 - 27
lib/Cake/Network/CakeRequest.php

@@ -694,26 +694,7 @@ class CakeRequest implements ArrayAccess {
  * @return array An array of prefValue => array(content/types)
  */
 	public function parseAccept() {
-		$accept = array();
-		$header = explode(',', $this->header('accept'));
-		foreach (array_filter($header) as $value) {
-			$prefPos = strpos($value, ';');
-			if ($prefPos !== false) {
-				$prefValue = substr($value, strpos($value, '=') + 1);
-				$value = trim(substr($value, 0, $prefPos));
-			} else {
-				$prefValue = '1.0';
-				$value = trim($value);
-			}
-			if (!isset($accept[$prefValue])) {
-				$accept[$prefValue] = array();
-			}
-			if ($prefValue) {
-				$accept[$prefValue][] = $value;
-			}
-		}
-		krsort($accept);
-		return $accept;
+		return $this->_parseAcceptWithQualifier($this->header('accept'));
 	}
 
 /**
@@ -731,17 +712,50 @@ class CakeRequest implements ArrayAccess {
  * @return If a $language is provided, a boolean. Otherwise the array of accepted languages.
  */
 	public static function acceptLanguage($language = null) {
-		$accepts = preg_split('/[;,]/', self::header('Accept-Language'));
-		foreach ($accepts as &$accept) {
-			$accept = strtolower($accept);
-			if (strpos($accept, '_') !== false) {
-				$accept = str_replace('_', '-', $accept);
+		$raw = self::_parseAcceptWithQualifier(self::header('Accept-Language'));
+		$accept = array();
+		foreach ($raw as $qualifier => $languages) {
+			foreach ($languages as &$lang) {
+				if (strpos($lang, '_')) {
+					$lang = str_replace('_', '-', $lang);
+				}
+				$lang = strtolower($lang);
 			}
+			$accept = array_merge($accept, $languages);
 		}
 		if ($language === null) {
-			return $accepts;
+			return $accept;
+		}
+		return in_array(strtolower($language), $accept);
+	}
+
+/**
+ * Parse Accept* headers with qualifier options
+ *
+ * @param string $header
+ * @return array
+ */
+	protected static function _parseAcceptWithQualifier($header) {
+		$accept = array();
+		$header = explode(',', $header);
+		foreach (array_filter($header) as $value) {
+			$prefPos = strpos($value, ';');
+			if ($prefPos !== false) {
+				$prefValue = substr($value, strpos($value, '=') + 1);
+				$value = trim(substr($value, 0, $prefPos));
+			} else {
+				$prefValue = '1.0';
+				$value = trim($value);
+			}
+			if (!isset($accept[$prefValue])) {
+				$accept[$prefValue] = array();
+			}
+			if ($prefValue) {
+				$accept[$prefValue][] = $value;
+			}
 		}
-		return in_array($language, $accepts);
+		krsort($accept);
+		return $accept;
 	}
 
 /**

+ 23 - 1
lib/Cake/Test/Case/Network/CakeRequestTest.php

@@ -1746,19 +1746,41 @@ class CakeRequestTest extends CakeTestCase {
  * @return void
  */
 	public function testAcceptLanguage() {
+		// Weird language
 		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'inexistent,en-ca';
 		$result = CakeRequest::acceptLanguage();
 		$this->assertEquals(array('inexistent', 'en-ca'), $result, 'Languages do not match');
 
-		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'es_mx;en_ca';
+		// No qualifier
+		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'es_mx,en_ca';
 		$result = CakeRequest::acceptLanguage();
 		$this->assertEquals(array('es-mx', 'en-ca'), $result, 'Languages do not match');
 
+		// With qualifier
+		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US,en;q=0.8,pt-BR;q=0.6,pt;q=0.4';
+		$result = CakeRequest::acceptLanguage();
+		$this->assertEquals(array('en-us', 'en', 'pt-br', 'pt'), $result, 'Languages do not match');
+
+		// With spaces
+		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'da, en-gb;q=0.8, en;q=0.7';
+		$result = CakeRequest::acceptLanguage();
+		$this->assertEquals(array('da', 'en-gb', 'en'), $result, 'Languages do not match');
+
+		// Checking if requested
+		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'es_mx,en_ca';
+		$result = CakeRequest::acceptLanguage();
+
 		$result = CakeRequest::acceptLanguage('en-ca');
 		$this->assertTrue($result);
 
+		$result = CakeRequest::acceptLanguage('en-CA');
+		$this->assertTrue($result);
+
 		$result = CakeRequest::acceptLanguage('en-us');
 		$this->assertFalse($result);
+
+		$result = CakeRequest::acceptLanguage('en-US');
+		$this->assertFalse($result);
 	}
 
 /**