Refactoring how q values are parsed, as content types were

reversed for similar q value types.  This causes issues in
RequestHandlerComponent.
This commit is contained in:
Mark Story mark@mark-story.com 2011-09-01 00:15:27 +01:00
parent ef4bb2239e
commit e2f48b4a95
2 changed files with 53 additions and 16 deletions

View file

@ -613,29 +613,49 @@ class CakeRequest implements ArrayAccess {
* provided type.
*/
public function accepts($type = null) {
$raw = $this->parseAccept();
$accept = array();
$header = explode(',', $this->header('accept'));
foreach (array_filter(array_reverse($header)) as $value) {
$prefPos = strpos($value, ';');
if ($prefPos !== false) {
$prefValue = (float) substr($value, strpos($value, '=') + 1);
$value = trim(substr($value, 0, $prefPos));
} else {
$prefValue = 1.0;
$value = trim($value);
}
if ($prefValue) {
$accept[$value] = $prefValue;
}
foreach ($raw as $value => $types) {
$accept = array_merge($accept, $types);
}
arsort($accept);
$accept = array_keys($accept);
if ($type === null) {
return $accept;
}
return in_array($type, $accept);
}
/**
* Parse the HTTP_ACCEPT header and return a sorted array with content types
* as the keys, and pref values as the values.
*
* Generally you want to use CakeRequest::accept() to get a simple list
* of the accepted content types.
*
* @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;
}
/**
* Get the lanaguages accepted by the client, or check if a specific language is accepted.
*

View file

@ -785,7 +785,7 @@ class CakeRequestTestCase extends CakeTestCase {
$result = $request->accepts();
$expected = array(
'text/xml', 'application/xhtml+xml', 'text/html', 'image/png', 'text/plain', 'application/xml'
'text/xml', 'application/xhtml+xml', 'text/html', 'text/plain', 'image/png', 'application/xml'
);
$this->assertEquals($expected, $result, 'Content types differ.');
@ -826,6 +826,23 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertEquals($expected, $result);
}
/**
* Test the raw parsing of accept headers into the q value formatting.
*
* @return void
*/
public function testParseAcceptWithQValue() {
$_SERVER['HTTP_ACCEPT'] = 'text/html;q=0.8,application/json;q=0.7,application/xml;q=1.0,image/png';
$request = new CakeRequest('/', false);
$result = $request->parseAccept();
$expected = array(
'1.0' => array('application/xml', 'image/png'),
'0.8' => array('text/html'),
'0.7' => array('application/json'),
);
$this->assertEquals($expected, $result);
}
/**
* testBaseUrlAndWebrootWithModRewrite method
*