Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameter $encodeValue to Cookie constructor and Cookie::withRawValue() method #27

Merged
merged 1 commit into from
May 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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