protected $path;
protected $secure;
protected $httpOnly;
+ private $raw;
+ private $sameSite;
+
+ const SAMESITE_LAX = 'lax';
+ const SAMESITE_STRICT = 'strict';
/**
* Constructor.
*
- * @param string $name The name of the cookie
- * @param string $value The value of the cookie
- * @param int|string|\DateTime|\DateTimeInterface $expire The time the cookie expires
- * @param string $path The path on the server in which the cookie will be available on
- * @param string $domain The domain that the cookie is available to
- * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
- * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
+ * @param string $name The name of the cookie
+ * @param string $value The value of the cookie
+ * @param int|string|\DateTimeInterface $expire The time the cookie expires
+ * @param string $path The path on the server in which the cookie will be available on
+ * @param string $domain The domain that the cookie is available to
+ * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
+ * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
+ * @param bool $raw Whether the cookie value should be sent with no url encoding
+ * @param string|null $sameSite Whether the cookie will be available for cross-site requests
*
* @throws \InvalidArgumentException
*/
- public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true)
+ public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null)
{
// from PHP source code
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
}
// convert expiration time to a Unix timestamp
- if ($expire instanceof \DateTime || $expire instanceof \DateTimeInterface) {
+ if ($expire instanceof \DateTimeInterface) {
$expire = $expire->format('U');
} elseif (!is_numeric($expire)) {
$expire = strtotime($expire);
$this->path = empty($path) ? '/' : $path;
$this->secure = (bool) $secure;
$this->httpOnly = (bool) $httpOnly;
+ $this->raw = (bool) $raw;
+
+ if (null !== $sameSite) {
+ $sameSite = strtolower($sameSite);
+ }
+
+ if (!in_array($sameSite, array(self::SAMESITE_LAX, self::SAMESITE_STRICT, null), true)) {
+ throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
+ }
+
+ $this->sameSite = $sameSite;
}
/**
*/
public function __toString()
{
- $str = urlencode($this->getName()).'=';
+ $str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'=';
if ('' === (string) $this->getValue()) {
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001);
} else {
- $str .= urlencode($this->getValue());
+ $str .= $this->isRaw() ? $this->getValue() : rawurlencode($this->getValue());
if (0 !== $this->getExpiresTime()) {
$str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime());
}
}
- if ($this->path) {
- $str .= '; path='.$this->path;
+ if ($this->getPath()) {
+ $str .= '; path='.$this->getPath();
}
if ($this->getDomain()) {
$str .= '; httponly';
}
+ if (null !== $this->getSameSite()) {
+ $str .= '; samesite='.$this->getSameSite();
+ }
+
return $str;
}
/**
* Gets the value of the cookie.
*
- * @return string
+ * @return string|null
*/
public function getValue()
{
/**
* Gets the domain that the cookie is available to.
*
- * @return string
+ * @return string|null
*/
public function getDomain()
{
{
return $this->expire < time();
}
+
+ /**
+ * Checks if the cookie value should be sent with no url encoding.
+ *
+ * @return bool
+ */
+ public function isRaw()
+ {
+ return $this->raw;
+ }
+
+ /**
+ * Gets the SameSite attribute.
+ *
+ * @return string|null
+ */
+ public function getSameSite()
+ {
+ return $this->sameSite;
+ }
}