/wp-content/plugins/iwp-client/lib/amazon/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/ArrayCookieJar.php

https://gitlab.com/treighton/wpgit · PHP · 237 lines · 157 code · 30 blank · 50 comment · 31 complexity · be0a852c2c9001c32441145623116620 MD5 · raw file

  1. <?php
  2. namespace Guzzle\Plugin\Cookie\CookieJar;
  3. use Guzzle\Plugin\Cookie\Cookie;
  4. use Guzzle\Http\Message\RequestInterface;
  5. use Guzzle\Http\Message\Response;
  6. use Guzzle\Parser\ParserRegistry;
  7. use Guzzle\Plugin\Cookie\Exception\InvalidCookieException;
  8. /**
  9. * Cookie cookieJar that stores cookies an an array
  10. */
  11. class ArrayCookieJar implements CookieJarInterface, \Serializable
  12. {
  13. /** @var array Loaded cookie data */
  14. protected $cookies = array();
  15. /** @var bool Whether or not strict mode is enabled. When enabled, exceptions will be thrown for invalid cookies */
  16. protected $strictMode;
  17. /**
  18. * @param bool $strictMode Set to true to throw exceptions when invalid cookies are added to the cookie jar
  19. */
  20. public function __construct($strictMode = false)
  21. {
  22. $this->strictMode = $strictMode;
  23. }
  24. /**
  25. * Enable or disable strict mode on the cookie jar
  26. *
  27. * @param bool $strictMode Set to true to throw exceptions when invalid cookies are added. False to ignore them.
  28. *
  29. * @return self
  30. */
  31. public function setStrictMode($strictMode)
  32. {
  33. $this->strictMode = $strictMode;
  34. }
  35. public function remove($domain = null, $path = null, $name = null)
  36. {
  37. $cookies = $this->all($domain, $path, $name, false, false);
  38. $this->cookies = array_filter($this->cookies, function (Cookie $cookie) use ($cookies) {
  39. return !in_array($cookie, $cookies, true);
  40. });
  41. return $this;
  42. }
  43. public function removeTemporary()
  44. {
  45. $this->cookies = array_filter($this->cookies, function (Cookie $cookie) {
  46. return !$cookie->getDiscard() && $cookie->getExpires();
  47. });
  48. return $this;
  49. }
  50. public function removeExpired()
  51. {
  52. $currentTime = time();
  53. $this->cookies = array_filter($this->cookies, function (Cookie $cookie) use ($currentTime) {
  54. return !$cookie->getExpires() || $currentTime < $cookie->getExpires();
  55. });
  56. return $this;
  57. }
  58. public function all($domain = null, $path = null, $name = null, $skipDiscardable = false, $skipExpired = true)
  59. {
  60. return array_values(array_filter($this->cookies, function (Cookie $cookie) use (
  61. $domain,
  62. $path,
  63. $name,
  64. $skipDiscardable,
  65. $skipExpired
  66. ) {
  67. return false === (($name && $cookie->getName() != $name) ||
  68. ($skipExpired && $cookie->isExpired()) ||
  69. ($skipDiscardable && ($cookie->getDiscard() || !$cookie->getExpires())) ||
  70. ($path && !$cookie->matchesPath($path)) ||
  71. ($domain && !$cookie->matchesDomain($domain)));
  72. }));
  73. }
  74. public function add(Cookie $cookie)
  75. {
  76. // Only allow cookies with set and valid domain, name, value
  77. $result = $cookie->validate();
  78. if ($result !== true) {
  79. if ($this->strictMode) {
  80. throw new InvalidCookieException($result);
  81. } else {
  82. $this->removeCookieIfEmpty($cookie);
  83. return false;
  84. }
  85. }
  86. // Resolve conflicts with previously set cookies
  87. foreach ($this->cookies as $i => $c) {
  88. // Two cookies are identical, when their path, domain, port and name are identical
  89. if ($c->getPath() != $cookie->getPath() ||
  90. $c->getDomain() != $cookie->getDomain() ||
  91. $c->getPorts() != $cookie->getPorts() ||
  92. $c->getName() != $cookie->getName()
  93. ) {
  94. continue;
  95. }
  96. // The previously set cookie is a discard cookie and this one is not so allow the new cookie to be set
  97. if (!$cookie->getDiscard() && $c->getDiscard()) {
  98. unset($this->cookies[$i]);
  99. continue;
  100. }
  101. // If the new cookie's expiration is further into the future, then replace the old cookie
  102. if ($cookie->getExpires() > $c->getExpires()) {
  103. unset($this->cookies[$i]);
  104. continue;
  105. }
  106. // If the value has changed, we better change it
  107. if ($cookie->getValue() !== $c->getValue()) {
  108. unset($this->cookies[$i]);
  109. continue;
  110. }
  111. // The cookie exists, so no need to continue
  112. return false;
  113. }
  114. $this->cookies[] = $cookie;
  115. return true;
  116. }
  117. /**
  118. * Serializes the cookie cookieJar
  119. *
  120. * @return string
  121. */
  122. public function serialize()
  123. {
  124. // Only serialize long term cookies and unexpired cookies
  125. return json_encode(array_map(function (Cookie $cookie) {
  126. return $cookie->toArray();
  127. }, $this->all(null, null, null, true, true)));
  128. }
  129. /**
  130. * Unserializes the cookie cookieJar
  131. */
  132. public function unserialize($data)
  133. {
  134. $data = json_decode($data, true);
  135. if (empty($data)) {
  136. $this->cookies = array();
  137. } else {
  138. $this->cookies = array_map(function (array $cookie) {
  139. return new Cookie($cookie);
  140. }, $data);
  141. }
  142. }
  143. /**
  144. * Returns the total number of stored cookies
  145. *
  146. * @return int
  147. */
  148. public function count()
  149. {
  150. return count($this->cookies);
  151. }
  152. /**
  153. * Returns an iterator
  154. *
  155. * @return \ArrayIterator
  156. */
  157. public function getIterator()
  158. {
  159. return new \ArrayIterator($this->cookies);
  160. }
  161. public function addCookiesFromResponse(Response $response, RequestInterface $request = null)
  162. {
  163. if ($cookieHeader = $response->getHeader('Set-Cookie')) {
  164. $parser = ParserRegistry::getInstance()->getParser('cookie');
  165. foreach ($cookieHeader as $cookie) {
  166. if ($parsed = $request
  167. ? $parser->parseCookie($cookie, $request->getHost(), $request->getPath())
  168. : $parser->parseCookie($cookie)
  169. ) {
  170. // Break up cookie v2 into multiple cookies
  171. foreach ($parsed['cookies'] as $key => $value) {
  172. $row = $parsed;
  173. $row['name'] = $key;
  174. $row['value'] = $value;
  175. unset($row['cookies']);
  176. $this->add(new Cookie($row));
  177. }
  178. }
  179. }
  180. }
  181. }
  182. public function getMatchingCookies(RequestInterface $request)
  183. {
  184. // Find cookies that match this request
  185. $cookies = $this->all($request->getHost(), $request->getPath());
  186. // Remove ineligible cookies
  187. foreach ($cookies as $index => $cookie) {
  188. if (!$cookie->matchesPort($request->getPort()) || ($cookie->getSecure() && $request->getScheme() != 'https')) {
  189. unset($cookies[$index]);
  190. }
  191. };
  192. return $cookies;
  193. }
  194. /**
  195. * If a cookie already exists and the server asks to set it again with a null value, the
  196. * cookie must be deleted.
  197. *
  198. * @param \Guzzle\Plugin\Cookie\Cookie $cookie
  199. */
  200. private function removeCookieIfEmpty(Cookie $cookie)
  201. {
  202. $cookieValue = $cookie->getValue();
  203. if ($cookieValue === null || $cookieValue === '') {
  204. $this->remove($cookie->getDomain(), $cookie->getPath(), $cookie->getName());
  205. }
  206. }
  207. }