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
|
|
|
/**
|
|
|
|
* CookieJar.
|
|
|
|
*
|
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 CookieJar
|
|
|
|
{
|
2010-05-06 12:25:53 +01:00
|
|
|
protected $cookieJar = array();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets a cookie.
|
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @param Cookie $cookie A Cookie instance
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function set(Cookie $cookie)
|
2010-04-19 13:12:42 +01:00
|
|
|
{
|
2011-09-20 19:51:19 +01:00
|
|
|
$this->cookieJar[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
|
2010-04-19 13:12:42 +01:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a cookie by name.
|
|
|
|
*
|
2013-04-29 21:22:06 +01:00
|
|
|
* You should never use an empty domain, but if you do so,
|
|
|
|
* this method returns the first cookie for the given name/path
|
|
|
|
* (this behavior ensures a BC behavior with previous versions of
|
|
|
|
* Symfony).
|
|
|
|
*
|
2011-09-20 19:51:19 +01:00
|
|
|
* @param string $name The cookie name
|
|
|
|
* @param string $path The cookie path
|
|
|
|
* @param string $domain The cookie domain
|
2010-05-06 12:25:53 +01:00
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @return Cookie|null A Cookie instance or null if the cookie does not exist
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2011-09-20 19:51:19 +01:00
|
|
|
public function get($name, $path = '/', $domain = null)
|
2010-04-19 13:12:42 +01:00
|
|
|
{
|
2010-05-06 12:25:53 +01:00
|
|
|
$this->flushExpiredCookies();
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2013-04-29 21:22:06 +01:00
|
|
|
if (!empty($domain)) {
|
|
|
|
return isset($this->cookieJar[$domain][$path][$name]) ? $this->cookieJar[$domain][$path][$name] : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// avoid relying on this behavior that is mainly here for BC reasons
|
2013-07-07 11:19:59 +01:00
|
|
|
foreach ($this->cookieJar as $cookies) {
|
2013-04-29 21:22:06 +01:00
|
|
|
if (isset($cookies[$path][$name])) {
|
|
|
|
return $cookies[$path][$name];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Removes a cookie by name.
|
|
|
|
*
|
2013-04-29 21:22:06 +01:00
|
|
|
* You should never use an empty domain, but if you do so,
|
|
|
|
* all cookies for the given name/path expire (this behavior
|
|
|
|
* ensures a BC behavior with previous versions of Symfony).
|
|
|
|
*
|
2011-09-20 19:51:19 +01:00
|
|
|
* @param string $name The cookie name
|
|
|
|
* @param string $path The cookie path
|
|
|
|
* @param string $domain The cookie domain
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2011-09-20 19:51:19 +01:00
|
|
|
public function expire($name, $path = '/', $domain = null)
|
2010-04-19 13:12:42 +01:00
|
|
|
{
|
2011-09-20 19:51:19 +01:00
|
|
|
if (null === $path) {
|
|
|
|
$path = '/';
|
|
|
|
}
|
|
|
|
|
2013-04-29 21:22:06 +01:00
|
|
|
if (empty($domain)) {
|
|
|
|
// an empty domain means any domain
|
|
|
|
// this should never happen but it allows for a better BC
|
|
|
|
$domains = array_keys($this->cookieJar);
|
|
|
|
} else {
|
|
|
|
$domains = array($domain);
|
|
|
|
}
|
2011-09-20 19:51:19 +01:00
|
|
|
|
2013-04-29 21:22:06 +01:00
|
|
|
foreach ($domains as $domain) {
|
|
|
|
unset($this->cookieJar[$domain][$path][$name]);
|
2011-09-20 19:51:19 +01:00
|
|
|
|
2013-04-29 21:22:06 +01:00
|
|
|
if (empty($this->cookieJar[$domain][$path])) {
|
|
|
|
unset($this->cookieJar[$domain][$path]);
|
|
|
|
|
|
|
|
if (empty($this->cookieJar[$domain])) {
|
|
|
|
unset($this->cookieJar[$domain]);
|
|
|
|
}
|
2011-09-20 19:51:19 +01:00
|
|
|
}
|
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes all the cookies from the jar.
|
2011-03-24 08:25:46 +00:00
|
|
|
*
|
|
|
|
* @api
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function clear()
|
|
|
|
{
|
|
|
|
$this->cookieJar = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-05-01 22:09:37 +01:00
|
|
|
* Updates the cookie jar from a response Set-Cookie headers.
|
2010-05-06 12:25:53 +01:00
|
|
|
*
|
2012-05-15 21:19:31 +01:00
|
|
|
* @param array $setCookies Set-Cookie headers from an HTTP response
|
|
|
|
* @param string $uri The base URL
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2012-05-01 22:09:37 +01:00
|
|
|
public function updateFromSetCookie(array $setCookies, $uri = null)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2012-04-07 18:38:39 +01:00
|
|
|
$cookies = array();
|
|
|
|
|
2012-05-01 22:09:37 +01:00
|
|
|
foreach ($setCookies as $cookie) {
|
2012-04-07 18:38:39 +01:00
|
|
|
foreach (explode(',', $cookie) as $i => $part) {
|
2012-04-07 19:45:50 +01:00
|
|
|
if (0 === $i || preg_match('/^(?P<token>\s*[0-9A-Za-z!#\$%\&\'\*\+\-\.^_`\|~]+)=/', $part)) {
|
2012-04-07 18:38:39 +01:00
|
|
|
$cookies[] = ltrim($part);
|
|
|
|
} else {
|
2012-04-07 19:45:50 +01:00
|
|
|
$cookies[count($cookies) - 1] .= ','.$part;
|
2012-04-07 18:38:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($cookies as $cookie) {
|
2013-03-12 15:50:09 +00:00
|
|
|
try {
|
|
|
|
$this->set(Cookie::fromString($cookie, $uri));
|
|
|
|
} catch (\InvalidArgumentException $e) {
|
|
|
|
// invalid cookies are just ignored
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-01 22:09:37 +01:00
|
|
|
/**
|
|
|
|
* Updates the cookie jar from a Response object.
|
|
|
|
*
|
|
|
|
* @param Response $response A Response object
|
2012-05-15 21:19:31 +01:00
|
|
|
* @param string $uri The base URL
|
2012-05-01 22:09:37 +01:00
|
|
|
*/
|
|
|
|
public function updateFromResponse(Response $response, $uri = null)
|
|
|
|
{
|
|
|
|
$this->updateFromSetCookie($response->getHeader('Set-Cookie', false), $uri);
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Returns not yet expired cookies.
|
|
|
|
*
|
2012-11-01 15:08:59 +00:00
|
|
|
* @return Cookie[] An array of cookies
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
|
|
|
public function all()
|
|
|
|
{
|
|
|
|
$this->flushExpiredCookies();
|
|
|
|
|
2011-09-20 19:51:19 +01:00
|
|
|
$flattenedCookies = array();
|
|
|
|
foreach ($this->cookieJar as $path) {
|
|
|
|
foreach ($path as $cookies) {
|
|
|
|
foreach ($cookies as $cookie) {
|
|
|
|
$flattenedCookies[] = $cookie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $flattenedCookies;
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns not yet expired cookie values for the given URI.
|
|
|
|
*
|
2011-09-20 19:51:19 +01:00
|
|
|
* @param string $uri A URI
|
2011-06-04 16:30:56 +01:00
|
|
|
* @param Boolean $returnsRawValue Returns raw value or urldecoded value
|
2010-05-06 12:25:53 +01:00
|
|
|
*
|
|
|
|
* @return array An array of cookie values
|
|
|
|
*/
|
2011-05-22 12:06:09 +01:00
|
|
|
public function allValues($uri, $returnsRawValue = false)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
|
|
|
$this->flushExpiredCookies();
|
|
|
|
|
2011-05-24 19:08:11 +01:00
|
|
|
$parts = array_replace(array('path' => '/'), parse_url($uri));
|
2010-05-06 12:25:53 +01:00
|
|
|
$cookies = array();
|
2011-09-20 19:51:19 +01:00
|
|
|
foreach ($this->cookieJar as $domain => $pathCookies) {
|
|
|
|
if ($domain) {
|
2013-09-25 12:22:21 +01:00
|
|
|
$domain = '.'.ltrim($domain, '.');
|
|
|
|
if ($domain != substr('.'.$parts['host'], -strlen($domain))) {
|
2011-05-24 19:08:11 +01:00
|
|
|
continue;
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
|
2011-09-20 19:51:19 +01:00
|
|
|
foreach ($pathCookies as $path => $namedCookies) {
|
|
|
|
if ($path != substr($parts['path'], 0, strlen($path))) {
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2012-01-10 19:57:15 +00:00
|
|
|
foreach ($namedCookies as $cookie) {
|
2011-09-20 19:51:19 +01:00
|
|
|
if ($cookie->isSecure() && 'https' != $parts['scheme']) {
|
|
|
|
continue;
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2011-09-20 19:51:19 +01:00
|
|
|
$cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue();
|
|
|
|
}
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $cookies;
|
|
|
|
}
|
|
|
|
|
2011-05-22 12:06:09 +01:00
|
|
|
/**
|
|
|
|
* Returns not yet expired raw cookie values for the given URI.
|
|
|
|
*
|
|
|
|
* @param string $uri A URI
|
|
|
|
*
|
|
|
|
* @return array An array of cookie values
|
|
|
|
*/
|
2011-05-24 19:23:23 +01:00
|
|
|
public function allRawValues($uri)
|
|
|
|
{
|
2011-05-22 12:06:09 +01:00
|
|
|
return $this->allValues($uri, true);
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Removes all expired cookies.
|
|
|
|
*/
|
|
|
|
public function flushExpiredCookies()
|
|
|
|
{
|
2011-09-20 19:51:19 +01:00
|
|
|
foreach ($this->cookieJar as $domain => $pathCookies) {
|
|
|
|
foreach ($pathCookies as $path => $namedCookies) {
|
|
|
|
foreach ($namedCookies as $name => $cookie) {
|
|
|
|
if ($cookie->isExpired()) {
|
|
|
|
unset($this->cookieJar[$domain][$path][$name]);
|
|
|
|
}
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-04-19 13:12:42 +01:00
|
|
|
}
|