PluginProbe
Depicter — Popup & Slider Builder / 1.2.0
Depicter — Popup & Slider Builder v1.2.0
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / modules / GuzzleHttp / Cookie / CookieJar.php

CookieJar.php in Depicter — Popup & Slider Builder 1.2.0, at modules/GuzzleHttp/Cookie/CookieJar.php

314 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Depicter\GuzzleHttp\Cookie;
4
5 use Depicter\Psr\Http\Message\RequestInterface;
6 use Depicter\Psr\Http\Message\ResponseInterface;
7
8 /**
9 * Cookie jar that stores cookies as an array
10 */
11 class CookieJar implements CookieJarInterface
12 {
13 /**
14 * @var SetCookie[] Loaded cookie data
15 */
16 private $cookies = [];
17
18 /**
19 * @var bool
20 */
21 private $strictMode;
22
23 /**
24 * @param bool $strictMode Set to true to throw exceptions when invalid
25 * cookies are added to the cookie jar.
26 * @param array $cookieArray Array of SetCookie objects or a hash of
27 * arrays that can be used with the SetCookie
28 * constructor
29 */
30 public function __construct(bool $strictMode = false, array $cookieArray = [])
31 {
32 $this->strictMode = $strictMode;
33
34 foreach ($cookieArray as $cookie) {
35 if (!($cookie instanceof SetCookie)) {
36 $cookie = new SetCookie($cookie);
37 }
38 $this->setCookie($cookie);
39 }
40 }
41
42 /**
43 * Create a new Cookie jar from an associative array and domain.
44 *
45 * @param array $cookies Cookies to create the jar from
46 * @param string $domain Domain to set the cookies to
47 */
48 public static function fromArray(array $cookies, string $domain): self
49 {
50 $cookieJar = new self();
51 foreach ($cookies as $name => $value) {
52 $cookieJar->setCookie(new SetCookie([
53 'Domain' => $domain,
54 'Name' => $name,
55 'Value' => $value,
56 'Discard' => true
57 ]));
58 }
59
60 return $cookieJar;
61 }
62
63 /**
64 * Evaluate if this cookie should be persisted to storage
65 * that survives between requests.
66 *
67 * @param SetCookie $cookie Being evaluated.
68 * @param bool $allowSessionCookies If we should persist session cookies
69 */
70 public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = false): bool
71 {
72 if ($cookie->getExpires() || $allowSessionCookies) {
73 if (!$cookie->getDiscard()) {
74 return true;
75 }
76 }
77
78 return false;
79 }
80
81 /**
82 * Finds and returns the cookie based on the name
83 *
84 * @param string $name cookie name to search for
85 *
86 * @return SetCookie|null cookie that was found or null if not found
87 */
88 public function getCookieByName(string $name): ?SetCookie
89 {
90 foreach ($this->cookies as $cookie) {
91 if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) {
92 return $cookie;
93 }
94 }
95
96 return null;
97 }
98
99 /**
100 * @inheritDoc
101 */
102 public function toArray(): array
103 {
104 return \array_map(static function (SetCookie $cookie): array {
105 return $cookie->toArray();
106 }, $this->getIterator()->getArrayCopy());
107 }
108
109 /**
110 * @inheritDoc
111 */
112 public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void
113 {
114 if (!$domain) {
115 $this->cookies = [];
116 return;
117 } elseif (!$path) {
118 $this->cookies = \array_filter(
119 $this->cookies,
120 static function (SetCookie $cookie) use ($domain): bool {
121 return !$cookie->matchesDomain($domain);
122 }
123 );
124 } elseif (!$name) {
125 $this->cookies = \array_filter(
126 $this->cookies,
127 static function (SetCookie $cookie) use ($path, $domain): bool {
128 return !($cookie->matchesPath($path) &&
129 $cookie->matchesDomain($domain));
130 }
131 );
132 } else {
133 $this->cookies = \array_filter(
134 $this->cookies,
135 static function (SetCookie $cookie) use ($path, $domain, $name) {
136 return !($cookie->getName() == $name &&
137 $cookie->matchesPath($path) &&
138 $cookie->matchesDomain($domain));
139 }
140 );
141 }
142 }
143
144 /**
145 * @inheritDoc
146 */
147 public function clearSessionCookies(): void
148 {
149 $this->cookies = \array_filter(
150 $this->cookies,
151 static function (SetCookie $cookie): bool {
152 return !$cookie->getDiscard() && $cookie->getExpires();
153 }
154 );
155 }
156
157 /**
158 * @inheritDoc
159 */
160 public function setCookie(SetCookie $cookie): bool
161 {
162 // If the name string is empty (but not 0), ignore the set-cookie
163 // string entirely.
164 $name = $cookie->getName();
165 if (!$name && $name !== '0') {
166 return false;
167 }
168
169 // Only allow cookies with set and valid domain, name, value
170 $result = $cookie->validate();
171 if ($result !== true) {
172 if ($this->strictMode) {
173 throw new \RuntimeException('Invalid cookie: ' . $result);
174 }
175 $this->removeCookieIfEmpty($cookie);
176 return false;
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(): int
221 {
222 return \count($this->cookies);
223 }
224
225 /**
226 * @return \ArrayIterator<int, SetCookie>
227 */
228 public function getIterator(): \ArrayIterator
229 {
230 return new \ArrayIterator(\array_values($this->cookies));
231 }
232
233 public function extractCookies(RequestInterface $request, ResponseInterface $response): void
234 {
235 if ($cookieHeader = $response->getHeader('Set-Cookie')) {
236 foreach ($cookieHeader as $cookie) {
237 $sc = SetCookie::fromString($cookie);
238 if (!$sc->getDomain()) {
239 $sc->setDomain($request->getUri()->getHost());
240 }
241 if (0 !== \strpos($sc->getPath(), '/')) {
242 $sc->setPath($this->getCookiePathFromRequest($request));
243 }
244 $this->setCookie($sc);
245 }
246 }
247 }
248
249 /**
250 * Computes cookie path following RFC 6265 section 5.1.4
251 *
252 * @link https://tools.ietf.org/html/rfc6265#section-5.1.4
253 */
254 private function getCookiePathFromRequest(RequestInterface $request): string
255 {
256 $uriPath = $request->getUri()->getPath();
257 if ('' === $uriPath) {
258 return '/';
259 }
260 if (0 !== \strpos($uriPath, '/')) {
261 return '/';
262 }
263 if ('/' === $uriPath) {
264 return '/';
265 }
266 $lastSlashPos = \strrpos($uriPath, '/');
267 if (0 === $lastSlashPos || false === $lastSlashPos) {
268 return '/';
269 }
270
271 return \substr($uriPath, 0, $lastSlashPos);
272 }
273
274 public function withCookieHeader(RequestInterface $request): RequestInterface
275 {
276 $values = [];
277 $uri = $request->getUri();
278 $scheme = $uri->getScheme();
279 $host = $uri->getHost();
280 $path = $uri->getPath() ?: '/';
281
282 foreach ($this->cookies as $cookie) {
283 if ($cookie->matchesPath($path) &&
284 $cookie->matchesDomain($host) &&
285 !$cookie->isExpired() &&
286 (!$cookie->getSecure() || $scheme === 'https')
287 ) {
288 $values[] = $cookie->getName() . '='
289 . $cookie->getValue();
290 }
291 }
292
293 return $values
294 ? $request->withHeader('Cookie', \implode('; ', $values))
295 : $request;
296 }
297
298 /**
299 * If a cookie already exists and the server asks to set it again with a
300 * null value, the cookie must be deleted.
301 */
302 private function removeCookieIfEmpty(SetCookie $cookie): void
303 {
304 $cookieValue = $cookie->getValue();
305 if ($cookieValue === null || $cookieValue === '') {
306 $this->clear(
307 $cookie->getDomain(),
308 $cookie->getPath(),
309 $cookie->getName()
310 );
311 }
312 }
313 }
314