Skip to content

Commit

Permalink
Cookie Jar
Browse files Browse the repository at this point in the history
  • Loading branch information
bajb committed Nov 28, 2019
1 parent 6813322 commit 30b6739
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
52 changes: 52 additions & 0 deletions src/Cookies/CookieHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Packaged\Http\Cookies;

interface CookieHandler
{
/**
* Check to see if the handler can handle a cookie
*
* @param string $name
* @param string|null $value
*
* @return bool
*/
public function canHandle(string $name, string $value = null): bool;

/**
* Decode a cookie name from transport
*
* @param string $name
*
* @return string
*/
public function decodeName(string $name): string;

/**
* Encode a cookie name for transport
*
* @param string $name
*
* @return string
*/
public function encodeName(string $name): string;

/**
* Decode a cookie value from transport
*
* @param string $value
*
* @return string
*/
public function decodeValue(string $value): string;

/**
* Encode a cookie value for transport
*
* @param string $value
*
* @return string
*/
public function encodeValue(string $value): string;
}
138 changes: 138 additions & 0 deletions src/Cookies/CookieJar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

namespace Packaged\Http\Cookies;

use Packaged\Config\ConfigurableInterface;
use Packaged\Config\ConfigurableTrait;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class CookieJar implements ConfigurableInterface
{
use ConfigurableTrait;

/**
* @var CookieHandler[]
*/
protected $_handlers = [];

/**
* @var Cookie[]
*/
protected $_responseCookies = [];
/**
* @var string[]
*/
protected $_requestCookies = [];
protected $_deleteCookies = [];

public function __construct()
{
$this->_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;
}
}
32 changes: 32 additions & 0 deletions src/Cookies/DefaultHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Packaged\Http\Cookies;

class DefaultHandler implements CookieHandler
{
public function canHandle(string $name, string $value = null): bool
{
return true;
}

public function decodeName(string $name): string
{
return $name;
}

public function encodeName(string $name): string
{
return $name;
}

public function decodeValue(string $value): string
{
return $value;
}

public function encodeValue(string $value): string
{
return $value;
}

}

0 comments on commit 30b6739

Please sign in to comment.