diff --git a/lib/Cake/Controller/Component/CookieComponent.php b/lib/Cake/Controller/Component/CookieComponent.php index 5aeb5a365..a8ad8bbbe 100644 --- a/lib/Cake/Controller/Component/CookieComponent.php +++ b/lib/Cake/Controller/Component/CookieComponent.php @@ -316,20 +316,16 @@ class CookieComponent extends Component { $this->read(); } if (strpos($key, '.') === false) { - if (isset($this->_values[$this->name][$key]) && is_array($this->_values[$this->name][$key])) { - foreach ($this->_values[$this->name][$key] as $idx => $val) { - $this->_delete("[$key][$idx]"); - } - } - $this->_delete("[$key]"); unset($this->_values[$this->name][$key]); - return; + $this->_delete('[' . $key . ']'); + } else { + $this->_values[$this->name] = Hash::remove((array)$this->_values[$this->name], $key); + list($key) = explode('.', $key, 2); + if (isset($this->_values[$this->name][$key])) { + $value = $this->_values[$this->name][$key]; + $this->_write('[' . $key . ']', $value); + } } - $names = explode('.', $key, 2); - if (isset($this->_values[$this->name][$names[0]]) && is_array($this->_values[$this->name][$names[0]])) { - $this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]); - } - $this->_delete('[' . implode('][', $names) . ']'); } /** @@ -347,14 +343,7 @@ class CookieComponent extends Component { } foreach ($this->_values[$this->name] as $name => $value) { - if (is_array($value)) { - foreach ($value as $key => $val) { - unset($this->_values[$this->name][$name][$key]); - $this->_delete("[$name][$key]"); - } - } - unset($this->_values[$this->name][$name]); - $this->_delete("[$name]"); + $this->delete($name); } } diff --git a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php index ea2f4998b..5524e3366 100644 --- a/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php @@ -807,6 +807,89 @@ class CookieComponentTest extends CakeTestCase { $this->assertNull($this->Cookie->delete('Not.Found')); } +/** + * Test deleting deep child elements sends correct cookies. + * + * @return void + */ + public function testDeleteDeepChildren() { + $_COOKIE = array( + 'CakeTestCookie' => array( + 'foo' => $this->_encrypt(array( + 'bar' => array( + 'baz' => 'value', + ), + )), + ), + ); + + $this->Cookie->delete('foo.bar.baz'); + + $cookies = $this->Controller->response->cookie(); + $expected = array( + 'CakeTestCookie[foo]' => array( + 'name' => 'CakeTestCookie[foo]', + 'value' => '{"bar":[]}', + 'path' => '/', + 'domain' => '', + 'secure' => false, + 'httpOnly' => false + ), + ); + + $expires = Hash::combine($cookies, '{*}.name', '{*}.expire'); + $cookies = Hash::remove($cookies, '{*}.expire'); + $this->assertEquals($expected, $cookies); + + $this->assertWithinMargin($expires['CakeTestCookie[foo]'], time() + 10, 2); + } + +/** + * Test destroy works. + * + * @return void + */ + public function testDestroy() { + $_COOKIE = array( + 'CakeTestCookie' => array( + 'foo' => $this->_encrypt(array( + 'bar' => array( + 'baz' => 'value', + ), + )), + 'other' => 'value', + ), + ); + + $this->Cookie->destroy(); + + $cookies = $this->Controller->response->cookie(); + $expected = array( + 'CakeTestCookie[foo]' => array( + 'name' => 'CakeTestCookie[foo]', + 'value' => '', + 'path' => '/', + 'domain' => '', + 'secure' => false, + 'httpOnly' => false + ), + 'CakeTestCookie[other]' => array( + 'name' => 'CakeTestCookie[other]', + 'value' => '', + 'path' => '/', + 'domain' => '', + 'secure' => false, + 'httpOnly' => false + ), + ); + + $expires = Hash::combine($cookies, '{*}.name', '{*}.expire'); + $cookies = Hash::remove($cookies, '{*}.expire'); + $this->assertEquals($expected, $cookies); + $this->assertWithinMargin($expires['CakeTestCookie[foo]'], time() - 42000, 2); + $this->assertWithinMargin($expires['CakeTestCookie[other]'], time() - 42000, 2); + } + /** * Helper method for generating old style encoded cookie values. *