scratch – Blame information for rev 87

Subversion Repositories:
Rev:
Rev Author Line No. Line
87 office 1 <?php
2  
3 namespace GuzzleHttp\Cookie;
4  
5 use GuzzleHttp\ToArrayInterface;
6  
7 /**
8 * Set-Cookie object
9 */
10 class SetCookie implements ToArrayInterface
11 {
12 /** @var array */
13 private static $defaults = [
14 'Name' => null,
15 'Value' => null,
16 'Domain' => null,
17 'Path' => '/',
18 'Max-Age' => null,
19 'Expires' => null,
20 'Secure' => false,
21 'Discard' => false,
22 'HttpOnly' => false
23 ];
24  
25 /** @var array Cookie data */
26 private $data;
27  
28 /**
29 * Create a new SetCookie object from a string
30 *
31 * @param string $cookie Set-Cookie header string
32 *
33 * @return self
34 */
35 public static function fromString($cookie)
36 {
37 // Create the default return array
38 $data = self::$defaults;
39 // Explode the cookie string using a series of semicolons
40 $pieces = array_filter(array_map('trim', explode(';', $cookie)));
41 // The name of the cookie (first kvp) must include an equal sign.
42 if (empty($pieces) || !strpos($pieces[0], '=')) {
43 return new self($data);
44 }
45  
46 // Add the cookie pieces into the parsed data array
47 foreach ($pieces as $part) {
48  
49 $cookieParts = explode('=', $part, 2);
50 $key = trim($cookieParts[0]);
51 $value = isset($cookieParts[1])
52 ? trim($cookieParts[1], " \n\r\t\0\x0B\"")
53 : true;
54  
55 // Only check for non-cookies when cookies have been found
56 if (empty($data['Name'])) {
57 $data['Name'] = $key;
58 $data['Value'] = $value;
59 } else {
60 foreach (array_keys(self::$defaults) as $search) {
61 if (!strcasecmp($search, $key)) {
62 $data[$search] = $value;
63 continue 2;
64 }
65 }
66 $data[$key] = $value;
67 }
68 }
69  
70 return new self($data);
71 }
72  
73 /**
74 * @param array $data Array of cookie data provided by a Cookie parser
75 */
76 public function __construct(array $data = [])
77 {
78 $this->data = array_replace(self::$defaults, $data);
79 // Extract the Expires value and turn it into a UNIX timestamp if needed
80 if (!$this->getExpires() && $this->getMaxAge()) {
81 // Calculate the Expires date
82 $this->setExpires(time() + $this->getMaxAge());
83 } elseif ($this->getExpires() && !is_numeric($this->getExpires())) {
84 $this->setExpires($this->getExpires());
85 }
86 }
87  
88 public function __toString()
89 {
90 $str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
91 foreach ($this->data as $k => $v) {
92 if ($k != 'Name' && $k != 'Value' && $v !== null && $v !== false) {
93 if ($k == 'Expires') {
94 $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
95 } else {
96 $str .= ($v === true ? $k : "{$k}={$v}") . '; ';
97 }
98 }
99 }
100  
101 return rtrim($str, '; ');
102 }
103  
104 public function toArray()
105 {
106 return $this->data;
107 }
108  
109 /**
110 * Get the cookie name
111 *
112 * @return string
113 */
114 public function getName()
115 {
116 return $this->data['Name'];
117 }
118  
119 /**
120 * Set the cookie name
121 *
122 * @param string $name Cookie name
123 *
124 * @return self
125 */
126 public function setName($name)
127 {
128 $this->data['Name'] = $name;
129  
130 return $this;
131 }
132  
133 /**
134 * Get the cookie value
135 *
136 * @return string
137 */
138 public function getValue()
139 {
140 return $this->data['Value'];
141 }
142  
143 /**
144 * Set the cookie value
145 *
146 * @param string $value Cookie value
147 *
148 * @return self
149 */
150 public function setValue($value)
151 {
152 $this->data['Value'] = $value;
153  
154 return $this;
155 }
156  
157 /**
158 * Get the domain
159 *
160 * @return string|null
161 */
162 public function getDomain()
163 {
164 return $this->data['Domain'];
165 }
166  
167 /**
168 * Set the domain of the cookie
169 *
170 * @param string $domain
171 *
172 * @return self
173 */
174 public function setDomain($domain)
175 {
176 $this->data['Domain'] = $domain;
177  
178 return $this;
179 }
180  
181 /**
182 * Get the path
183 *
184 * @return string
185 */
186 public function getPath()
187 {
188 return $this->data['Path'];
189 }
190  
191 /**
192 * Set the path of the cookie
193 *
194 * @param string $path Path of the cookie
195 *
196 * @return self
197 */
198 public function setPath($path)
199 {
200 $this->data['Path'] = $path;
201  
202 return $this;
203 }
204  
205 /**
206 * Maximum lifetime of the cookie in seconds
207 *
208 * @return int|null
209 */
210 public function getMaxAge()
211 {
212 return $this->data['Max-Age'];
213 }
214  
215 /**
216 * Set the max-age of the cookie
217 *
218 * @param int $maxAge Max age of the cookie in seconds
219 *
220 * @return self
221 */
222 public function setMaxAge($maxAge)
223 {
224 $this->data['Max-Age'] = $maxAge;
225  
226 return $this;
227 }
228  
229 /**
230 * The UNIX timestamp when the cookie Expires
231 *
232 * @return mixed
233 */
234 public function getExpires()
235 {
236 return $this->data['Expires'];
237 }
238  
239 /**
240 * Set the unix timestamp for which the cookie will expire
241 *
242 * @param int $timestamp Unix timestamp
243 *
244 * @return self
245 */
246 public function setExpires($timestamp)
247 {
248 $this->data['Expires'] = is_numeric($timestamp)
249 ? (int) $timestamp
250 : strtotime($timestamp);
251  
252 return $this;
253 }
254  
255 /**
256 * Get whether or not this is a secure cookie
257 *
258 * @return null|bool
259 */
260 public function getSecure()
261 {
262 return $this->data['Secure'];
263 }
264  
265 /**
266 * Set whether or not the cookie is secure
267 *
268 * @param bool $secure Set to true or false if secure
269 *
270 * @return self
271 */
272 public function setSecure($secure)
273 {
274 $this->data['Secure'] = $secure;
275  
276 return $this;
277 }
278  
279 /**
280 * Get whether or not this is a session cookie
281 *
282 * @return null|bool
283 */
284 public function getDiscard()
285 {
286 return $this->data['Discard'];
287 }
288  
289 /**
290 * Set whether or not this is a session cookie
291 *
292 * @param bool $discard Set to true or false if this is a session cookie
293 *
294 * @return self
295 */
296 public function setDiscard($discard)
297 {
298 $this->data['Discard'] = $discard;
299  
300 return $this;
301 }
302  
303 /**
304 * Get whether or not this is an HTTP only cookie
305 *
306 * @return bool
307 */
308 public function getHttpOnly()
309 {
310 return $this->data['HttpOnly'];
311 }
312  
313 /**
314 * Set whether or not this is an HTTP only cookie
315 *
316 * @param bool $httpOnly Set to true or false if this is HTTP only
317 *
318 * @return self
319 */
320 public function setHttpOnly($httpOnly)
321 {
322 $this->data['HttpOnly'] = $httpOnly;
323  
324 return $this;
325 }
326  
327 /**
328 * Check if the cookie matches a path value
329 *
330 * @param string $path Path to check against
331 *
332 * @return bool
333 */
334 public function matchesPath($path)
335 {
336 return !$this->getPath() || 0 === stripos($path, $this->getPath());
337 }
338  
339 /**
340 * Check if the cookie matches a domain value
341 *
342 * @param string $domain Domain to check against
343 *
344 * @return bool
345 */
346 public function matchesDomain($domain)
347 {
348 // Remove the leading '.' as per spec in RFC 6265.
349 // http://tools.ietf.org/html/rfc6265#section-5.2.3
350 $cookieDomain = ltrim($this->getDomain(), '.');
351  
352 // Domain not set or exact match.
353 if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) {
354 return true;
355 }
356  
357 // Matching the subdomain according to RFC 6265.
358 // http://tools.ietf.org/html/rfc6265#section-5.1.3
359 if (filter_var($domain, FILTER_VALIDATE_IP)) {
360 return false;
361 }
362  
363 return (bool) preg_match('/\.' . preg_quote($cookieDomain) . '$/i', $domain);
364 }
365  
366 /**
367 * Check if the cookie is expired
368 *
369 * @return bool
370 */
371 public function isExpired()
372 {
373 return $this->getExpires() && time() > $this->getExpires();
374 }
375  
376 /**
377 * Check if the cookie is valid according to RFC 6265
378 *
379 * @return bool|string Returns true if valid or an error message if invalid
380 */
381 public function validate()
382 {
383 // Names must not be empty, but can be 0
384 $name = $this->getName();
385 if (empty($name) && !is_numeric($name)) {
386 return 'The cookie name must not be empty';
387 }
388  
389 // Check if any of the invalid characters are present in the cookie name
390 if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
391 return "Cookie name must not cannot invalid characters: =,; \\t\\r\\n\\013\\014";
392 }
393  
394 // Value must not be empty, but can be 0
395 $value = $this->getValue();
396 if (empty($value) && !is_numeric($value)) {
397 return 'The cookie value must not be empty';
398 }
399  
400 // Domains must not be empty, but can be 0
401 // A "0" is not a valid internet domain, but may be used as server name
402 // in a private network.
403 $domain = $this->getDomain();
404 if (empty($domain) && !is_numeric($domain)) {
405 return 'The cookie domain must not be empty';
406 }
407  
408 return true;
409 }
410 }