Skip to content

Commit

Permalink
Convert write() to use immutable patterns.
Browse files Browse the repository at this point in the history
Add withoutAddedValue as a way to remove keys from complex cookies.
  • Loading branch information
markstory committed Mar 19, 2017
1 parent 795cb1d commit 8dbd685
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 21 deletions.
60 changes: 42 additions & 18 deletions src/Http/Cookie/Cookie.php
Expand Up @@ -120,8 +120,15 @@ class Cookie implements CookieInterface
* @param bool $secure Is secure
* @param bool $httpOnly HTTP Only
*/
public function __construct($name, $value = '', $expiresAt = null, $path = '', $domain = '', $secure = false, $httpOnly = false)
{
public function __construct(
$name,
$value = '',
DateTimeInterface $expiresAt = null,
$path = '',
$domain = '',
$secure = false,
$httpOnly = false
) {
$this->validateName($name);
$this->name = $name;

Expand All @@ -140,7 +147,7 @@ public function __construct($name, $value = '', $expiresAt = null, $path = '', $
$this->secure = $secure;

if ($expiresAt !== null) {
$this->expiresAt($expiresAt);
$this->expiresAt = (int)$expiresAt->format('U');
}
}

Expand Down Expand Up @@ -186,17 +193,18 @@ public function toHeaderValue()
}

/**
* Sets the cookie name
* Create a cookie with an updated name
*
* @param string $name Name of the cookie
* @return $this
* @return static
*/
public function setName($name)
public function withName($name)
{
$this->validateName($name);
$this->name = $name;
$new = clone $this;
$new->name = $name;

return $this;
return $new;
}

/**
Expand Down Expand Up @@ -383,16 +391,17 @@ public function isHttpOnly()
}

/**
* Sets the expiration date
* Create a cookie with an updated expiration date
*
* @param \DateTimeInterface $dateTime Date time object
* @return $this
* @return static
*/
public function expiresAt(DateTimeInterface $dateTime)
public function withExpiry(DateTimeInterface $dateTime)
{
$this->expiresAt = (int)$dateTime->format('U');
$new = clone $this;
$new->expiresAt = (int)$dateTime->format('U');

return $this;
return $new;
}

/**
Expand Down Expand Up @@ -437,19 +446,34 @@ public function check($path)
}

/**
* Writes data to the cookie
* Create a new cookie with updated data.
*
* @param string $path Path to write to
* @param mixed $value Value to write
* @return $this
* @return static
*/
public function write($path, $value)
public function withAddedValue($path, $value)
{
$this->_isExpanded();
$new = clone $this;
$new->value = Hash::insert($new->value, $path, $value);

Hash::insert($this->value, $path, $value);
return $new;
}

return $this;
/**
* Create a new cookie without a specific path
*
* @param string $path Path to remove
* @return static
*/
public function withoutAddedValue($path)
{
$this->_isExpanded();
$new = clone $this;
$new->value = Hash::remove($new->value, $path);

return $new;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Cookie/CookieInterface.php
Expand Up @@ -22,9 +22,9 @@ interface CookieInterface
* Sets the cookie name
*
* @param string $name Name of the cookie
* @return $this
* @return static
*/
public function setName($name);
public function withName($name);

/**
* Gets the cookie name
Expand Down
67 changes: 66 additions & 1 deletion tests/TestCase/Http/Cookie/CookieTest.php
Expand Up @@ -98,9 +98,9 @@ public function testToHeaderValue()

$cookie = new Cookie('cakephp', 'cakephp-rocks');
$cookie = $cookie->withDomain('cakephp.org')
->withExpiry($date)
->withHttpOnly(true)
->withSecure(true);
$cookie->expiresAt($date);
$result = $cookie->toHeaderValue();

$expected = 'cakephp=cakephp-rocks; expires=Tue, 01-Dec-2026 12:00:00 GMT; domain=cakephp.org; secure; httponly';
Expand Down Expand Up @@ -308,11 +308,76 @@ public function testWithExpired()
$cookie = new Cookie('cakephp', 'cakephp-rocks');
$new = $cookie->withExpired();
$this->assertNotSame($new, $cookie, 'Should clone');
$this->assertNotContains('expiry', $cookie->toHeaderValue());

$now = Chronos::parse('-1 year');
$this->assertContains($now->format('Y'), $new->toHeaderValue());
}

/**
* Test the withExpiry method
*
* @return void
*/
public function testWithExpiry()
{
$cookie = new Cookie('cakephp', 'cakephp-rocks');
$new = $cookie->withExpiry(Chronos::createFromDate(2022, 6, 15));
$this->assertNotSame($new, $cookie, 'Should clone');
$this->assertNotContains('expires', $cookie->toHeaderValue());

$this->assertContains('expires=Wed, 15-Jun-2022', $new->toHeaderValue());
}

/**
* Test the withName method
*
* @return void
*/
public function testWithName()
{
$cookie = new Cookie('cakephp', 'cakephp-rocks');
$new = $cookie->withName('user');
$this->assertNotSame($new, $cookie, 'Should clone');
$this->assertNotSame('user', $cookie->getName());
$this->assertSame('user', $new->getName());
}

/**
* Test the withAddedValue method
*
* @return void
*/
public function testWithAddedValue()
{
$cookie = new Cookie('cakephp', '{"type":"mvc", "icing": true}');
$cookie->expand();
$new = $cookie->withAddedValue('type', 'mvc')
->withAddedValue('user.name', 'mark');
$this->assertNotSame($new, $cookie, 'Should clone');
$this->assertNull($cookie->read('user.name'));
$this->assertSame('mvc', $new->read('type'));
$this->assertSame('mark', $new->read('user.name'));
}

/**
* Test the withoutAddedValue method
*
* @return void
*/
public function testWithoutAddedValue()
{
$cookie = new Cookie('cakephp', '{"type":"mvc", "user": {"name":"mark"}}');
$cookie->expand();
$new = $cookie->withoutAddedValue('type', 'mvc')
->withoutAddedValue('user.name');
$this->assertNotSame($new, $cookie, 'Should clone');

$this->assertNotNull($cookie->read('type'));
$this->assertNull($new->read('type'));
$this->assertNull($new->read('user.name'));
}

/**
* testInflateAndExpand
*
Expand Down

0 comments on commit 8dbd685

Please sign in to comment.