Skip to content
Permalink
Browse files

Add lazy reading of cookie data.

Individual cookie values are now read on an ad hoc basis as they are
accessed. This alleviates issues where javascript libraries add cookies
that CookieComponent does not know about. Previously, these cookies
would trigger encrypted cookie warnings.

Unfortunately reading cookies lazily means we don't have a way to read
*all* cookies.

Refs #3814
  • Loading branch information...
markstory committed Jun 27, 2014
1 parent 170e6ff commit 849a04f8970f176e2d3ca12266df19df313e4d46
@@ -86,6 +86,17 @@ class CookieComponent extends Component {
*/
protected $_values = [];
/**
* A map of keys that have been loaded.
*
* Since CookieComponent lazily reads cookie data,
* we need to track which cookies have been read to account for
* read, delete, read patterns.
*
* @var array
*/
protected $_loaded = [];
/**
* A reference to the Controller's Cake\Network\Response object
*
@@ -193,16 +204,14 @@ public function implementedEvents() {
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::write
*/
public function write($key, $value = null) {
if (empty($this->_values)) {
$this->_load();
}
if (!is_array($key)) {
$key = array($key => $value);
}
$keys = [];
foreach ($key as $name => $value) {
$this->_load($name);
$this->_values = Hash::insert($this->_values, $name, $value);
$parts = explode('.', $name);
$keys[] = $parts[0];
@@ -219,17 +228,12 @@ public function write($key, $value = null) {
* This method will also allow you to read cookies that have been written in this
* request, but not yet sent to the client.
*
* @param string $key Key of the value to be obtained. If none specified, obtain map key => values
* @param string $key Key of the value to be obtained.
* @return string or null, value for specified key
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::read
*/
public function read($key = null) {
if (empty($this->_values)) {
$this->_load();
}
if ($key === null) {
return $this->_values;
}
$this->_load($key);
return Hash::get($this->_values, $key);
}
@@ -239,13 +243,22 @@ public function read($key = null) {
* Based on the configuration data, cookies will be decrypted. When cookies
* contain array data, that data will be expanded.
*
* @param string|array $key The key to load.
* @return void
*/
protected function _load() {
foreach ($this->_request->cookies as $name => $value) {
$config = $this->configKey($name);
$this->_values[$name] = $this->_decrypt($value, $config['encryption']);
protected function _load($key) {
$parts = explode('.', $key);
$first = array_shift($parts);
if (isset($this->_loaded[$first])) {
return;
}
if (!isset($this->_request->cookies[$first])) {
return;
}
$cookie = $this->_request->cookies[$first];
$config = $this->configKey($first);
$this->_loaded[$first] = true;
$this->_values[$first] = $this->_decrypt($cookie, $config['encryption']);
}
/**
@@ -275,9 +288,7 @@ public function check($key = null) {
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::delete
*/
public function delete($key) {
if (empty($this->_values)) {
$this->_load();
}
$this->_load($key);
$this->_values = Hash::remove($this->_values, $key);
$parts = explode('.', $key);
@@ -431,34 +431,6 @@ public function testWriteMixedArray() {
$this->assertEquals($expected, $result);
}
/**
* test reading all values at once.
*
* @return void
*/
public function testReadingAllValues() {
$this->_setCookieData();
$data = $this->Cookie->read();
$expected = array(
'Encrytped_array' => array(
'name' => 'CakePHP',
'version' => '1.2.0.x',
'tag' => 'CakePHP Rocks!'),
'Encrypted_multi_cookies' => array(
'name' => 'CakePHP',
'version' => '1.2.0.x',
'tag' => 'CakePHP Rocks!'),
'Plain_array' => array(
'name' => 'CakePHP',
'version' => '1.2.0.x',
'tag' => 'CakePHP Rocks!'),
'Plain_multi_cookies' => array(
'name' => 'CakePHP',
'version' => '1.2.0.x',
'tag' => 'CakePHP Rocks!'));
$this->assertEquals($expected, $data);
}
/**
* testDeleteCookieValue
*

0 comments on commit 849a04f

Please sign in to comment.
You can’t perform that action at this time.