Blame | Last modification | View Log | RSS feed
<?phpnamespace GuzzleHttp\Cookie;use Psr\Http\Message\RequestInterface;use Psr\Http\Message\ResponseInterface;/*** Cookie jar that stores cookies as an array*/class CookieJar implements CookieJarInterface{/** @var SetCookie[] Loaded cookie data */private $cookies = [];/** @var bool */private $strictMode;/*** @param bool $strictMode Set to true to throw exceptions when invalid* cookies are added to the cookie jar.* @param array $cookieArray Array of SetCookie objects or a hash of* arrays that can be used with the SetCookie* constructor*/public function __construct($strictMode = false, $cookieArray = []){$this->strictMode = $strictMode;foreach ($cookieArray as $cookie) {if (!($cookie instanceof SetCookie)) {$cookie = new SetCookie($cookie);}$this->setCookie($cookie);}}/*** Create a new Cookie jar from an associative array and domain.** @param array $cookies Cookies to create the jar from* @param string $domain Domain to set the cookies to** @return self*/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;}/*** @deprecated*/public static function getCookieValue($value){return $value;}/*** Evaluate if this cookie should be persisted to storage* that survives between requests.** @param SetCookie $cookie Being evaluated.* @param bool $allowSessionCookies If we should persist session cookies* @return bool*/public static function shouldPersist(SetCookie $cookie,$allowSessionCookies = false) {if ($cookie->getExpires() || $allowSessionCookies) {if (!$cookie->getDiscard()) {return true;}}return false;}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){// If the name string is empty (but not 0), ignore the set-cookie// string entirely.$name = $cookie->getName();if (!$name && $name !== '0') {return false;}// Only allow cookies with set and valid domain, name, value$result = $cookie->validate();if ($result !== true) {if ($this->strictMode) {throw new \RuntimeException('Invalid cookie: ' . $result);} else {$this->removeCookieIfEmpty($cookie);return false;}}// Resolve conflicts with previously set cookiesforeach ($this->cookies as $i => $c) {// Two cookies are identical, when their path, and domain are// identical.if ($c->getPath() != $cookie->getPath() ||$c->getDomain() != $cookie->getDomain() ||$c->getName() != $cookie->getName()) {continue;}// The previously set cookie is a discard cookie and this one is// not so allow the new cookie to be setif (!$cookie->getDiscard() && $c->getDiscard()) {unset($this->cookies[$i]);continue;}// If the new cookie's expiration is further into the future, then// replace the old cookieif ($cookie->getExpires() > $c->getExpires()) {unset($this->cookies[$i]);continue;}// If the value has changed, we better change itif ($cookie->getValue() !== $c->getValue()) {unset($this->cookies[$i]);continue;}// The cookie exists, so no need to continuereturn 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());}$this->setCookie($sc);}}}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;}/*** If a cookie already exists and the server asks to set it again with a* null value, the cookie must be deleted.** @param SetCookie $cookie*/private function removeCookieIfEmpty(SetCookie $cookie){$cookieValue = $cookie->getValue();if ($cookieValue === null || $cookieValue === '') {$this->clear($cookie->getDomain(),$cookie->getPath(),$cookie->getName());}}}