Skip to content

Commit

Permalink
Add cookie collection methods to ServerRequest.
Browse files Browse the repository at this point in the history
I've chosen to not use CookieCollection as the internal storage as
keeping the public property in-sync would be hard/impossible. This
approach also avoid eagerly allocating memory for the cookie collection
and the cookie objects.
  • Loading branch information
markstory committed Apr 3, 2017
1 parent d1bd022 commit 13353f7
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/Http/ServerRequest.php
Expand Up @@ -17,6 +17,7 @@
use ArrayAccess;
use BadMethodCallException;
use Cake\Core\Configure;
use Cake\Http\Cookie\CookieCollection;
use Cake\Network\Exception\MethodNotAllowedException;
use Cake\Network\Session;
use Cake\Utility\Hash;
Expand Down Expand Up @@ -1605,6 +1606,45 @@ public function getCookie($key, $default = null)
return Hash::get($this->cookies, $key, $default);
}

/**
* Get a cookie collection based on the request's cookies
*
* The CookieCollection lets you interact with request cookies using
* `\Cake\Http\Cookie\Cookie` objects and can make converting request cookies
* into response cookies easier.
*
* This method will create a new cookie collection each time it is called.
* This is an optimization that allows fewer objects to be allocated until
* the more complex CookieCollection is needed. In general you should prefer
* `getCookie()` and `getCookieParams()` over this method. Using a CookieCollection
* is ideal if your cookies contain complex JSON encoded data.
*
* @return \Cake\Http\Cookie\CookieCollection
*/
public function getCookieCollection()
{
return CookieCollection::createFromServerRequest($this);
}

/**
* Replace the cookies in the request with those contained in
* the provided CookieCollection.
*
* @param \Cake\Http\Cookie\CookieCollection $cookies The cookie collection
* @return static
*/
public function withCookieCollection(CookieCollection $cookies)
{
$new = clone $this;
$values = [];
foreach ($cookies as $cookie) {
$values[$cookie->getName()] = $cookie->getValue();
}
$new->cookies = $values;

return $new;
}

/**
* Get all the cookie data from the request.
*
Expand Down
41 changes: 41 additions & 0 deletions tests/TestCase/Http/ServerRequestTest.php
Expand Up @@ -15,6 +15,8 @@
namespace Cake\Test\TestCase\Http;

use Cake\Core\Configure;
use Cake\Http\Cookie\Cookie;
use Cake\Http\Cookie\CookieCollection;
use Cake\Http\ServerRequest;
use Cake\Http\ServerRequestFactory;
use Cake\Network\Exception\MethodNotAllowedException;
Expand Down Expand Up @@ -3080,6 +3082,45 @@ public function testWithCookieParams()
$this->assertSame(['remember_me' => 1], $new->getCookieParams());
}

/**
* Test getting a cookie collection from a request.
*
* @return void
*/
public function testGetCookieCollection()
{
$cookies = [
'remember_me' => '1',
'color' => 'blue'
];
$request = new ServerRequest(['cookies' => $cookies]);

$cookies = $request->getCookieCollection();
$this->assertInstanceOf(CookieCollection::class, $cookies);
$this->assertCount(2, $cookies);
$this->assertSame('1', $cookies->get('remember_me')->getValue());
$this->assertSame('blue', $cookies->get('color')->getValue());
}

/**
* Test replacing cookies from a collection
*
* @return void
*/
public function testWithCookieCollection()
{
$cookies = new CookieCollection([new Cookie('remember_me', 1), new Cookie('color', 'red')]);
$request = new ServerRequest(['cookies' => ['bad' => 'goaway']]);
$new = $request->withCookieCollection($cookies);
$this->assertNotSame($new, $request, 'Should clone');

$this->assertSame(['bad' => 'goaway'], $request->getCookieParams());
$this->assertSame(['remember_me' => 1, 'color' => 'red'], $new->getCookieParams());
$cookies = $new->getCookieCollection();
$this->assertCount(2, $cookies);
$this->assertSame('red', $cookies->get('color')->getValue());
}

/**
* TestAllowMethod
*
Expand Down

0 comments on commit 13353f7

Please sign in to comment.