Fix CookieComponent::delete() not working for deep children

This commit is contained in:
chinpei215 2017-10-16 20:55:00 +09:00
parent e85f489c1f
commit bbea91090d
2 changed files with 92 additions and 20 deletions

View file

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

View file

@ -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.
*