View source
<?php
namespace GuzzleHttp\Cookie;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class CookieJar implements CookieJarInterface {
private $cookies = [];
private $strictMode;
public function __construct($strictMode = false, $cookieArray = []) {
$this->strictMode = $strictMode;
foreach ($cookieArray as $cookie) {
if (!$cookie instanceof SetCookie) {
$cookie = new SetCookie($cookie);
}
$this
->setCookie($cookie);
}
}
public static function fromArray(array $cookies, $domain) {
$cookieJar = new self();
foreach ($cookies as $name => $value) {
$cookieJar
->setCookie(new SetCookie([
'Domain' => $domain,
'Name' => $name,
'Value' => $value,
'Discard' => true,
]));
}
return $cookieJar;
}
public static function getCookieValue($value) {
return $value;
}
public static function shouldPersist(SetCookie $cookie, $allowSessionCookies = false) {
if ($cookie
->getExpires() || $allowSessionCookies) {
if (!$cookie
->getDiscard()) {
return true;
}
}
return false;
}
public function getCookieByName($name) {
if ($name === null) {
return null;
}
foreach ($this->cookies as $cookie) {
if ($cookie
->getName() !== null && strcasecmp($cookie
->getName(), $name) === 0) {
return $cookie;
}
}
}
public function toArray() {
return array_map(function (SetCookie $cookie) {
return $cookie
->toArray();
}, $this
->getIterator()
->getArrayCopy());
}
public function clear($domain = null, $path = null, $name = null) {
if (!$domain) {
$this->cookies = [];
return;
}
elseif (!$path) {
$this->cookies = array_filter($this->cookies, function (SetCookie $cookie) use ($path, $domain) {
return !$cookie
->matchesDomain($domain);
});
}
elseif (!$name) {
$this->cookies = array_filter($this->cookies, function (SetCookie $cookie) use ($path, $domain) {
return !($cookie
->matchesPath($path) && $cookie
->matchesDomain($domain));
});
}
else {
$this->cookies = array_filter($this->cookies, function (SetCookie $cookie) use ($path, $domain, $name) {
return !($cookie
->getName() == $name && $cookie
->matchesPath($path) && $cookie
->matchesDomain($domain));
});
}
}
public function clearSessionCookies() {
$this->cookies = array_filter($this->cookies, function (SetCookie $cookie) {
return !$cookie
->getDiscard() && $cookie
->getExpires();
});
}
public function setCookie(SetCookie $cookie) {
$name = $cookie
->getName();
if (!$name && $name !== '0') {
return false;
}
$result = $cookie
->validate();
if ($result !== true) {
if ($this->strictMode) {
throw new \RuntimeException('Invalid cookie: ' . $result);
}
else {
$this
->removeCookieIfEmpty($cookie);
return false;
}
}
foreach ($this->cookies as $i => $c) {
if ($c
->getPath() != $cookie
->getPath() || $c
->getDomain() != $cookie
->getDomain() || $c
->getName() != $cookie
->getName()) {
continue;
}
if (!$cookie
->getDiscard() && $c
->getDiscard()) {
unset($this->cookies[$i]);
continue;
}
if ($cookie
->getExpires() > $c
->getExpires()) {
unset($this->cookies[$i]);
continue;
}
if ($cookie
->getValue() !== $c
->getValue()) {
unset($this->cookies[$i]);
continue;
}
return false;
}
$this->cookies[] = $cookie;
return true;
}
public function count() {
return count($this->cookies);
}
public function getIterator() {
return new \ArrayIterator(array_values($this->cookies));
}
public function extractCookies(RequestInterface $request, ResponseInterface $response) {
if ($cookieHeader = $response
->getHeader('Set-Cookie')) {
foreach ($cookieHeader as $cookie) {
$sc = SetCookie::fromString($cookie);
if (!$sc
->getDomain()) {
$sc
->setDomain($request
->getUri()
->getHost());
}
if (0 !== strpos($sc
->getPath(), '/')) {
$sc
->setPath($this
->getCookiePathFromRequest($request));
}
$this
->setCookie($sc);
}
}
}
private function getCookiePathFromRequest(RequestInterface $request) {
$uriPath = $request
->getUri()
->getPath();
if ('' === $uriPath) {
return '/';
}
if (0 !== strpos($uriPath, '/')) {
return '/';
}
if ('/' === $uriPath) {
return '/';
}
if (0 === ($lastSlashPos = strrpos($uriPath, '/'))) {
return '/';
}
return substr($uriPath, 0, $lastSlashPos);
}
public function withCookieHeader(RequestInterface $request) {
$values = [];
$uri = $request
->getUri();
$scheme = $uri
->getScheme();
$host = $uri
->getHost();
$path = $uri
->getPath() ?: '/';
foreach ($this->cookies as $cookie) {
if ($cookie
->matchesPath($path) && $cookie
->matchesDomain($host) && !$cookie
->isExpired() && (!$cookie
->getSecure() || $scheme === 'https')) {
$values[] = $cookie
->getName() . '=' . $cookie
->getValue();
}
}
return $values ? $request
->withHeader('Cookie', implode('; ', $values)) : $request;
}
private function removeCookieIfEmpty(SetCookie $cookie) {
$cookieValue = $cookie
->getValue();
if ($cookieValue === null || $cookieValue === '') {
$this
->clear($cookie
->getDomain(), $cookie
->getPath(), $cookie
->getName());
}
}
}