annotate vendor/symfony/http-foundation/Cookie.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\HttpFoundation;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Represents a cookie.
Chris@0 16 *
Chris@0 17 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
Chris@0 18 */
Chris@0 19 class Cookie
Chris@0 20 {
Chris@0 21 protected $name;
Chris@0 22 protected $value;
Chris@0 23 protected $domain;
Chris@0 24 protected $expire;
Chris@0 25 protected $path;
Chris@0 26 protected $secure;
Chris@0 27 protected $httpOnly;
Chris@0 28 private $raw;
Chris@0 29 private $sameSite;
Chris@0 30
Chris@0 31 const SAMESITE_LAX = 'lax';
Chris@0 32 const SAMESITE_STRICT = 'strict';
Chris@0 33
Chris@0 34 /**
Chris@14 35 * Creates cookie from raw header string.
Chris@0 36 *
Chris@14 37 * @param string $cookie
Chris@14 38 * @param bool $decode
Chris@14 39 *
Chris@14 40 * @return static
Chris@14 41 */
Chris@14 42 public static function fromString($cookie, $decode = false)
Chris@14 43 {
Chris@17 44 $data = [
Chris@14 45 'expires' => 0,
Chris@14 46 'path' => '/',
Chris@14 47 'domain' => null,
Chris@14 48 'secure' => false,
Chris@14 49 'httponly' => false,
Chris@14 50 'raw' => !$decode,
Chris@14 51 'samesite' => null,
Chris@17 52 ];
Chris@14 53 foreach (explode(';', $cookie) as $part) {
Chris@14 54 if (false === strpos($part, '=')) {
Chris@14 55 $key = trim($part);
Chris@14 56 $value = true;
Chris@14 57 } else {
Chris@14 58 list($key, $value) = explode('=', trim($part), 2);
Chris@14 59 $key = trim($key);
Chris@14 60 $value = trim($value);
Chris@14 61 }
Chris@14 62 if (!isset($data['name'])) {
Chris@14 63 $data['name'] = $decode ? urldecode($key) : $key;
Chris@14 64 $data['value'] = true === $value ? null : ($decode ? urldecode($value) : $value);
Chris@14 65 continue;
Chris@14 66 }
Chris@14 67 switch ($key = strtolower($key)) {
Chris@14 68 case 'name':
Chris@14 69 case 'value':
Chris@14 70 break;
Chris@14 71 case 'max-age':
Chris@14 72 $data['expires'] = time() + (int) $value;
Chris@14 73 break;
Chris@14 74 default:
Chris@14 75 $data[$key] = $value;
Chris@14 76 break;
Chris@14 77 }
Chris@14 78 }
Chris@14 79
Chris@14 80 return new static($data['name'], $data['value'], $data['expires'], $data['path'], $data['domain'], $data['secure'], $data['httponly'], $data['raw'], $data['samesite']);
Chris@14 81 }
Chris@14 82
Chris@14 83 /**
Chris@0 84 * @param string $name The name of the cookie
Chris@14 85 * @param string|null $value The value of the cookie
Chris@0 86 * @param int|string|\DateTimeInterface $expire The time the cookie expires
Chris@0 87 * @param string $path The path on the server in which the cookie will be available on
Chris@14 88 * @param string|null $domain The domain that the cookie is available to
Chris@0 89 * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
Chris@0 90 * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
Chris@0 91 * @param bool $raw Whether the cookie value should be sent with no url encoding
Chris@0 92 * @param string|null $sameSite Whether the cookie will be available for cross-site requests
Chris@0 93 *
Chris@0 94 * @throws \InvalidArgumentException
Chris@0 95 */
Chris@0 96 public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null)
Chris@0 97 {
Chris@0 98 // from PHP source code
Chris@0 99 if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
Chris@0 100 throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
Chris@0 101 }
Chris@0 102
Chris@0 103 if (empty($name)) {
Chris@0 104 throw new \InvalidArgumentException('The cookie name cannot be empty.');
Chris@0 105 }
Chris@0 106
Chris@0 107 // convert expiration time to a Unix timestamp
Chris@0 108 if ($expire instanceof \DateTimeInterface) {
Chris@0 109 $expire = $expire->format('U');
Chris@0 110 } elseif (!is_numeric($expire)) {
Chris@0 111 $expire = strtotime($expire);
Chris@0 112
Chris@0 113 if (false === $expire) {
Chris@0 114 throw new \InvalidArgumentException('The cookie expiration time is not valid.');
Chris@0 115 }
Chris@0 116 }
Chris@0 117
Chris@0 118 $this->name = $name;
Chris@0 119 $this->value = $value;
Chris@0 120 $this->domain = $domain;
Chris@0 121 $this->expire = 0 < $expire ? (int) $expire : 0;
Chris@0 122 $this->path = empty($path) ? '/' : $path;
Chris@0 123 $this->secure = (bool) $secure;
Chris@0 124 $this->httpOnly = (bool) $httpOnly;
Chris@0 125 $this->raw = (bool) $raw;
Chris@0 126
Chris@12 127 if (null !== $sameSite) {
Chris@12 128 $sameSite = strtolower($sameSite);
Chris@12 129 }
Chris@12 130
Chris@17 131 if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, null], true)) {
Chris@0 132 throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
Chris@0 133 }
Chris@0 134
Chris@0 135 $this->sameSite = $sameSite;
Chris@0 136 }
Chris@0 137
Chris@0 138 /**
Chris@0 139 * Returns the cookie as a string.
Chris@0 140 *
Chris@0 141 * @return string The cookie
Chris@0 142 */
Chris@0 143 public function __toString()
Chris@0 144 {
Chris@0 145 $str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'=';
Chris@0 146
Chris@0 147 if ('' === (string) $this->getValue()) {
Chris@16 148 $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';
Chris@0 149 } else {
Chris@12 150 $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
Chris@0 151
Chris@0 152 if (0 !== $this->getExpiresTime()) {
Chris@16 153 $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()).'; Max-Age='.$this->getMaxAge();
Chris@0 154 }
Chris@0 155 }
Chris@0 156
Chris@0 157 if ($this->getPath()) {
Chris@0 158 $str .= '; path='.$this->getPath();
Chris@0 159 }
Chris@0 160
Chris@0 161 if ($this->getDomain()) {
Chris@0 162 $str .= '; domain='.$this->getDomain();
Chris@0 163 }
Chris@0 164
Chris@0 165 if (true === $this->isSecure()) {
Chris@0 166 $str .= '; secure';
Chris@0 167 }
Chris@0 168
Chris@0 169 if (true === $this->isHttpOnly()) {
Chris@0 170 $str .= '; httponly';
Chris@0 171 }
Chris@0 172
Chris@0 173 if (null !== $this->getSameSite()) {
Chris@0 174 $str .= '; samesite='.$this->getSameSite();
Chris@0 175 }
Chris@0 176
Chris@0 177 return $str;
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * Gets the name of the cookie.
Chris@0 182 *
Chris@0 183 * @return string
Chris@0 184 */
Chris@0 185 public function getName()
Chris@0 186 {
Chris@0 187 return $this->name;
Chris@0 188 }
Chris@0 189
Chris@0 190 /**
Chris@0 191 * Gets the value of the cookie.
Chris@0 192 *
Chris@0 193 * @return string|null
Chris@0 194 */
Chris@0 195 public function getValue()
Chris@0 196 {
Chris@0 197 return $this->value;
Chris@0 198 }
Chris@0 199
Chris@0 200 /**
Chris@0 201 * Gets the domain that the cookie is available to.
Chris@0 202 *
Chris@0 203 * @return string|null
Chris@0 204 */
Chris@0 205 public function getDomain()
Chris@0 206 {
Chris@0 207 return $this->domain;
Chris@0 208 }
Chris@0 209
Chris@0 210 /**
Chris@0 211 * Gets the time the cookie expires.
Chris@0 212 *
Chris@0 213 * @return int
Chris@0 214 */
Chris@0 215 public function getExpiresTime()
Chris@0 216 {
Chris@0 217 return $this->expire;
Chris@0 218 }
Chris@0 219
Chris@0 220 /**
Chris@14 221 * Gets the max-age attribute.
Chris@14 222 *
Chris@14 223 * @return int
Chris@14 224 */
Chris@14 225 public function getMaxAge()
Chris@14 226 {
Chris@16 227 $maxAge = $this->expire - time();
Chris@16 228
Chris@16 229 return 0 >= $maxAge ? 0 : $maxAge;
Chris@14 230 }
Chris@14 231
Chris@14 232 /**
Chris@0 233 * Gets the path on the server in which the cookie will be available on.
Chris@0 234 *
Chris@0 235 * @return string
Chris@0 236 */
Chris@0 237 public function getPath()
Chris@0 238 {
Chris@0 239 return $this->path;
Chris@0 240 }
Chris@0 241
Chris@0 242 /**
Chris@0 243 * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
Chris@0 244 *
Chris@0 245 * @return bool
Chris@0 246 */
Chris@0 247 public function isSecure()
Chris@0 248 {
Chris@0 249 return $this->secure;
Chris@0 250 }
Chris@0 251
Chris@0 252 /**
Chris@0 253 * Checks whether the cookie will be made accessible only through the HTTP protocol.
Chris@0 254 *
Chris@0 255 * @return bool
Chris@0 256 */
Chris@0 257 public function isHttpOnly()
Chris@0 258 {
Chris@0 259 return $this->httpOnly;
Chris@0 260 }
Chris@0 261
Chris@0 262 /**
Chris@0 263 * Whether this cookie is about to be cleared.
Chris@0 264 *
Chris@0 265 * @return bool
Chris@0 266 */
Chris@0 267 public function isCleared()
Chris@0 268 {
Chris@17 269 return 0 !== $this->expire && $this->expire < time();
Chris@0 270 }
Chris@0 271
Chris@0 272 /**
Chris@0 273 * Checks if the cookie value should be sent with no url encoding.
Chris@0 274 *
Chris@0 275 * @return bool
Chris@0 276 */
Chris@0 277 public function isRaw()
Chris@0 278 {
Chris@0 279 return $this->raw;
Chris@0 280 }
Chris@0 281
Chris@0 282 /**
Chris@0 283 * Gets the SameSite attribute.
Chris@0 284 *
Chris@0 285 * @return string|null
Chris@0 286 */
Chris@0 287 public function getSameSite()
Chris@0 288 {
Chris@0 289 return $this->sameSite;
Chris@0 290 }
Chris@0 291 }