Skip to content

Commit

Permalink
Fix #27: Add the parameter $encodeValue to the Cookie constructor…
Browse files Browse the repository at this point in the history
… and the `Cookie::withRawValue()` method that creates a cookie copy with a new value that will not be encoded
  • Loading branch information
vjik committed May 22, 2021
1 parent 6285385 commit 3a7b32e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 10 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -3,7 +3,8 @@

## 1.1.1 under development

- no changes in this release.
- Add #27: Add the parameter `$encodeValue` to the `Cookie` constructor and the `Cookie::withRawValue()` method
that creates a cookie copy with a new value that will not be encoded (vjik)


## 1.1.0 May 05, 2021
Expand Down
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -140,6 +140,13 @@ $middleware = new \Yiisoft\Cookies\CookieMiddleware(
$response = $middleware->process($request, $handler);
```

Create cookie with raw value that will not be encoded:

```php
$cookie = (new \Yiisoft\Cookies\Cookie('cookieName'))
->withRawValue('ebaKUq90PhiHck_MR7st-E1SxhbYWiTsLo82mCTbNuAh7rgflx5LVsYfJJseyQCrODuVcJkTSYhm1WKte-l5lQ==')
```

See [Yii guide to cookies](https://github.com/yiisoft/docs/blob/master/guide/en/runtime/cookies.md) for more info.

## Testing
Expand Down
35 changes: 26 additions & 9 deletions src/Cookie.php
Expand Up @@ -70,6 +70,11 @@ final class Cookie
*/
private string $value;

/**
* @var bool Whether cookie value should be encoded.
*/
private bool $encodeValue;

/**
* @var DateTimeInterface|null The maximum lifetime of the cookie.
* If unspecified, the cookie becomes a session cookie, which will be removed
Expand Down Expand Up @@ -127,6 +132,7 @@ final class Cookie
* @param bool|null $secure Whether the client should send back the cookie only over HTTPS connection.
* @param bool|null $httpOnly Whether the cookie should be accessible only through the HTTP protocol.
* @param string|null $sameSite Whether the cookie should be available for cross-site requests.
* @param bool $encodeValue Whether cookie value should be encoded.
*
* @throws InvalidArgumentException When one or more arguments are not valid.
*/
Expand All @@ -138,14 +144,16 @@ public function __construct(
?string $path = '/',
?bool $secure = true,
?bool $httpOnly = true,
?string $sameSite = self::SAME_SITE_LAX
?string $sameSite = self::SAME_SITE_LAX,
bool $encodeValue = true
) {
if (!preg_match(self::PATTERN_TOKEN, $name)) {
throw new InvalidArgumentException("The cookie name \"$name\" contains invalid characters or is empty.");
}

$this->name = $name;
$this->setValue($value);
$this->value = $value;
$this->encodeValue = $encodeValue;
$this->expires = $expires !== null ? clone $expires : null;
$this->domain = $domain;
$this->setPath($path);
Expand Down Expand Up @@ -176,7 +184,21 @@ public function getName(): string
public function withValue(string $value): self
{
$new = clone $this;
$new->setValue($value);
$new->value = $value;
$new->encodeValue = true;
return $new;
}

/**
* Creates a cookie copy with a new value that will not be encoded.
*
* @param $value string Value of the cookie.
*/
public function withRawValue(string $value): self
{
$new = clone $this;
$new->value = $value;
$new->encodeValue = false;
return $new;
}

Expand All @@ -190,11 +212,6 @@ public function getValue(): string
return $this->value;
}

private function setValue(string $value): void
{
$this->value = $value;
}

/**
* Creates a cookie copy with a new time the cookie expires.
*
Expand Down Expand Up @@ -450,7 +467,7 @@ public function addToResponse(ResponseInterface $response): ResponseInterface
public function __toString(): string
{
$cookieParts = [
$this->name . '=' . urlencode($this->value),
$this->name . '=' . ($this->encodeValue ? urlencode($this->value) : $this->value),
];

if ($this->expires !== null) {
Expand Down
9 changes: 9 additions & 0 deletions tests/CookieTest.php
Expand Up @@ -292,6 +292,14 @@ public function testGetters(): void
$this->assertEquals(Cookie::SAME_SITE_LAX, $cookie->getSameSite());
}

public function testRawValue(): void
{
$cookie = (new Cookie('test'))->withRawValue('Q==');

$this->assertSame('Q==', $cookie->getValue());
$this->assertSame('test=Q==; Path=/; Secure; HttpOnly; SameSite=Lax', (string)$cookie);
}

public function testImmutability(): void
{
$expires = new DateTime();
Expand All @@ -310,6 +318,7 @@ public function testImmutability(): void
$this->assertNotSame($original, $original->withSameSite(Cookie::SAME_SITE_LAX));
$this->assertNotSame($original, $original->withSecure(true));
$this->assertNotSame($original, $original->withValue('value'));
$this->assertNotSame($original, $original->withRawValue('value'));
$this->assertNotSame($original, $original->expire());
$this->assertNotSame($original, $original->expireWhenBrowserIsClosed());
}
Expand Down

0 comments on commit 3a7b32e

Please sign in to comment.