PluginProbe
WPIDE – File Manager & Code Editor / 3.5.9
WPIDE – File Manager & Code Editor v3.5.9
3.5.9 3.5.8 3.5.7 2.0.14 2.0.15 2.0.16 2.0.2 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1 2.2 2.3 2.3.1 2.3.2 2.4.0 2.5 2.6 3.0 3.1 3.2 3.3 All 55 releases
wpide / vendor / symfony / http-foundation / Cookie.php

Cookie.php in WPIDE – File Manager & Code Editor 3.5.9, at vendor/symfony/http-foundation/Cookie.php

423 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <[email protected]>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\HttpFoundation;
13
14 /**
15 * Represents a cookie.
16 *
17 * @author Johannes M. Schmitt <[email protected]>
18 */
19 class Cookie
20 {
21 public const SAMESITE_NONE = 'none';
22 public const SAMESITE_LAX = 'lax';
23 public const SAMESITE_STRICT = 'strict';
24
25 protected $name;
26 protected $value;
27 protected $domain;
28 protected $expire;
29 protected $path;
30 protected $secure;
31 protected $httpOnly;
32
33 private $raw;
34 private $sameSite;
35 private $secureDefault = false;
36
37 private const RESERVED_CHARS_LIST = "=,; \t\r\n\v\f";
38 private const RESERVED_CHARS_FROM = ['=', ',', ';', ' ', "\t", "\r", "\n", "\v", "\f"];
39 private const RESERVED_CHARS_TO = ['%3D', '%2C', '%3B', '%20', '%09', '%0D', '%0A', '%0B', '%0C'];
40
41 /**
42 * Creates cookie from raw header string.
43 *
44 * @return static
45 */
46 public static function fromString(string $cookie, bool $decode = false)
47 {
48 $data = [
49 'expires' => 0,
50 'path' => '/',
51 'domain' => null,
52 'secure' => false,
53 'httponly' => false,
54 'raw' => !$decode,
55 'samesite' => null,
56 ];
57
58 $parts = HeaderUtils::split($cookie, ';=');
59 $part = array_shift($parts);
60
61 $name = $decode ? urldecode($part[0]) : $part[0];
62 $value = isset($part[1]) ? ($decode ? urldecode($part[1]) : $part[1]) : null;
63
64 $data = HeaderUtils::combine($parts) + $data;
65 $data['expires'] = self::expiresTimestamp($data['expires']);
66
67 if (isset($data['max-age']) && ($data['max-age'] > 0 || $data['expires'] > time())) {
68 $data['expires'] = time() + (int) $data['max-age'];
69 }
70
71 return new static($name, $value, $data['expires'], $data['path'], $data['domain'], $data['secure'], $data['httponly'], $data['raw'], $data['samesite']);
72 }
73
74 public static function create(string $name, ?string $value = null, $expire = 0, ?string $path = '/', ?string $domain = null, ?bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = self::SAMESITE_LAX): self
75 {
76 return new self($name, $value, $expire, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
77 }
78
79 /**
80 * @param string $name The name of the cookie
81 * @param string|null $value The value of the cookie
82 * @param int|string|\DateTimeInterface $expire The time the cookie expires
83 * @param string|null $path The path on the server in which the cookie will be available on
84 * @param string|null $domain The domain that the cookie is available to
85 * @param bool|null $secure Whether the client should send back the cookie only over HTTPS or null to auto-enable this when the request is already using HTTPS
86 * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
87 * @param bool $raw Whether the cookie value should be sent with no url encoding
88 * @param string|null $sameSite Whether the cookie will be available for cross-site requests
89 *
90 * @throws \InvalidArgumentException
91 */
92 public function __construct(string $name, ?string $value = null, $expire = 0, ?string $path = '/', ?string $domain = null, ?bool $secure = null, bool $httpOnly = true, bool $raw = false, ?string $sameSite = 'lax')
93 {
94 // from PHP source code
95 if ($raw && false !== strpbrk($name, self::RESERVED_CHARS_LIST)) {
96 throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
97 }
98
99 if (empty($name)) {
100 throw new \InvalidArgumentException('The cookie name cannot be empty.');
101 }
102
103 $this->name = $name;
104 $this->value = $value;
105 $this->domain = $domain;
106 $this->expire = self::expiresTimestamp($expire);
107 $this->path = empty($path) ? '/' : $path;
108 $this->secure = $secure;
109 $this->httpOnly = $httpOnly;
110 $this->raw = $raw;
111 $this->sameSite = $this->withSameSite($sameSite)->sameSite;
112 }
113
114 /**
115 * Creates a cookie copy with a new value.
116 *
117 * @return static
118 */
119 public function withValue(?string $value): self
120 {
121 $cookie = clone $this;
122 $cookie->value = $value;
123
124 return $cookie;
125 }
126
127 /**
128 * Creates a cookie copy with a new domain that the cookie is available to.
129 *
130 * @return static
131 */
132 public function withDomain(?string $domain): self
133 {
134 $cookie = clone $this;
135 $cookie->domain = $domain;
136
137 return $cookie;
138 }
139
140 /**
141 * Creates a cookie copy with a new time the cookie expires.
142 *
143 * @param int|string|\DateTimeInterface $expire
144 *
145 * @return static
146 */
147 public function withExpires($expire = 0): self
148 {
149 $cookie = clone $this;
150 $cookie->expire = self::expiresTimestamp($expire);
151
152 return $cookie;
153 }
154
155 /**
156 * Converts expires formats to a unix timestamp.
157 *
158 * @param int|string|\DateTimeInterface $expire
159 */
160 private static function expiresTimestamp($expire = 0): int
161 {
162 // convert expiration time to a Unix timestamp
163 if ($expire instanceof \DateTimeInterface) {
164 $expire = $expire->format('U');
165 } elseif (!is_numeric($expire)) {
166 $expire = strtotime($expire);
167
168 if (false === $expire) {
169 throw new \InvalidArgumentException('The cookie expiration time is not valid.');
170 }
171 }
172
173 return 0 < $expire ? (int) $expire : 0;
174 }
175
176 /**
177 * Creates a cookie copy with a new path on the server in which the cookie will be available on.
178 *
179 * @return static
180 */
181 public function withPath(string $path): self
182 {
183 $cookie = clone $this;
184 $cookie->path = '' === $path ? '/' : $path;
185
186 return $cookie;
187 }
188
189 /**
190 * Creates a cookie copy that only be transmitted over a secure HTTPS connection from the client.
191 *
192 * @return static
193 */
194 public function withSecure(bool $secure = true): self
195 {
196 $cookie = clone $this;
197 $cookie->secure = $secure;
198
199 return $cookie;
200 }
201
202 /**
203 * Creates a cookie copy that be accessible only through the HTTP protocol.
204 *
205 * @return static
206 */
207 public function withHttpOnly(bool $httpOnly = true): self
208 {
209 $cookie = clone $this;
210 $cookie->httpOnly = $httpOnly;
211
212 return $cookie;
213 }
214
215 /**
216 * Creates a cookie copy that uses no url encoding.
217 *
218 * @return static
219 */
220 public function withRaw(bool $raw = true): self
221 {
222 if ($raw && false !== strpbrk($this->name, self::RESERVED_CHARS_LIST)) {
223 throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $this->name));
224 }
225
226 $cookie = clone $this;
227 $cookie->raw = $raw;
228
229 return $cookie;
230 }
231
232 /**
233 * Creates a cookie copy with SameSite attribute.
234 *
235 * @return static
236 */
237 public function withSameSite(?string $sameSite): self
238 {
239 if ('' === $sameSite) {
240 $sameSite = null;
241 } elseif (null !== $sameSite) {
242 $sameSite = strtolower($sameSite);
243 }
244
245 if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, self::SAMESITE_NONE, null], true)) {
246 throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
247 }
248
249 $cookie = clone $this;
250 $cookie->sameSite = $sameSite;
251
252 return $cookie;
253 }
254
255 /**
256 * Returns the cookie as a string.
257 *
258 * @return string
259 */
260 public function __toString()
261 {
262 if ($this->isRaw()) {
263 $str = $this->getName();
264 } else {
265 $str = str_replace(self::RESERVED_CHARS_FROM, self::RESERVED_CHARS_TO, $this->getName());
266 }
267
268 $str .= '=';
269
270 if ('' === (string) $this->getValue()) {
271 $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';
272 } else {
273 $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
274
275 if (0 !== $this->getExpiresTime()) {
276 $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge();
277 }
278 }
279
280 if ($this->getPath()) {
281 $str .= '; path='.$this->getPath();
282 }
283
284 if ($this->getDomain()) {
285 $str .= '; domain='.$this->getDomain();
286 }
287
288 if (true === $this->isSecure()) {
289 $str .= '; secure';
290 }
291
292 if (true === $this->isHttpOnly()) {
293 $str .= '; httponly';
294 }
295
296 if (null !== $this->getSameSite()) {
297 $str .= '; samesite='.$this->getSameSite();
298 }
299
300 return $str;
301 }
302
303 /**
304 * Gets the name of the cookie.
305 *
306 * @return string
307 */
308 public function getName()
309 {
310 return $this->name;
311 }
312
313 /**
314 * Gets the value of the cookie.
315 *
316 * @return string|null
317 */
318 public function getValue()
319 {
320 return $this->value;
321 }
322
323 /**
324 * Gets the domain that the cookie is available to.
325 *
326 * @return string|null
327 */
328 public function getDomain()
329 {
330 return $this->domain;
331 }
332
333 /**
334 * Gets the time the cookie expires.
335 *
336 * @return int
337 */
338 public function getExpiresTime()
339 {
340 return $this->expire;
341 }
342
343 /**
344 * Gets the max-age attribute.
345 *
346 * @return int
347 */
348 public function getMaxAge()
349 {
350 $maxAge = $this->expire - time();
351
352 return 0 >= $maxAge ? 0 : $maxAge;
353 }
354
355 /**
356 * Gets the path on the server in which the cookie will be available on.
357 *
358 * @return string
359 */
360 public function getPath()
361 {
362 return $this->path;
363 }
364
365 /**
366 * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
367 *
368 * @return bool
369 */
370 public function isSecure()
371 {
372 return $this->secure ?? $this->secureDefault;
373 }
374
375 /**
376 * Checks whether the cookie will be made accessible only through the HTTP protocol.
377 *
378 * @return bool
379 */
380 public function isHttpOnly()
381 {
382 return $this->httpOnly;
383 }
384
385 /**
386 * Whether this cookie is about to be cleared.
387 *
388 * @return bool
389 */
390 public function isCleared()
391 {
392 return 0 !== $this->expire && $this->expire < time();
393 }
394
395 /**
396 * Checks if the cookie value should be sent with no url encoding.
397 *
398 * @return bool
399 */
400 public function isRaw()
401 {
402 return $this->raw;
403 }
404
405 /**
406 * Gets the SameSite attribute.
407 *
408 * @return string|null
409 */
410 public function getSameSite()
411 {
412 return $this->sameSite;
413 }
414
415 /**
416 * @param bool $default The default value of the "secure" flag when it is set to null
417 */
418 public function setSecureDefault(bool $default): void
419 {
420 $this->secureDefault = $default;
421 }
422 }
423