Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix CookieComponent::delete() not working for deep children
  • Loading branch information
chinpei215 committed Oct 16, 2017
1 parent e85f489 commit bbea910
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 20 deletions.
29 changes: 9 additions & 20 deletions lib/Cake/Controller/Component/CookieComponent.php
Expand Up @@ -316,20 +316,16 @@ public function delete($key) {
$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;
}
$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('[' . $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);
}
}
$this->_delete('[' . implode('][', $names) . ']');
}

/**
Expand All @@ -347,14 +343,7 @@ public function destroy() {
}

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);
}
}

Expand Down
83 changes: 83 additions & 0 deletions lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php
Expand Up @@ -807,6 +807,89 @@ public function testDeleteChildrenNotExist() {
$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.
*
Expand Down

0 comments on commit bbea910

Please sign in to comment.