generated from yiisoft/package-template
-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
I implemented a straightforward cookie collection mechanism that allo…
…ws for project work from any place
- Loading branch information
hcan359
committed
Oct 21, 2024
1 parent
22f829d
commit 8f3fbee
Showing
9 changed files
with
430 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Cookies\Exception; | ||
|
||
use LogicException; | ||
use Throwable; | ||
|
||
/** | ||
* Thrown when Request cookie collect isn't set before. | ||
*/ | ||
final class RequestCookieCollectionNotSetException extends LogicException | ||
{ | ||
public function __construct(int $code = 0, ?Throwable $previous = null) | ||
Check warning on line 15 in src/Exception/RequestCookieCollectionNotSetException.php GitHub Actions / mutation / PHP 8.1-ubuntu-latest
Check warning on line 15 in src/Exception/RequestCookieCollectionNotSetException.php GitHub Actions / mutation / PHP 8.1-ubuntu-latest
|
||
{ | ||
parent::__construct('Request cookie collect is not set.', $code, $previous); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Cookies; | ||
|
||
use InvalidArgumentException; | ||
|
||
/** | ||
* A CookieCollection helps to work with many cookies at once and to read request cookies. | ||
* | ||
* @see Cookie | ||
* | ||
*/ | ||
final class RequestCookieCollection | ||
{ | ||
/** | ||
* @var Cookie[] The cookies in this collection (indexed by the cookie name). | ||
* | ||
* @psalm-var array<string, Cookie> | ||
*/ | ||
private array $cookies = []; | ||
|
||
/** | ||
* CookieCollection constructor. | ||
* | ||
* @param array|Cookie[] $cookies The cookies that this collection initially contains. | ||
*/ | ||
public function __construct(array $cookies = []) | ||
{ | ||
foreach ($cookies as $cookie) { | ||
if (!($cookie instanceof Cookie)) { | ||
throw new InvalidArgumentException('CookieCollection can contain only Cookie instances.'); | ||
} | ||
|
||
$this->cookies[$cookie->getName()] = $cookie; | ||
} | ||
} | ||
|
||
/** | ||
* Returns the value of the named cookie. | ||
* | ||
* @param string $name The cookie name. | ||
* @param string|null $defaultValue The value that should be returned when the named cookie does not exist. | ||
* | ||
* @return string|null The value of the named cookie or the default value if cookie is not set. | ||
* | ||
* @see get() | ||
*/ | ||
public function getValue(string $name, ?string $defaultValue = null): ?string | ||
{ | ||
return isset($this->cookies[$name]) ? $this->cookies[$name]->getValue() : $defaultValue; | ||
} | ||
|
||
/** | ||
* Returns the cookie with the specified name. | ||
* | ||
* @param string $name The cookie name. | ||
* | ||
* @return Cookie|null The cookie with the specified name. Null if the named cookie does not exist. | ||
* | ||
* @see getValue() | ||
*/ | ||
public function get(string $name): ?Cookie | ||
{ | ||
return $this->cookies[$name] ?? null; | ||
} | ||
|
||
/** | ||
* Returns whether there is a cookie with the specified name. | ||
* | ||
* @param string $name The cookie name. | ||
* | ||
* @return bool Whether the named cookie exists. | ||
* | ||
* @see remove() | ||
*/ | ||
public function has(string $name): bool | ||
{ | ||
return isset($this->cookies[$name]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Cookies; | ||
|
||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
use Psr\Http\Server\MiddlewareInterface; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
|
||
/** | ||
* Stores cookies request {@see RequestCookieProviderInterface}. | ||
* You need to add this into your application middleware stack. | ||
*/ | ||
final class RequestCookieCollectionMiddleware implements MiddlewareInterface | ||
{ | ||
private RequestCookieProviderInterface $cookieProvider; | ||
|
||
public function __construct(RequestCookieProviderInterface $cookieProvider) | ||
{ | ||
$this->cookieProvider = $cookieProvider; | ||
} | ||
|
||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface | ||
{ | ||
$cookies = $this->collectCookies($request); | ||
$this->cookieProvider->set(new RequestCookieCollection($cookies)); | ||
return $handler->handle($request); | ||
} | ||
|
||
private function collectCookies(ServerRequestInterface $request): array | ||
{ | ||
$collection = []; | ||
foreach ($request->getCookieParams() as $name => $value) { | ||
if (!is_string($name) || !is_string($value)) { | ||
continue; | ||
} | ||
$collection[] = (new Cookie($name, $value)); | ||
} | ||
return $collection; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Cookies; | ||
|
||
use Yiisoft\Cookies\Exception\RequestCookieCollectionNotSetException; | ||
|
||
/** | ||
* Stores request for further consumption by attribute handlers. | ||
*/ | ||
final class RequestCookieProvider implements RequestCookieProviderInterface | ||
{ | ||
/** | ||
* @var RequestCookieCollection|null The collection. | ||
*/ | ||
private ?RequestCookieCollection $cookieCollection = null; | ||
|
||
public function set(RequestCookieCollection $cookieCollection): void | ||
{ | ||
$this->cookieCollection = $cookieCollection; | ||
} | ||
|
||
public function get(): RequestCookieCollection | ||
{ | ||
if ($this->cookieCollection === null) { | ||
throw new RequestCookieCollectionNotSetException(); | ||
} | ||
|
||
return $this->cookieCollection; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Cookies; | ||
|
||
use Yiisoft\Cookies\Exception\RequestCookieCollectionNotSetException; | ||
|
||
/** | ||
* Provides a way to set the current cookie collection and then get it when needed. | ||
*/ | ||
interface RequestCookieProviderInterface | ||
{ | ||
/** | ||
* Set the current cookie request collection. | ||
* | ||
* @param RequestCookieCollection $cookieCollection The collection to set. | ||
*/ | ||
public function set(RequestCookieCollection $cookieCollection): void; | ||
|
||
/** | ||
* Get the current request cookie collection. | ||
* | ||
* @throws RequestCookieCollectionNotSetException | ||
*/ | ||
public function get(): RequestCookieCollection; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Cookies\Tests; | ||
|
||
use InvalidArgumentException; | ||
use PHPUnit\Framework\TestCase; | ||
use Yiisoft\Cookies\Cookie; | ||
use Yiisoft\Cookies\RequestCookieCollection; | ||
|
||
final class LocalCookieCollectionTest extends TestCase | ||
{ | ||
public function testConstructorWithInvalidArray(): void | ||
{ | ||
$this->expectException(InvalidArgumentException::class); | ||
new RequestCookieCollection([new Cookie('test'), 'string']); | ||
} | ||
|
||
public function testGet(): void | ||
{ | ||
$cookie = new Cookie('test'); | ||
$collection = new RequestCookieCollection([$cookie]); | ||
$this->assertEquals($cookie, $collection->get('test')); | ||
} | ||
|
||
public function testGetNonExisting(): void | ||
{ | ||
$collection = new RequestCookieCollection([]); | ||
$this->assertEquals(null, $collection->get('test')); | ||
} | ||
|
||
public function testGetValue(): void | ||
{ | ||
$cookie = new Cookie('test', 'testVal'); | ||
$collection = new RequestCookieCollection([$cookie]); | ||
|
||
$this->assertEquals('testVal', $collection->getValue('test')); | ||
} | ||
|
||
public function testExpireWithNonExistingKey(): void | ||
{ | ||
$cookie = new Cookie('test', 'testVal'); | ||
$collection = new RequestCookieCollection([$cookie]); | ||
|
||
$this->assertTrue($collection->has('test')); | ||
$this->assertFalse($collection->has('test2')); | ||
} | ||
} |
Oops, something went wrong.