Fix cookie component being inconsistent about writes.

Instead of treating multi-key and single key writes differently, they
should be treated consistently to allow simpler and more consistent interactions
with the stored data. This also results in fewer cookies being sent
across the wire which is an added benefit.

Fixes #2182
This commit is contained in:
mark_story 2013-10-28 22:34:25 -04:00
parent eef2d919af
commit 07f4779efe
2 changed files with 57 additions and 9 deletions

View file

@ -230,17 +230,27 @@ class CookieComponent extends Component {
} }
foreach ($key as $name => $value) { foreach ($key as $name => $value) {
if (strpos($name, '.') === false) { $names = array($name);
$this->_values[$this->name][$name] = $value; if (strpos($name, '.') !== false) {
$this->_write("[$name]", $value);
} else {
$names = explode('.', $name, 2); $names = explode('.', $name, 2);
if (!isset($this->_values[$this->name][$names[0]])) {
$this->_values[$this->name][$names[0]] = array();
}
$this->_values[$this->name][$names[0]] = Hash::insert($this->_values[$this->name][$names[0]], $names[1], $value);
$this->_write('[' . implode('][', $names) . ']', $value);
} }
$firstName = $names[0];
$isMultiValue = (is_array($value) || count($names) > 1);
if (!isset($this->_values[$this->name][$firstName]) && $isMultiValue) {
$this->_values[$this->name][$firstName] = array();
}
if (count($names) > 1) {
$this->_values[$this->name][$firstName] = Hash::insert(
$this->_values[$this->name][$firstName],
$names[1],
$value
);
} else {
$this->_values[$this->name][$firstName] = $value;
}
$this->_write('[' . $firstName . ']', $this->_values[$this->name][$firstName]);
} }
$this->_encrypted = true; $this->_encrypted = true;
} }

View file

@ -327,6 +327,44 @@ class CookieComponentTest extends CakeTestCase {
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
/**
* Test that writing mixed arrays results in the correct data.
*
* @return void
*/
public function testWriteMixedArray() {
$this->Cookie->encrypt = false;
$this->Cookie->write('User', array('name' => 'mark'), false);
$this->Cookie->write('User.email', 'mark@example.com', false);
$expected = array(
'name' => $this->Cookie->name . '[User]',
'value' => '{"name":"mark","email":"mark@example.com"}',
'path' => '/',
'domain' => '',
'secure' => false,
'httpOnly' => false
);
$result = $this->Controller->response->cookie($this->Cookie->name . '[User]');
unset($result['expire']);
$this->assertEquals($expected, $result);
$this->Cookie->write('User.email', 'mark@example.com', false);
$this->Cookie->write('User', array('name' => 'mark'), false);
$expected = array(
'name' => $this->Cookie->name . '[User]',
'value' => '{"name":"mark"}',
'path' => '/',
'domain' => '',
'secure' => false,
'httpOnly' => false
);
$result = $this->Controller->response->cookie($this->Cookie->name . '[User]');
unset($result['expire']);
$this->assertEquals($expected, $result);
}
/** /**
* testReadingCookieValue * testReadingCookieValue
* *