annotate vendor/symfony/http-foundation/Cookie.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 7a779792577d
children c2387f117808
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@14 44 $data = array(
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@14 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@0 131 if (!in_array($sameSite, array(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@14 148 $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; max-age=-31536001';
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@14 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@14 227 return 0 !== $this->expire ? $this->expire - time() : 0;
Chris@14 228 }
Chris@14 229
Chris@14 230 /**
Chris@0 231 * Gets the path on the server in which the cookie will be available on.
Chris@0 232 *
Chris@0 233 * @return string
Chris@0 234 */
Chris@0 235 public function getPath()
Chris@0 236 {
Chris@0 237 return $this->path;
Chris@0 238 }
Chris@0 239
Chris@0 240 /**
Chris@0 241 * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
Chris@0 242 *
Chris@0 243 * @return bool
Chris@0 244 */
Chris@0 245 public function isSecure()
Chris@0 246 {
Chris@0 247 return $this->secure;
Chris@0 248 }
Chris@0 249
Chris@0 250 /**
Chris@0 251 * Checks whether the cookie will be made accessible only through the HTTP protocol.
Chris@0 252 *
Chris@0 253 * @return bool
Chris@0 254 */
Chris@0 255 public function isHttpOnly()
Chris@0 256 {
Chris@0 257 return $this->httpOnly;
Chris@0 258 }
Chris@0 259
Chris@0 260 /**
Chris@0 261 * Whether this cookie is about to be cleared.
Chris@0 262 *
Chris@0 263 * @return bool
Chris@0 264 */
Chris@0 265 public function isCleared()
Chris@0 266 {
Chris@0 267 return $this->expire < time();
Chris@0 268 }
Chris@0 269
Chris@0 270 /**
Chris@0 271 * Checks if the cookie value should be sent with no url encoding.
Chris@0 272 *
Chris@0 273 * @return bool
Chris@0 274 */
Chris@0 275 public function isRaw()
Chris@0 276 {
Chris@0 277 return $this->raw;
Chris@0 278 }
Chris@0 279
Chris@0 280 /**
Chris@0 281 * Gets the SameSite attribute.
Chris@0 282 *
Chris@0 283 * @return string|null
Chris@0 284 */
Chris@0 285 public function getSameSite()
Chris@0 286 {
Chris@0 287 return $this->sameSite;
Chris@0 288 }
Chris@0 289 }