vendor/symfony/http-foundation/Cookie.php line 19

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