2010-04-19 13:12:42 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
2010-04-24 00:22:16 +01:00
|
|
|
* This file is part of the Symfony package.
|
2010-04-19 13:12:42 +01:00
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
2010-04-19 13:12:42 +01:00
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
2011-01-15 13:29:43 +00:00
|
|
|
namespace Symfony\Component\BrowserKit;
|
|
|
|
|
2010-04-19 13:12:42 +01:00
|
|
|
/**
|
|
|
|
* Cookie represents an HTTP cookie.
|
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-04-19 13:12:42 +01:00
|
|
|
*/
|
|
|
|
class Cookie
|
|
|
|
{
|
2011-07-24 20:13:25 +01:00
|
|
|
/**
|
|
|
|
* Handles dates as defined by RFC 2616 section 3.3.1, and also some other
|
|
|
|
* non-standard, but common formats.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
private static $dateFormats = array(
|
|
|
|
'D, d M Y H:i:s T',
|
|
|
|
'D, d-M-y H:i:s T',
|
|
|
|
'D, d-M-Y H:i:s T',
|
2013-02-21 16:53:30 +00:00
|
|
|
'D, d-m-y H:i:s T',
|
|
|
|
'D, d-m-Y H:i:s T',
|
2011-07-24 20:13:25 +01:00
|
|
|
'D M j G:i:s Y',
|
2012-10-25 07:42:36 +01:00
|
|
|
'D M d H:i:s Y T',
|
2011-07-24 20:13:25 +01:00
|
|
|
);
|
2010-06-23 15:24:24 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
protected $name;
|
|
|
|
protected $value;
|
2010-06-23 15:24:24 +01:00
|
|
|
protected $expires;
|
2010-05-06 12:25:53 +01:00
|
|
|
protected $path;
|
|
|
|
protected $domain;
|
|
|
|
protected $secure;
|
2010-06-23 15:24:24 +01:00
|
|
|
protected $httponly;
|
2011-05-22 12:06:09 +01:00
|
|
|
protected $rawValue;
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Sets a cookie.
|
|
|
|
*
|
2012-05-15 17:56:32 +01:00
|
|
|
* @param string $name The cookie name
|
|
|
|
* @param string $value The value of the cookie
|
|
|
|
* @param string $expires 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
|
|
|
|
* @param Boolean $secure Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client
|
|
|
|
* @param Boolean $httponly The cookie httponly flag
|
|
|
|
* @param Boolean $encodedValue Whether the value is encoded or not
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-06-23 15:24:24 +01:00
|
|
|
*/
|
2011-05-26 06:28:51 +01:00
|
|
|
public function __construct($name, $value, $expires = null, $path = null, $domain = '', $secure = false, $httponly = true, $encodedValue = false)
|
2010-06-23 15:24:24 +01:00
|
|
|
{
|
2011-05-24 19:23:23 +01:00
|
|
|
if ($encodedValue) {
|
2011-05-22 12:06:09 +01:00
|
|
|
$this->value = urldecode($value);
|
|
|
|
$this->rawValue = $value;
|
|
|
|
} else {
|
|
|
|
$this->value = $value;
|
|
|
|
$this->rawValue = urlencode($value);
|
|
|
|
}
|
2011-05-24 19:23:23 +01:00
|
|
|
$this->name = $name;
|
2010-06-23 15:24:24 +01:00
|
|
|
$this->expires = null === $expires ? null : (integer) $expires;
|
2011-09-28 09:49:26 +01:00
|
|
|
$this->path = empty($path) ? '/' : $path;
|
2010-06-23 15:24:24 +01:00
|
|
|
$this->domain = $domain;
|
|
|
|
$this->secure = (Boolean) $secure;
|
|
|
|
$this->httponly = (Boolean) $httponly;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the HTTP representation of the Cookie.
|
|
|
|
*
|
|
|
|
* @return string The HTTP representation of the Cookie
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-06-23 15:24:24 +01:00
|
|
|
*/
|
|
|
|
public function __toString()
|
|
|
|
{
|
2011-05-22 12:06:09 +01:00
|
|
|
$cookie = sprintf('%s=%s', $this->name, $this->rawValue);
|
2010-06-23 15:24:24 +01:00
|
|
|
|
|
|
|
if (null !== $this->expires) {
|
2011-07-24 20:13:25 +01:00
|
|
|
$cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'))->format(self::$dateFormats[0]), 0, -5);
|
2010-06-23 15:24:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ('' !== $this->domain) {
|
|
|
|
$cookie .= '; domain='.$this->domain;
|
|
|
|
}
|
|
|
|
|
2013-04-20 19:04:59 +01:00
|
|
|
if ($this->path) {
|
2010-06-28 07:31:22 +01:00
|
|
|
$cookie .= '; path='.$this->path;
|
|
|
|
}
|
|
|
|
|
2010-06-23 15:24:24 +01:00
|
|
|
if ($this->secure) {
|
|
|
|
$cookie .= '; secure';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->httponly) {
|
|
|
|
$cookie .= '; httponly';
|
|
|
|
}
|
|
|
|
|
|
|
|
return $cookie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a Cookie instance from a Set-Cookie header value.
|
|
|
|
*
|
|
|
|
* @param string $cookie A Set-Cookie header value
|
|
|
|
* @param string $url The base URL
|
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @return Cookie A Cookie instance
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
2012-12-16 12:02:54 +00:00
|
|
|
* @throws \InvalidArgumentException
|
|
|
|
*
|
2011-03-24 08:25:46 +00:00
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2012-07-09 13:38:28 +01:00
|
|
|
public static function fromString($cookie, $url = null)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2010-06-23 15:24:24 +01:00
|
|
|
$parts = explode(';', $cookie);
|
|
|
|
|
|
|
|
if (false === strpos($parts[0], '=')) {
|
|
|
|
throw new \InvalidArgumentException('The cookie string "%s" is not valid.');
|
|
|
|
}
|
|
|
|
|
|
|
|
list($name, $value) = explode('=', array_shift($parts), 2);
|
|
|
|
|
|
|
|
$values = array(
|
|
|
|
'name' => trim($name),
|
2011-05-22 12:06:09 +01:00
|
|
|
'value' => trim($value),
|
2011-09-28 09:49:26 +01:00
|
|
|
'expires' => null,
|
|
|
|
'path' => '/',
|
2010-06-23 15:24:24 +01:00
|
|
|
'domain' => '',
|
|
|
|
'secure' => false,
|
|
|
|
'httponly' => false,
|
2011-05-22 12:06:09 +01:00
|
|
|
'passedRawValue' => true,
|
2010-06-23 15:24:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
if (null !== $url) {
|
2011-05-26 06:28:51 +01:00
|
|
|
if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host']) || !isset($urlParts['path'])) {
|
2010-06-23 15:24:24 +01:00
|
|
|
throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url));
|
|
|
|
}
|
2011-06-08 11:12:55 +01:00
|
|
|
|
2013-04-20 19:04:45 +01:00
|
|
|
$values['domain'] = $urlParts['host'];
|
|
|
|
$values['path'] = substr($urlParts['path'], 0, strrpos($urlParts['path'], '/'));
|
2010-06-23 15:24:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($parts as $part) {
|
|
|
|
$part = trim($part);
|
|
|
|
|
|
|
|
if ('secure' === strtolower($part)) {
|
2011-07-22 12:29:57 +01:00
|
|
|
// Ignore the secure flag if the original URI is not given or is not HTTPS
|
|
|
|
if (!$url || !isset($urlParts['scheme']) || 'https' != $urlParts['scheme']) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-06-23 15:24:24 +01:00
|
|
|
$values['secure'] = true;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('httponly' === strtolower($part)) {
|
|
|
|
$values['httponly'] = true;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (2 === count($elements = explode('=', $part, 2))) {
|
2011-10-14 20:17:31 +01:00
|
|
|
if ('expires' === strtolower($elements[0])) {
|
2011-07-24 20:13:25 +01:00
|
|
|
$elements[1] = self::parseDate($elements[1]);
|
2010-06-23 15:24:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$values[strtolower($elements[0])] = $elements[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new static(
|
|
|
|
$values['name'],
|
|
|
|
$values['value'],
|
|
|
|
$values['expires'],
|
|
|
|
$values['path'],
|
|
|
|
$values['domain'],
|
|
|
|
$values['secure'],
|
2011-05-22 12:06:09 +01:00
|
|
|
$values['httponly'],
|
|
|
|
$values['passedRawValue']
|
2010-06-23 15:24:24 +01:00
|
|
|
);
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2011-07-24 20:13:25 +01:00
|
|
|
private static function parseDate($dateValue)
|
|
|
|
{
|
|
|
|
// trim single quotes around date if present
|
|
|
|
if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length-1]) {
|
|
|
|
$dateValue = substr($dateValue, 1, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (self::$dateFormats as $dateFormat) {
|
|
|
|
if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) {
|
|
|
|
return $date->getTimestamp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-21 16:53:30 +00:00
|
|
|
// attempt a fallback for unusual formatting
|
|
|
|
if (false !== $date = date_create($dateValue, new \DateTimeZone('GMT'))) {
|
|
|
|
return $date->getTimestamp();
|
|
|
|
}
|
|
|
|
|
2011-07-24 20:13:25 +01:00
|
|
|
throw new \InvalidArgumentException(sprintf('Could not parse date "%s".', $dateValue));
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Gets the name of the cookie.
|
|
|
|
*
|
|
|
|
* @return string The cookie name
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function getName()
|
|
|
|
{
|
|
|
|
return $this->name;
|
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Gets the value of the cookie.
|
|
|
|
*
|
|
|
|
* @return string The cookie value
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function getValue()
|
|
|
|
{
|
|
|
|
return $this->value;
|
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2011-05-22 12:06:09 +01:00
|
|
|
/**
|
2011-05-22 21:43:45 +01:00
|
|
|
* Gets the raw value of the cookie.
|
2011-05-22 12:06:09 +01:00
|
|
|
*
|
|
|
|
* @return string The cookie value
|
|
|
|
*
|
|
|
|
* @api
|
|
|
|
*/
|
|
|
|
public function getRawValue()
|
|
|
|
{
|
|
|
|
return $this->rawValue;
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
2010-06-23 15:24:24 +01:00
|
|
|
* Gets the expires time of the cookie.
|
2010-05-06 12:25:53 +01:00
|
|
|
*
|
2010-06-23 15:24:24 +01:00
|
|
|
* @return string The cookie expires time
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2010-06-23 15:24:24 +01:00
|
|
|
public function getExpiresTime()
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2010-06-23 15:24:24 +01:00
|
|
|
return $this->expires;
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Gets the path of the cookie.
|
|
|
|
*
|
|
|
|
* @return string The cookie path
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function getPath()
|
|
|
|
{
|
2011-09-28 09:49:26 +01:00
|
|
|
return $this->path;
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Gets the domain of the cookie.
|
|
|
|
*
|
|
|
|
* @return string The cookie domain
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function getDomain()
|
|
|
|
{
|
|
|
|
return $this->domain;
|
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Returns the secure flag of the cookie.
|
|
|
|
*
|
|
|
|
* @return Boolean The cookie secure flag
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function isSecure()
|
|
|
|
{
|
|
|
|
return $this->secure;
|
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-06-23 15:24:24 +01:00
|
|
|
/**
|
|
|
|
* Returns the httponly flag of the cookie.
|
|
|
|
*
|
|
|
|
* @return Boolean The cookie httponly flag
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-06-23 15:24:24 +01:00
|
|
|
*/
|
2011-03-03 13:52:03 +00:00
|
|
|
public function isHttpOnly()
|
2010-06-23 15:24:24 +01:00
|
|
|
{
|
|
|
|
return $this->httponly;
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Returns true if the cookie has expired.
|
|
|
|
*
|
|
|
|
* @return Boolean true if the cookie has expired, false otherwise
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function isExpired()
|
|
|
|
{
|
2011-07-15 10:07:35 +01:00
|
|
|
return null !== $this->expires && 0 !== $this->expires && $this->expires < time();
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
}
|