Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / symfony / browser-kit / Cookie.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  * Cookie represents an HTTP cookie.
16  *
17  * @author Fabien Potencier <fabien@symfony.com>
18  */
19 class Cookie
20 {
21     /**
22      * Handles dates as defined by RFC 2616 section 3.3.1, and also some other
23      * non-standard, but common formats.
24      */
25     private static $dateFormats = array(
26         'D, d M Y H:i:s T',
27         'D, d-M-y H:i:s T',
28         'D, d-M-Y H:i:s T',
29         'D, d-m-y H:i:s T',
30         'D, d-m-Y H:i:s T',
31         'D M j G:i:s Y',
32         'D M d H:i:s Y T',
33     );
34
35     protected $name;
36     protected $value;
37     protected $expires;
38     protected $path;
39     protected $domain;
40     protected $secure;
41     protected $httponly;
42     protected $rawValue;
43
44     /**
45      * Sets a cookie.
46      *
47      * @param string      $name         The cookie name
48      * @param string      $value        The value of the cookie
49      * @param string|null $expires      The time the cookie expires
50      * @param string|null $path         The path on the server in which the cookie will be available on
51      * @param string      $domain       The domain that the cookie is available
52      * @param bool        $secure       Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client
53      * @param bool        $httponly     The cookie httponly flag
54      * @param bool        $encodedValue Whether the value is encoded or not
55      */
56     public function __construct($name, $value, $expires = null, $path = null, $domain = '', $secure = false, $httponly = true, $encodedValue = false)
57     {
58         if ($encodedValue) {
59             $this->value = urldecode($value);
60             $this->rawValue = $value;
61         } else {
62             $this->value = $value;
63             $this->rawValue = rawurlencode($value);
64         }
65         $this->name = $name;
66         $this->path = empty($path) ? '/' : $path;
67         $this->domain = $domain;
68         $this->secure = (bool) $secure;
69         $this->httponly = (bool) $httponly;
70
71         if (null !== $expires) {
72             $timestampAsDateTime = \DateTime::createFromFormat('U', $expires);
73             if (false === $timestampAsDateTime) {
74                 throw new \UnexpectedValueException(sprintf('The cookie expiration time "%s" is not valid.', $expires));
75             }
76
77             $this->expires = $timestampAsDateTime->format('U');
78         }
79     }
80
81     /**
82      * Returns the HTTP representation of the Cookie.
83      */
84     public function __toString()
85     {
86         $cookie = sprintf('%s=%s', $this->name, $this->rawValue);
87
88         if (null !== $this->expires) {
89             $dateTime = \DateTime::createFromFormat('U', $this->expires, new \DateTimeZone('GMT'));
90             $cookie .= '; expires='.str_replace('+0000', '', $dateTime->format(self::$dateFormats[0]));
91         }
92
93         if ('' !== $this->domain) {
94             $cookie .= '; domain='.$this->domain;
95         }
96
97         if ($this->path) {
98             $cookie .= '; path='.$this->path;
99         }
100
101         if ($this->secure) {
102             $cookie .= '; secure';
103         }
104
105         if ($this->httponly) {
106             $cookie .= '; httponly';
107         }
108
109         return $cookie;
110     }
111
112     /**
113      * Creates a Cookie instance from a Set-Cookie header value.
114      *
115      * @param string      $cookie A Set-Cookie header value
116      * @param string|null $url    The base URL
117      *
118      * @return static
119      *
120      * @throws \InvalidArgumentException
121      */
122     public static function fromString($cookie, $url = null)
123     {
124         $parts = explode(';', $cookie);
125
126         if (false === strpos($parts[0], '=')) {
127             throw new \InvalidArgumentException(sprintf('The cookie string "%s" is not valid.', $parts[0]));
128         }
129
130         list($name, $value) = explode('=', array_shift($parts), 2);
131
132         $values = array(
133             'name' => trim($name),
134             'value' => trim($value),
135             'expires' => null,
136             'path' => '/',
137             'domain' => '',
138             'secure' => false,
139             'httponly' => false,
140             'passedRawValue' => true,
141         );
142
143         if (null !== $url) {
144             if ((false === $urlParts = parse_url($url)) || !isset($urlParts['host'])) {
145                 throw new \InvalidArgumentException(sprintf('The URL "%s" is not valid.', $url));
146             }
147
148             $values['domain'] = $urlParts['host'];
149             $values['path'] = isset($urlParts['path']) ? substr($urlParts['path'], 0, strrpos($urlParts['path'], '/')) : '';
150         }
151
152         foreach ($parts as $part) {
153             $part = trim($part);
154
155             if ('secure' === strtolower($part)) {
156                 // Ignore the secure flag if the original URI is not given or is not HTTPS
157                 if (!$url || !isset($urlParts['scheme']) || 'https' != $urlParts['scheme']) {
158                     continue;
159                 }
160
161                 $values['secure'] = true;
162
163                 continue;
164             }
165
166             if ('httponly' === strtolower($part)) {
167                 $values['httponly'] = true;
168
169                 continue;
170             }
171
172             if (2 === count($elements = explode('=', $part, 2))) {
173                 if ('expires' === strtolower($elements[0])) {
174                     $elements[1] = self::parseDate($elements[1]);
175                 }
176
177                 $values[strtolower($elements[0])] = $elements[1];
178             }
179         }
180
181         return new static(
182             $values['name'],
183             $values['value'],
184             $values['expires'],
185             $values['path'],
186             $values['domain'],
187             $values['secure'],
188             $values['httponly'],
189             $values['passedRawValue']
190         );
191     }
192
193     private static function parseDate($dateValue)
194     {
195         // trim single quotes around date if present
196         if (($length = strlen($dateValue)) > 1 && "'" === $dateValue[0] && "'" === $dateValue[$length - 1]) {
197             $dateValue = substr($dateValue, 1, -1);
198         }
199
200         foreach (self::$dateFormats as $dateFormat) {
201             if (false !== $date = \DateTime::createFromFormat($dateFormat, $dateValue, new \DateTimeZone('GMT'))) {
202                 return $date->format('U');
203             }
204         }
205
206         // attempt a fallback for unusual formatting
207         if (false !== $date = date_create($dateValue, new \DateTimeZone('GMT'))) {
208             return $date->format('U');
209         }
210     }
211
212     /**
213      * Gets the name of the cookie.
214      *
215      * @return string The cookie name
216      */
217     public function getName()
218     {
219         return $this->name;
220     }
221
222     /**
223      * Gets the value of the cookie.
224      *
225      * @return string The cookie value
226      */
227     public function getValue()
228     {
229         return $this->value;
230     }
231
232     /**
233      * Gets the raw value of the cookie.
234      *
235      * @return string The cookie value
236      */
237     public function getRawValue()
238     {
239         return $this->rawValue;
240     }
241
242     /**
243      * Gets the expires time of the cookie.
244      *
245      * @return string|null The cookie expires time
246      */
247     public function getExpiresTime()
248     {
249         return $this->expires;
250     }
251
252     /**
253      * Gets the path of the cookie.
254      *
255      * @return string The cookie path
256      */
257     public function getPath()
258     {
259         return $this->path;
260     }
261
262     /**
263      * Gets the domain of the cookie.
264      *
265      * @return string The cookie domain
266      */
267     public function getDomain()
268     {
269         return $this->domain;
270     }
271
272     /**
273      * Returns the secure flag of the cookie.
274      *
275      * @return bool The cookie secure flag
276      */
277     public function isSecure()
278     {
279         return $this->secure;
280     }
281
282     /**
283      * Returns the httponly flag of the cookie.
284      *
285      * @return bool The cookie httponly flag
286      */
287     public function isHttpOnly()
288     {
289         return $this->httponly;
290     }
291
292     /**
293      * Returns true if the cookie has expired.
294      *
295      * @return bool true if the cookie has expired, false otherwise
296      */
297     public function isExpired()
298     {
299         return null !== $this->expires && 0 != $this->expires && $this->expires < time();
300     }
301 }