Open Journal Systems  3.3.0
vendor/symfony/http-foundation/Cookie.php
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
13 
19 class Cookie
20 {
21  const SAMESITE_NONE = 'none';
22  const SAMESITE_LAX = 'lax';
23  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 static $reservedCharsList = "=,; \t\r\n\v\f";
38  private static $reservedCharsFrom = ['=', ',', ';', ' ', "\t", "\r", "\n", "\v", "\f"];
39  private static $reservedCharsTo = ['%3D', '%2C', '%3B', '%20', '%09', '%0D', '%0A', '%0B', '%0C'];
40 
49  public static function fromString($cookie, $decode = false)
50  {
51  $data = [
52  'expires' => 0,
53  'path' => '/',
54  'domain' => null,
55  'secure' => false,
56  'httponly' => false,
57  'raw' => !$decode,
58  'samesite' => null,
59  ];
60 
61  $parts = HeaderUtils::split($cookie, ';=');
62  $part = array_shift($parts);
63 
64  $name = $decode ? urldecode($part[0]) : $part[0];
65  $value = isset($part[1]) ? ($decode ? urldecode($part[1]) : $part[1]) : null;
66 
67  $data = HeaderUtils::combine($parts) + $data;
68 
69  if (isset($data['max-age'])) {
70  $data['expires'] = time() + (int) $data['max-age'];
71  }
72 
73  return new static($name, $value, $data['expires'], $data['path'], $data['domain'], $data['secure'], $data['httponly'], $data['raw'], $data['samesite']);
74  }
75 
76  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
77  {
78  return new self($name, $value, $expire, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
79  }
80 
94  public function __construct(string $name, string $value = null, $expire = 0, ?string $path = '/', string $domain = null, ?bool $secure = false, bool $httpOnly = true, bool $raw = false, string $sameSite = null)
95  {
96  if (9 > \func_num_args()) {
97  @trigger_error(sprintf('The default value of the "$secure" and "$samesite" arguments of "%s"\'s constructor will respectively change from "false" to "null" and from "null" to "lax" in Symfony 5.0, you should define their values explicitly or use "Cookie::create()" instead.', __METHOD__), E_USER_DEPRECATED);
98  }
99 
100  // from PHP source code
101  if ($raw && false !== strpbrk($name, self::$reservedCharsList)) {
102  throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
103  }
104 
105  if (empty($name)) {
106  throw new \InvalidArgumentException('The cookie name cannot be empty.');
107  }
108 
109  // convert expiration time to a Unix timestamp
110  if ($expire instanceof \DateTimeInterface) {
111  $expire = $expire->format('U');
112  } elseif (!is_numeric($expire)) {
113  $expire = strtotime($expire);
114 
115  if (false === $expire) {
116  throw new \InvalidArgumentException('The cookie expiration time is not valid.');
117  }
118  }
119 
120  $this->name = $name;
121  $this->value = $value;
122  $this->domain = $domain;
123  $this->expire = 0 < $expire ? (int) $expire : 0;
124  $this->path = empty($path) ? '/' : $path;
125  $this->secure = $secure;
126  $this->httpOnly = $httpOnly;
127  $this->raw = $raw;
128 
129  if ('' === $sameSite) {
130  $sameSite = null;
131  } elseif (null !== $sameSite) {
132  $sameSite = strtolower($sameSite);
133  }
134 
135  if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, self::SAMESITE_NONE, null], true)) {
136  throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
137  }
138 
139  $this->sameSite = $sameSite;
140  }
141 
147  public function __toString()
148  {
149  if ($this->isRaw()) {
150  $str = $this->getName();
151  } else {
152  $str = str_replace(self::$reservedCharsFrom, self::$reservedCharsTo, $this->getName());
153  }
154 
155  $str .= '=';
156 
157  if ('' === (string) $this->getValue()) {
158  $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';
159  } else {
160  $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
161 
162  if (0 !== $this->getExpiresTime()) {
163  $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge();
164  }
165  }
166 
167  if ($this->getPath()) {
168  $str .= '; path='.$this->getPath();
169  }
170 
171  if ($this->getDomain()) {
172  $str .= '; domain='.$this->getDomain();
173  }
174 
175  if (true === $this->isSecure()) {
176  $str .= '; secure';
177  }
178 
179  if (true === $this->isHttpOnly()) {
180  $str .= '; httponly';
181  }
182 
183  if (null !== $this->getSameSite()) {
184  $str .= '; samesite='.$this->getSameSite();
185  }
186 
187  return $str;
188  }
189 
195  public function getName()
196  {
197  return $this->name;
198  }
199 
205  public function getValue()
206  {
207  return $this->value;
208  }
209 
215  public function getDomain()
216  {
217  return $this->domain;
218  }
219 
225  public function getExpiresTime()
226  {
227  return $this->expire;
228  }
229 
235  public function getMaxAge()
236  {
237  $maxAge = $this->expire - time();
238 
239  return 0 >= $maxAge ? 0 : $maxAge;
240  }
241 
247  public function getPath()
248  {
249  return $this->path;
250  }
251 
257  public function isSecure()
258  {
259  return $this->secure ?? $this->secureDefault;
260  }
261 
267  public function isHttpOnly()
268  {
269  return $this->httpOnly;
270  }
271 
277  public function isCleared()
278  {
279  return 0 !== $this->expire && $this->expire < time();
280  }
281 
287  public function isRaw()
288  {
289  return $this->raw;
290  }
291 
297  public function getSameSite()
298  {
299  return $this->sameSite;
300  }
301 
305  public function setSecureDefault(bool $default): void
306  {
307  $this->secureDefault = $default;
308  }
309 }
Symfony\Component\HttpFoundation\Cookie\__construct
__construct(string $name, string $value=null, $expire=0, ?string $path='/', string $domain=null, ?bool $secure=false, bool $httpOnly=true, bool $raw=false, string $sameSite=null)
Definition: vendor/symfony/http-foundation/Cookie.php:94
Symfony\Component\HttpFoundation\HeaderUtils\combine
static combine(array $parts)
Definition: HeaderUtils.php:83
Symfony\Component\HttpFoundation\Cookie\$httpOnly
$httpOnly
Definition: lib/vendor/symfony/http-foundation/Cookie.php:27
Symfony\Component\HttpFoundation\Cookie\$domain
$domain
Definition: lib/vendor/symfony/http-foundation/Cookie.php:23
Symfony\Component\HttpFoundation\Cookie\$value
$value
Definition: lib/vendor/symfony/http-foundation/Cookie.php:22
Symfony\Component\HttpFoundation\Cookie\setSecureDefault
setSecureDefault(bool $default)
Definition: vendor/symfony/http-foundation/Cookie.php:305
Symfony\Component\HttpFoundation\Cookie\getSameSite
getSameSite()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:287
Symfony\Component\HttpFoundation\Cookie\SAMESITE_LAX
const SAMESITE_LAX
Definition: lib/vendor/symfony/http-foundation/Cookie.php:31
Symfony\Component\HttpFoundation\Cookie\create
static 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)
Definition: vendor/symfony/http-foundation/Cookie.php:76
Symfony\Component\HttpFoundation\Cookie\getPath
getPath()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:237
Symfony\Component\HttpFoundation\Cookie\getMaxAge
getMaxAge()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:227
Symfony\Component\HttpFoundation\Cookie\isRaw
isRaw()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:277
Symfony\Component\HttpFoundation\Cookie\isCleared
isCleared()
Definition: vendor/symfony/http-foundation/Cookie.php:277
Symfony\Component\HttpFoundation\Cookie\isHttpOnly
isHttpOnly()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:257
Symfony\Component\HttpFoundation\Cookie\getDomain
getDomain()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:207
Symfony\Component\HttpFoundation\Cookie\$expire
$expire
Definition: lib/vendor/symfony/http-foundation/Cookie.php:24
Symfony\Component\HttpFoundation\Cookie\__toString
__toString()
Definition: vendor/symfony/http-foundation/Cookie.php:147
Symfony\Component\HttpFoundation\Cookie\fromString
static fromString($cookie, $decode=false)
Definition: vendor/symfony/http-foundation/Cookie.php:49
Symfony\Component\HttpFoundation\Cookie\$secure
$secure
Definition: lib/vendor/symfony/http-foundation/Cookie.php:26
Symfony\Component\HttpFoundation
Definition: lib/vendor/symfony/http-foundation/AcceptHeader.php:12
Symfony\Component\HttpFoundation\Cookie\$path
$path
Definition: lib/vendor/symfony/http-foundation/Cookie.php:25
Symfony\Component\HttpFoundation\Cookie\isSecure
isSecure()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:247
Symfony\Component\HttpFoundation\Cookie\getExpiresTime
getExpiresTime()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:217
Symfony\Component\HttpFoundation\HeaderUtils\split
static split(string $header, string $separators)
Definition: HeaderUtils.php:45
Symfony\Component\HttpFoundation\Cookie\$name
$name
Definition: lib/vendor/symfony/http-foundation/Cookie.php:21
Symfony\Component\HttpFoundation\Cookie\getValue
getValue()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:197
Symfony\Component\HttpFoundation\Cookie\getName
getName()
Definition: lib/vendor/symfony/http-foundation/Cookie.php:187
Symfony\Component\HttpFoundation\Cookie\SAMESITE_NONE
const SAMESITE_NONE
Definition: vendor/symfony/http-foundation/Cookie.php:21
Symfony\Component\HttpFoundation\Cookie\SAMESITE_STRICT
const SAMESITE_STRICT
Definition: lib/vendor/symfony/http-foundation/Cookie.php:32