Yaffs site version 1.1
[yaffs-website] / vendor / symfony / browser-kit / CookieJar.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\BrowserKit;
13
14 /**
15  * CookieJar.
16  *
17  * @author Fabien Potencier <fabien@symfony.com>
18  */
19 class CookieJar
20 {
21     protected $cookieJar = array();
22
23     /**
24      * Sets a cookie.
25      *
26      * @param Cookie $cookie A Cookie instance
27      */
28     public function set(Cookie $cookie)
29     {
30         $this->cookieJar[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
31     }
32
33     /**
34      * Gets a cookie by name.
35      *
36      * You should never use an empty domain, but if you do so,
37      * this method returns the first cookie for the given name/path
38      * (this behavior ensures a BC behavior with previous versions of
39      * Symfony).
40      *
41      * @param string $name   The cookie name
42      * @param string $path   The cookie path
43      * @param string $domain The cookie domain
44      *
45      * @return Cookie|null A Cookie instance or null if the cookie does not exist
46      */
47     public function get($name, $path = '/', $domain = null)
48     {
49         $this->flushExpiredCookies();
50
51         if (!empty($domain)) {
52             foreach ($this->cookieJar as $cookieDomain => $pathCookies) {
53                 if ($cookieDomain) {
54                     $cookieDomain = '.'.ltrim($cookieDomain, '.');
55                     if ($cookieDomain != substr('.'.$domain, -strlen($cookieDomain))) {
56                         continue;
57                     }
58                 }
59
60                 foreach ($pathCookies as $cookiePath => $namedCookies) {
61                     if ($cookiePath != substr($path, 0, strlen($cookiePath))) {
62                         continue;
63                     }
64                     if (isset($namedCookies[$name])) {
65                         return $namedCookies[$name];
66                     }
67                 }
68             }
69
70             return;
71         }
72
73         // avoid relying on this behavior that is mainly here for BC reasons
74         foreach ($this->cookieJar as $cookies) {
75             if (isset($cookies[$path][$name])) {
76                 return $cookies[$path][$name];
77             }
78         }
79     }
80
81     /**
82      * Removes a cookie by name.
83      *
84      * You should never use an empty domain, but if you do so,
85      * all cookies for the given name/path expire (this behavior
86      * ensures a BC behavior with previous versions of Symfony).
87      *
88      * @param string $name   The cookie name
89      * @param string $path   The cookie path
90      * @param string $domain The cookie domain
91      */
92     public function expire($name, $path = '/', $domain = null)
93     {
94         if (null === $path) {
95             $path = '/';
96         }
97
98         if (empty($domain)) {
99             // an empty domain means any domain
100             // this should never happen but it allows for a better BC
101             $domains = array_keys($this->cookieJar);
102         } else {
103             $domains = array($domain);
104         }
105
106         foreach ($domains as $domain) {
107             unset($this->cookieJar[$domain][$path][$name]);
108
109             if (empty($this->cookieJar[$domain][$path])) {
110                 unset($this->cookieJar[$domain][$path]);
111
112                 if (empty($this->cookieJar[$domain])) {
113                     unset($this->cookieJar[$domain]);
114                 }
115             }
116         }
117     }
118
119     /**
120      * Removes all the cookies from the jar.
121      */
122     public function clear()
123     {
124         $this->cookieJar = array();
125     }
126
127     /**
128      * Updates the cookie jar from a response Set-Cookie headers.
129      *
130      * @param array  $setCookies Set-Cookie headers from an HTTP response
131      * @param string $uri        The base URL
132      */
133     public function updateFromSetCookie(array $setCookies, $uri = null)
134     {
135         $cookies = array();
136
137         foreach ($setCookies as $cookie) {
138             foreach (explode(',', $cookie) as $i => $part) {
139                 if (0 === $i || preg_match('/^(?P<token>\s*[0-9A-Za-z!#\$%\&\'\*\+\-\.^_`\|~]+)=/', $part)) {
140                     $cookies[] = ltrim($part);
141                 } else {
142                     $cookies[count($cookies) - 1] .= ','.$part;
143                 }
144             }
145         }
146
147         foreach ($cookies as $cookie) {
148             try {
149                 $this->set(Cookie::fromString($cookie, $uri));
150             } catch (\InvalidArgumentException $e) {
151                 // invalid cookies are just ignored
152             }
153         }
154     }
155
156     /**
157      * Updates the cookie jar from a Response object.
158      *
159      * @param Response $response A Response object
160      * @param string   $uri      The base URL
161      */
162     public function updateFromResponse(Response $response, $uri = null)
163     {
164         $this->updateFromSetCookie($response->getHeader('Set-Cookie', false), $uri);
165     }
166
167     /**
168      * Returns not yet expired cookies.
169      *
170      * @return Cookie[] An array of cookies
171      */
172     public function all()
173     {
174         $this->flushExpiredCookies();
175
176         $flattenedCookies = array();
177         foreach ($this->cookieJar as $path) {
178             foreach ($path as $cookies) {
179                 foreach ($cookies as $cookie) {
180                     $flattenedCookies[] = $cookie;
181                 }
182             }
183         }
184
185         return $flattenedCookies;
186     }
187
188     /**
189      * Returns not yet expired cookie values for the given URI.
190      *
191      * @param string $uri             A URI
192      * @param bool   $returnsRawValue Returns raw value or urldecoded value
193      *
194      * @return array An array of cookie values
195      */
196     public function allValues($uri, $returnsRawValue = false)
197     {
198         $this->flushExpiredCookies();
199
200         $parts = array_replace(array('path' => '/'), parse_url($uri));
201         $cookies = array();
202         foreach ($this->cookieJar as $domain => $pathCookies) {
203             if ($domain) {
204                 $domain = '.'.ltrim($domain, '.');
205                 if ($domain != substr('.'.$parts['host'], -strlen($domain))) {
206                     continue;
207                 }
208             }
209
210             foreach ($pathCookies as $path => $namedCookies) {
211                 if ($path != substr($parts['path'], 0, strlen($path))) {
212                     continue;
213                 }
214
215                 foreach ($namedCookies as $cookie) {
216                     if ($cookie->isSecure() && 'https' != $parts['scheme']) {
217                         continue;
218                     }
219
220                     $cookies[$cookie->getName()] = $returnsRawValue ? $cookie->getRawValue() : $cookie->getValue();
221                 }
222             }
223         }
224
225         return $cookies;
226     }
227
228     /**
229      * Returns not yet expired raw cookie values for the given URI.
230      *
231      * @param string $uri A URI
232      *
233      * @return array An array of cookie values
234      */
235     public function allRawValues($uri)
236     {
237         return $this->allValues($uri, true);
238     }
239
240     /**
241      * Removes all expired cookies.
242      */
243     public function flushExpiredCookies()
244     {
245         foreach ($this->cookieJar as $domain => $pathCookies) {
246             foreach ($pathCookies as $path => $namedCookies) {
247                 foreach ($namedCookies as $name => $cookie) {
248                     if ($cookie->isExpired()) {
249                         unset($this->cookieJar[$domain][$path][$name]);
250                     }
251                 }
252             }
253         }
254     }
255 }