From 07f4779efef507c31291ca0f29222c1b06d626b8 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 28 Oct 2013 22:34:25 -0400 Subject: [PATCH] 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 --- .../Controller/Component/CookieComponent.php | 28 +++++++++----- .../Component/CookieComponentTest.php | 38 +++++++++++++++++++ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/lib/Cake/Controller/Component/CookieComponent.php b/lib/Cake/Controller/Component/CookieComponent.php index 4259f7e9f0e..59694df9123 100644 --- a/lib/Cake/Controller/Component/CookieComponent.php +++ b/lib/Cake/Controller/Component/CookieComponent.php @@ -230,17 +230,27 @@ public function write($key, $value = null, $encrypt = true, $expires = null) { } foreach ($key as $name => $value) { - if (strpos($name, '.') === false) { - $this->_values[$this->name][$name] = $value; - $this->_write("[$name]", $value); - } else { + $names = array($name); + if (strpos($name, '.') !== false) { $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; } diff --git a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php index 12371d83eee..9b0488f5723 100644 --- a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php @@ -327,6 +327,44 @@ public function testWriteArrayValues() { $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 *