Open Journal Systems  3.3.0
guzzlehttp/guzzle/src/Cookie/CookieJar.php
1 <?php
2 namespace GuzzleHttp\Cookie;
3 
6 
10 class CookieJar implements CookieJarInterface
11 {
13  private $cookies = [];
14 
16  private $strictMode;
17 
25  public function __construct($strictMode = false, $cookieArray = [])
26  {
27  $this->strictMode = $strictMode;
28 
29  foreach ($cookieArray as $cookie) {
30  if (!($cookie instanceof SetCookie)) {
31  $cookie = new SetCookie($cookie);
32  }
33  $this->setCookie($cookie);
34  }
35  }
36 
45  public static function fromArray(array $cookies, $domain)
46  {
47  $cookieJar = new self();
48  foreach ($cookies as $name => $value) {
49  $cookieJar->setCookie(new SetCookie([
50  'Domain' => $domain,
51  'Name' => $name,
52  'Value' => $value,
53  'Discard' => true
54  ]));
55  }
56 
57  return $cookieJar;
58  }
59 
63  public static function getCookieValue($value)
64  {
65  return $value;
66  }
67 
76  public static function shouldPersist(
77  SetCookie $cookie,
78  $allowSessionCookies = false
79  ) {
80  if ($cookie->getExpires() || $allowSessionCookies) {
81  if (!$cookie->getDiscard()) {
82  return true;
83  }
84  }
85 
86  return false;
87  }
88 
95  public function getCookieByName($name)
96  {
97  // don't allow a non string name
98  if ($name === null || !is_scalar($name)) {
99  return null;
100  }
101  foreach ($this->cookies as $cookie) {
102  if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
103  return $cookie;
104  }
105  }
106 
107  return null;
108  }
109 
110  public function toArray()
111  {
112  return array_map(function (SetCookie $cookie) {
113  return $cookie->toArray();
114  }, $this->getIterator()->getArrayCopy());
115  }
116 
117  public function clear($domain = null, $path = null, $name = null)
118  {
119  if (!$domain) {
120  $this->cookies = [];
121  return;
122  } elseif (!$path) {
123  $this->cookies = array_filter(
124  $this->cookies,
125  function (SetCookie $cookie) use ($domain) {
126  return !$cookie->matchesDomain($domain);
127  }
128  );
129  } elseif (!$name) {
130  $this->cookies = array_filter(
131  $this->cookies,
132  function (SetCookie $cookie) use ($path, $domain) {
133  return !($cookie->matchesPath($path) &&
134  $cookie->matchesDomain($domain));
135  }
136  );
137  } else {
138  $this->cookies = array_filter(
139  $this->cookies,
140  function (SetCookie $cookie) use ($path, $domain, $name) {
141  return !($cookie->getName() == $name &&
142  $cookie->matchesPath($path) &&
143  $cookie->matchesDomain($domain));
144  }
145  );
146  }
147  }
148 
149  public function clearSessionCookies()
150  {
151  $this->cookies = array_filter(
152  $this->cookies,
153  function (SetCookie $cookie) {
154  return !$cookie->getDiscard() && $cookie->getExpires();
155  }
156  );
157  }
158 
159  public function setCookie(SetCookie $cookie)
160  {
161  // If the name string is empty (but not 0), ignore the set-cookie
162  // string entirely.
163  $name = $cookie->getName();
164  if (!$name && $name !== '0') {
165  return false;
166  }
167 
168  // Only allow cookies with set and valid domain, name, value
169  $result = $cookie->validate();
170  if ($result !== true) {
171  if ($this->strictMode) {
172  throw new \RuntimeException('Invalid cookie: ' . $result);
173  } else {
174  $this->removeCookieIfEmpty($cookie);
175  return false;
176  }
177  }
178 
179  // Resolve conflicts with previously set cookies
180  foreach ($this->cookies as $i => $c) {
181 
182  // Two cookies are identical, when their path, and domain are
183  // identical.
184  if ($c->getPath() != $cookie->getPath() ||
185  $c->getDomain() != $cookie->getDomain() ||
186  $c->getName() != $cookie->getName()
187  ) {
188  continue;
189  }
190 
191  // The previously set cookie is a discard cookie and this one is
192  // not so allow the new cookie to be set
193  if (!$cookie->getDiscard() && $c->getDiscard()) {
194  unset($this->cookies[$i]);
195  continue;
196  }
197 
198  // If the new cookie's expiration is further into the future, then
199  // replace the old cookie
200  if ($cookie->getExpires() > $c->getExpires()) {
201  unset($this->cookies[$i]);
202  continue;
203  }
204 
205  // If the value has changed, we better change it
206  if ($cookie->getValue() !== $c->getValue()) {
207  unset($this->cookies[$i]);
208  continue;
209  }
210 
211  // The cookie exists, so no need to continue
212  return false;
213  }
214 
215  $this->cookies[] = $cookie;
216 
217  return true;
218  }
219 
220  public function count()
221  {
222  return count($this->cookies);
223  }
224 
225  public function getIterator()
226  {
227  return new \ArrayIterator(array_values($this->cookies));
228  }
229 
230  public function extractCookies(
232  ResponseInterface $response
233  ) {
234  if ($cookieHeader = $response->getHeader('Set-Cookie')) {
235  foreach ($cookieHeader as $cookie) {
236  $sc = SetCookie::fromString($cookie);
237  if (!$sc->getDomain()) {
238  $sc->setDomain($request->getUri()->getHost());
239  }
240  if (0 !== strpos($sc->getPath(), '/')) {
241  $sc->setPath($this->getCookiePathFromRequest($request));
242  }
243  $this->setCookie($sc);
244  }
245  }
246  }
247 
256  private function getCookiePathFromRequest(RequestInterface $request)
257  {
258  $uriPath = $request->getUri()->getPath();
259  if ('' === $uriPath) {
260  return '/';
261  }
262  if (0 !== strpos($uriPath, '/')) {
263  return '/';
264  }
265  if ('/' === $uriPath) {
266  return '/';
267  }
268  if (0 === $lastSlashPos = strrpos($uriPath, '/')) {
269  return '/';
270  }
271 
272  return substr($uriPath, 0, $lastSlashPos);
273  }
274 
275  public function withCookieHeader(RequestInterface $request)
276  {
277  $values = [];
278  $uri = $request->getUri();
279  $scheme = $uri->getScheme();
280  $host = $uri->getHost();
281  $path = $uri->getPath() ?: '/';
282 
283  foreach ($this->cookies as $cookie) {
284  if ($cookie->matchesPath($path) &&
285  $cookie->matchesDomain($host) &&
286  !$cookie->isExpired() &&
287  (!$cookie->getSecure() || $scheme === 'https')
288  ) {
289  $values[] = $cookie->getName() . '='
290  . $cookie->getValue();
291  }
292  }
293 
294  return $values
295  ? $request->withHeader('Cookie', implode('; ', $values))
296  : $request;
297  }
298 
305  private function removeCookieIfEmpty(SetCookie $cookie)
306  {
307  $cookieValue = $cookie->getValue();
308  if ($cookieValue === null || $cookieValue === '') {
309  $this->clear(
310  $cookie->getDomain(),
311  $cookie->getPath(),
312  $cookie->getName()
313  );
314  }
315  }
316 }
GuzzleHttp\Cookie\SetCookie\toArray
toArray()
Definition: SetCookie.php:103
GuzzleHttp\Cookie
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:2
GuzzleHttp\Cookie\CookieJar\extractCookies
extractCookies(RequestInterface $request, ResponseInterface $response)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:236
GuzzleHttp\Cookie\SetCookie\matchesDomain
matchesDomain($domain)
Definition: SetCookie.php:337
GuzzleHttp\Cookie\SetCookie
Definition: SetCookie.php:7
GuzzleHttp\Cookie\CookieJar\__construct
__construct($strictMode=false, $cookieArray=[])
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:31
Psr\Http\Message\RequestInterface
Definition: vendor/psr/http-message/src/RequestInterface.php:24
GuzzleHttp\Cookie\CookieJar\clear
clear($domain=null, $path=null, $name=null)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:123
GuzzleHttp\Cookie\CookieJar\getCookieValue
static getCookieValue($value)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:69
GuzzleHttp\Cookie\SetCookie\getValue
getValue()
Definition: SetCookie.php:133
GuzzleHttp\Cookie\CookieJar\withCookieHeader
withCookieHeader(RequestInterface $request)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:281
GuzzleHttp\Cookie\CookieJar\shouldPersist
static shouldPersist(SetCookie $cookie, $allowSessionCookies=false)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:82
GuzzleHttp\Cookie\SetCookie\getName
getName()
Definition: SetCookie.php:113
GuzzleHttp\Cookie\CookieJar\clearSessionCookies
clearSessionCookies()
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:155
GuzzleHttp\Cookie\CookieJar\setCookie
setCookie(SetCookie $cookie)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:165
Psr\Http\Message\MessageInterface\withHeader
withHeader($name, $value)
GuzzleHttp\Cookie\SetCookie\getPath
getPath()
Definition: SetCookie.php:173
GuzzleHttp\Cookie\SetCookie\getDiscard
getDiscard()
Definition: SetCookie.php:255
GuzzleHttp\Cookie\SetCookie\matchesPath
matchesPath($requestPath)
Definition: SetCookie.php:307
GuzzleHttp\Cookie\CookieJar\fromArray
static fromArray(array $cookies, $domain)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:51
Psr\Http\Message\ResponseInterface
Definition: vendor/psr/http-message/src/ResponseInterface.php:20
GuzzleHttp\Cookie\CookieJarInterface
Definition: vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php:17
GuzzleHttp\Cookie\SetCookie\fromString
static fromString($cookie)
Definition: SetCookie.php:35
GuzzleHttp\Cookie\CookieJar\getIterator
getIterator()
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:231
GuzzleHttp\Cookie\CookieJar\toArray
toArray()
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:116
GuzzleHttp\Cookie\SetCookie\getDomain
getDomain()
Definition: SetCookie.php:153
GuzzleHttp\Cookie\CookieJar\count
count()
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:226
Psr\Http\Message\RequestInterface\getUri
getUri()
GuzzleHttp\Cookie\CookieJar\getCookieByName
getCookieByName($name)
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:101
GuzzleHttp\Cookie\SetCookie\validate
validate()
Definition: SetCookie.php:372
GuzzleHttp\Cookie\SetCookie\getExpires
getExpires()
Definition: SetCookie.php:213
GuzzleHttp\Cookie\CookieJar
Definition: guzzlehttp/guzzle/src/Cookie/CookieJar.php:10