diff --git a/composer.json b/composer.json index 73b55bc..dd979c7 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "php": ">=7.1", "ext-json": "*", "packaged/helpers": "^1.9||^2.0", + "packaged/config": "^1.2", "symfony/http-foundation": "~4.2" }, "require-dev": { diff --git a/src/Cookies/CookieHandler.php b/src/Cookies/CookieHandler.php new file mode 100644 index 0000000..60e5a97 --- /dev/null +++ b/src/Cookies/CookieHandler.php @@ -0,0 +1,52 @@ +_handlers[1000] = new DefaultHandler(); + } + + /** + * @param CookieHandler $handler + * @param int $priority + * @param bool $replace + * + * @return $this + * @throws \Exception + */ + public function addHandler(CookieHandler $handler, int $priority = 10, bool $replace = false) + { + if(isset($this->_handlers[$priority]) && !$replace) + { + throw new \Exception("A cookie handler already exists with priority " . $priority); + } + $this->_handlers[$priority] = $handler; + return $this; + } + + protected function _getHandler($name, $value): CookieHandler + { + foreach($this->_handlers as $handler) + { + if($handler->canHandle($name, $value)) + { + return $handler; + } + } + } + + public function hydrate(Request $request) + { + foreach($request->cookies->all() as $name => $cookie) + { + $handler = $this->_getHandler($name, $cookie); + $this->_requestCookies[$handler->decodeName($name)] = $handler->decodeValue($cookie); + } + } + + public function read(string $name, bool $checkQueued = false) + { + return $this->_requestCookies[$name] ?? + ($checkQueued && isset($this->_responseCookies[$name]) ? $this->_responseCookies[$name]['v'] : null); + } + + public function has(string $name): bool + { + return isset($this->_requestCookies[$name]) || isset($this->_responseCookies[$name]); + } + + public function store(string $name, string $value = null, $expireSeconds = 0) + { + unset($this->_deleteCookies[$name]); + $this->_responseCookies[$name] = ['v' => $value, 'e' => $expireSeconds > 0 ? (time() + $expireSeconds) : 0]; + return $this; + } + + public function delete(string $name) + { + unset($this->_responseCookies[$name], $this->_requestCookies[$name]); + $this->_deleteCookies[$name] = $name; + return $this; + } + + /** + * Apply cookies to a response object + * + * @param Response $response + * + * @return Response + * @throws \Exception + */ + public function applyToResponse(Response $response): Response + { + $domain = $this->_config()->getItem("domain"); + $secure = $this->_config()->getItem("secure_only", null); + + //Write cookies + foreach($this->_responseCookies as $name => $rc) + { + $handler = $this->_getHandler($name, $rc['v']); + $response->headers->setCookie( + Cookie::create( + $handler->encodeName($name), + $handler->encodeValue($rc['v']), + $rc['e'], + null, + $domain, + $secure, + true, + false + ) + ); + } + + //Delete Cookies + foreach($this->_deleteCookies as $cookieName) + { + $handler = $this->_getHandler($cookieName, null); + $response->headers->setCookie(Cookie::create($handler->encodeName($cookieName), null, '-2628000', null, $domain)); + } + + return $response; + } +} diff --git a/src/Cookies/DefaultHandler.php b/src/Cookies/DefaultHandler.php new file mode 100644 index 0000000..fbd5474 --- /dev/null +++ b/src/Cookies/DefaultHandler.php @@ -0,0 +1,32 @@ +