]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/Requests/Requests/Cookie.php
Add Requests 1.6
[Github/YOURLS.git] / includes / Requests / Requests / Cookie.php
1 <?php
2 /**
3  * Cookie storage object
4  *
5  * @package Requests
6  * @subpackage Cookies
7  */
8
9 /**
10  * Cookie storage object
11  *
12  * @package Requests
13  * @subpackage Cookies
14  */
15 class Requests_Cookie {
16         /**
17          * 
18          * @var string
19          */
20         public $name;
21
22         /**
23          * @var string
24          */
25         public $value;
26
27         /**
28          * Cookie attributes
29          * 
30          * Valid keys are (currently) path, domain, expires, max-age, secure and
31          * httponly.
32          *
33          * @var array
34          */
35         public $attributes = array();
36
37         /**
38          * Create a new cookie object
39          *
40          * @param string $name
41          * @param string $value
42          * @param array $attributes Associative array of attribute data
43          */
44         public function __construct($name, $value, $attributes = array()) {
45                 $this->name = $name;
46                 $this->value = $value;
47                 $this->attributes = $attributes;
48         }
49
50         /**
51          * Format a cookie for a Cookie header
52          *
53          * This is used when sending cookies to a server.
54          *
55          * @return string Cookie formatted for Cookie header
56          */
57         public function formatForHeader() {
58                 return sprintf('%s=%s', $this->name, $this->value);
59         }
60
61         /**
62          * Format a cookie for a Set-Cookie header
63          *
64          * This is used when sending cookies to clients. This isn't really
65          * applicable to client-side usage, but might be handy for debugging.
66          *
67          * @return string Cookie formatted for Set-Cookie header
68          */
69         public function formatForSetCookie() {
70                 $header_value = $this->formatForHeader();
71                 if (!empty($this->attributes)) {
72                         $parts = array();
73                         foreach ($this->attributes as $key => $value) {
74                                 // Ignore non-associative attributes
75                                 if (is_numeric($key)) {
76                                         $parts[] = $value;
77                                 }
78                                 else {
79                                         $parts[] = sprintf('%s=%s', $key, $value);
80                                 }
81                         }
82
83                         $header_value .= '; ' . implode('; ', $parts);
84                 }
85                 return $header_value;
86         }
87
88         /**
89          * Get the cookie value
90          *
91          * Attributes and other data can be accessed via methods.
92          */
93         public function __toString() {
94                 return $this->value;
95         }
96
97         /**
98          * Parse a cookie string into a cookie object
99          *
100          * Based on Mozilla's parsing code in Firefox and related projects, which
101          * is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265
102          * specifies some of this handling, but not in a thorough manner.
103          *
104          * @param string Cookie header value (from a Set-Cookie header)
105          * @return Requests_Cookie Parsed cookie object
106          */
107         public static function parse($string, $name = '') {
108                 $parts = explode(';', $string);
109                 $kvparts = array_shift($parts);
110
111                 if (!empty($name)) {
112                         $value = $string;
113                 }
114                 elseif (strpos($kvparts, '=') === false) {
115                         // Some sites might only have a value without the equals separator.
116                         // Deviate from RFC 6265 and pretend it was actually a blank name
117                         // (`=foo`)
118                         //
119                         // https://bugzilla.mozilla.org/show_bug.cgi?id=169091
120                         $name = '';
121                         $value = $kvparts;
122                 }
123                 else {
124                         list($name, $value) = explode('=', $kvparts, 2);
125                 }
126                 $name = trim($name);
127                 $value = trim($value);
128
129                 // Attribute key are handled case-insensitively
130                 $attributes = new Requests_Utility_CaseInsensitiveDictionary();
131
132                 if (!empty($parts)) {
133                         foreach ($parts as $part) {
134                                 if (strpos($part, '=') === false) {
135                                         $part_key = $part;
136                                         $part_value = true;
137                                 }
138                                 else {
139                                         list($part_key, $part_value) = explode('=', $part, 2);
140                                         $part_value = trim($part_value);
141                                 }
142
143                                 $part_key = trim($part_key);
144                                 $attributes[$part_key] = $part_value;
145                         }
146                 }
147
148                 return new Requests_Cookie($name, $value, $attributes);
149         }
150
151         /**
152          * Parse all Set-Cookie headers from request headers
153          *
154          * @param Requests_Response_Headers $headers
155          * @return array
156          */
157         public static function parseFromHeaders(Requests_Response_Headers $headers) {
158                 $cookie_headers = $headers->getValues('Set-Cookie');
159                 if (empty($cookie_headers)) {
160                         return array();
161                 }
162
163                 $cookies = array();
164                 foreach ($cookie_headers as $header) {
165                         $parsed = self::parse($header);
166                         $cookies[$parsed->name] = $parsed;
167                 }
168
169                 return $cookies;
170         }
171 }