4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\BrowserKit;
17 * @author Fabien Potencier <fabien@symfony.com>
21 protected $cookieJar = array();
23 public function set(Cookie $cookie)
25 $this->cookieJar[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
29 * Gets a cookie by name.
31 * You should never use an empty domain, but if you do so,
32 * this method returns the first cookie for the given name/path
33 * (this behavior ensures a BC behavior with previous versions of
36 * @param string $name The cookie name
37 * @param string $path The cookie path
38 * @param string $domain The cookie domain
40 * @return Cookie|null A Cookie instance or null if the cookie does not exist
42 public function get($name, $path = '/', $domain = null)
44 $this->flushExpiredCookies();
46 foreach ($this->cookieJar as $cookieDomain => $pathCookies) {
47 if ($cookieDomain && $domain) {
48 $cookieDomain = '.'.ltrim($cookieDomain, '.');
49 if ($cookieDomain !== substr('.'.$domain, -\strlen($cookieDomain))) {
54 foreach ($pathCookies as $cookiePath => $namedCookies) {
55 if (0 !== strpos($path, $cookiePath)) {
58 if (isset($namedCookies[$name])) {
59 return $namedCookies[$name];
66 * Removes a cookie by name.
68 * You should never use an empty domain, but if you do so,
69 * all cookies for the given name/path expire (this behavior
70 * ensures a BC behavior with previous versions of Symfony).
72 * @param string $name The cookie name
73 * @param string $path The cookie path
74 * @param string $domain The cookie domain
76 public function expire($name, $path = '/', $domain = null)
83 // an empty domain means any domain
84 // this should never happen but it allows for a better BC
85 $domains = array_keys($this->cookieJar);
87 $domains = array($domain);
90 foreach ($domains as $domain) {
91 unset($this->cookieJar[$domain][$path][$name]);
93 if (empty($this->cookieJar[$domain][$path])) {
94 unset($this->cookieJar[$domain][$path]);
96 if (empty($this->cookieJar[$domain])) {
97 unset($this->cookieJar[$domain]);
104 * Removes all the cookies from the jar.
106 public function clear()
108 $this->cookieJar = array();
112 * Updates the cookie jar from a response Set-Cookie headers.
114 * @param array $setCookies Set-Cookie headers from an HTTP response
115 * @param string $uri The base URL
117 public function updateFromSetCookie(array $setCookies, $uri = null)
121 foreach ($setCookies as $cookie) {
122 foreach (explode(',', $cookie) as $i => $part) {
123 if (0 === $i || preg_match('/^(?P<token>\s*[0-9A-Za-z!#\$%\&\'\*\+\-\.^_`\|~]+)=/', $part)) {
124 $cookies[] = ltrim($part);
126 $cookies[count($cookies) - 1] .= ','.$part;
131 foreach ($cookies as $cookie) {
133 $this->set(Cookie::fromString($cookie, $uri));
134 } catch (\InvalidArgumentException $e) {
135 // invalid cookies are just ignored
141 * Updates the cookie jar from a Response object.
143 * @param Response $response A Response object
144 * @param string $uri The base URL
146 public function updateFromResponse(Response $response, $uri = null)
148 $this->updateFromSetCookie($response->getHeader('Set-Cookie', false), $uri);
152 * Returns not yet expired cookies.
154 * @return Cookie[] An array of cookies
156 public function all()
158 $this->flushExpiredCookies();
160 $flattenedCookies = array();
161 foreach ($this->cookieJar as $path) {
162 foreach ($path as $cookies) {
163 foreach ($cookies as $cookie) {
164 $flattenedCookies[] = $cookie;
169 return $flattenedCookies;
173 * Returns not yet expired cookie values for the given URI.
175 * @param string $uri A URI
176 * @param bool $returnsRawValue Returns raw value or urldecoded value
178 * @return array An array of cookie values
180 public function allValues($uri, $returnsRawValue = false)
182 $this->flushExpiredCookies();
184 $parts = array_replace(array('path' => '/'), parse_url($uri));
186 foreach ($this->cookieJar as $domain => $pathCookies) {
188 $domain = '.'.ltrim($domain, '.');
189 if ($domain != substr('.'.$parts['host'], -strlen($domain))) {
194 foreach ($pathCookies as $path => $namedCookies) {
195 if ($path != substr($parts['path'], 0, strlen($path))) {
199 foreach ($namedCookies as $cookie) {
200 if ($cookie->isSecure() && 'https' != $parts['scheme']) {
204 $cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue();
213 * Returns not yet expired raw cookie values for the given URI.
215 * @param string $uri A URI
217 * @return array An array of cookie values
219 public function allRawValues($uri)
221 return $this->allValues($uri, true);
225 * Removes all expired cookies.
227 public function flushExpiredCookies()
229 foreach ($this->cookieJar as $domain => $pathCookies) {
230 foreach ($pathCookies as $path => $namedCookies) {
231 foreach ($namedCookies as $name => $cookie) {
232 if ($cookie->isExpired()) {
233 unset($this->cookieJar[$domain][$path][$name]);