Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/http-foundation/HeaderBag.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
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\HttpFoundation; | |
13 | |
14 /** | |
15 * HeaderBag is a container for HTTP headers. | |
16 * | |
17 * @author Fabien Potencier <fabien@symfony.com> | |
18 */ | |
19 class HeaderBag implements \IteratorAggregate, \Countable | |
20 { | |
21 protected $headers = array(); | |
22 protected $cacheControl = array(); | |
23 | |
24 /** | |
25 * Constructor. | |
26 * | |
27 * @param array $headers An array of HTTP headers | |
28 */ | |
29 public function __construct(array $headers = array()) | |
30 { | |
31 foreach ($headers as $key => $values) { | |
32 $this->set($key, $values); | |
33 } | |
34 } | |
35 | |
36 /** | |
37 * Returns the headers as a string. | |
38 * | |
39 * @return string The headers | |
40 */ | |
41 public function __toString() | |
42 { | |
43 if (!$this->headers) { | |
44 return ''; | |
45 } | |
46 | |
47 $max = max(array_map('strlen', array_keys($this->headers))) + 1; | |
48 $content = ''; | |
49 ksort($this->headers); | |
50 foreach ($this->headers as $name => $values) { | |
51 $name = implode('-', array_map('ucfirst', explode('-', $name))); | |
52 foreach ($values as $value) { | |
53 $content .= sprintf("%-{$max}s %s\r\n", $name.':', $value); | |
54 } | |
55 } | |
56 | |
57 return $content; | |
58 } | |
59 | |
60 /** | |
61 * Returns the headers. | |
62 * | |
63 * @return array An array of headers | |
64 */ | |
65 public function all() | |
66 { | |
67 return $this->headers; | |
68 } | |
69 | |
70 /** | |
71 * Returns the parameter keys. | |
72 * | |
73 * @return array An array of parameter keys | |
74 */ | |
75 public function keys() | |
76 { | |
77 return array_keys($this->headers); | |
78 } | |
79 | |
80 /** | |
81 * Replaces the current HTTP headers by a new set. | |
82 * | |
83 * @param array $headers An array of HTTP headers | |
84 */ | |
85 public function replace(array $headers = array()) | |
86 { | |
87 $this->headers = array(); | |
88 $this->add($headers); | |
89 } | |
90 | |
91 /** | |
92 * Adds new headers the current HTTP headers set. | |
93 * | |
94 * @param array $headers An array of HTTP headers | |
95 */ | |
96 public function add(array $headers) | |
97 { | |
98 foreach ($headers as $key => $values) { | |
99 $this->set($key, $values); | |
100 } | |
101 } | |
102 | |
103 /** | |
104 * Returns a header value by name. | |
105 * | |
106 * @param string $key The header name | |
107 * @param mixed $default The default value | |
108 * @param bool $first Whether to return the first value or all header values | |
109 * | |
110 * @return string|array The first header value if $first is true, an array of values otherwise | |
111 */ | |
112 public function get($key, $default = null, $first = true) | |
113 { | |
114 $key = str_replace('_', '-', strtolower($key)); | |
115 | |
116 if (!array_key_exists($key, $this->headers)) { | |
117 if (null === $default) { | |
118 return $first ? null : array(); | |
119 } | |
120 | |
121 return $first ? $default : array($default); | |
122 } | |
123 | |
124 if ($first) { | |
125 return count($this->headers[$key]) ? $this->headers[$key][0] : $default; | |
126 } | |
127 | |
128 return $this->headers[$key]; | |
129 } | |
130 | |
131 /** | |
132 * Sets a header by name. | |
133 * | |
134 * @param string $key The key | |
135 * @param string|array $values The value or an array of values | |
136 * @param bool $replace Whether to replace the actual value or not (true by default) | |
137 */ | |
138 public function set($key, $values, $replace = true) | |
139 { | |
140 $key = str_replace('_', '-', strtolower($key)); | |
141 | |
142 $values = array_values((array) $values); | |
143 | |
144 if (true === $replace || !isset($this->headers[$key])) { | |
145 $this->headers[$key] = $values; | |
146 } else { | |
147 $this->headers[$key] = array_merge($this->headers[$key], $values); | |
148 } | |
149 | |
150 if ('cache-control' === $key) { | |
151 $this->cacheControl = $this->parseCacheControl($values[0]); | |
152 } | |
153 } | |
154 | |
155 /** | |
156 * Returns true if the HTTP header is defined. | |
157 * | |
158 * @param string $key The HTTP header | |
159 * | |
160 * @return bool true if the parameter exists, false otherwise | |
161 */ | |
162 public function has($key) | |
163 { | |
164 return array_key_exists(str_replace('_', '-', strtolower($key)), $this->headers); | |
165 } | |
166 | |
167 /** | |
168 * Returns true if the given HTTP header contains the given value. | |
169 * | |
170 * @param string $key The HTTP header name | |
171 * @param string $value The HTTP value | |
172 * | |
173 * @return bool true if the value is contained in the header, false otherwise | |
174 */ | |
175 public function contains($key, $value) | |
176 { | |
177 return in_array($value, $this->get($key, null, false)); | |
178 } | |
179 | |
180 /** | |
181 * Removes a header. | |
182 * | |
183 * @param string $key The HTTP header name | |
184 */ | |
185 public function remove($key) | |
186 { | |
187 $key = str_replace('_', '-', strtolower($key)); | |
188 | |
189 unset($this->headers[$key]); | |
190 | |
191 if ('cache-control' === $key) { | |
192 $this->cacheControl = array(); | |
193 } | |
194 } | |
195 | |
196 /** | |
197 * Returns the HTTP header value converted to a date. | |
198 * | |
199 * @param string $key The parameter key | |
200 * @param \DateTime $default The default value | |
201 * | |
202 * @return null|\DateTime The parsed DateTime or the default value if the header does not exist | |
203 * | |
204 * @throws \RuntimeException When the HTTP header is not parseable | |
205 */ | |
206 public function getDate($key, \DateTime $default = null) | |
207 { | |
208 if (null === $value = $this->get($key)) { | |
209 return $default; | |
210 } | |
211 | |
212 if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) { | |
213 throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value)); | |
214 } | |
215 | |
216 return $date; | |
217 } | |
218 | |
219 /** | |
220 * Adds a custom Cache-Control directive. | |
221 * | |
222 * @param string $key The Cache-Control directive name | |
223 * @param mixed $value The Cache-Control directive value | |
224 */ | |
225 public function addCacheControlDirective($key, $value = true) | |
226 { | |
227 $this->cacheControl[$key] = $value; | |
228 | |
229 $this->set('Cache-Control', $this->getCacheControlHeader()); | |
230 } | |
231 | |
232 /** | |
233 * Returns true if the Cache-Control directive is defined. | |
234 * | |
235 * @param string $key The Cache-Control directive | |
236 * | |
237 * @return bool true if the directive exists, false otherwise | |
238 */ | |
239 public function hasCacheControlDirective($key) | |
240 { | |
241 return array_key_exists($key, $this->cacheControl); | |
242 } | |
243 | |
244 /** | |
245 * Returns a Cache-Control directive value by name. | |
246 * | |
247 * @param string $key The directive name | |
248 * | |
249 * @return mixed|null The directive value if defined, null otherwise | |
250 */ | |
251 public function getCacheControlDirective($key) | |
252 { | |
253 return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null; | |
254 } | |
255 | |
256 /** | |
257 * Removes a Cache-Control directive. | |
258 * | |
259 * @param string $key The Cache-Control directive | |
260 */ | |
261 public function removeCacheControlDirective($key) | |
262 { | |
263 unset($this->cacheControl[$key]); | |
264 | |
265 $this->set('Cache-Control', $this->getCacheControlHeader()); | |
266 } | |
267 | |
268 /** | |
269 * Returns an iterator for headers. | |
270 * | |
271 * @return \ArrayIterator An \ArrayIterator instance | |
272 */ | |
273 public function getIterator() | |
274 { | |
275 return new \ArrayIterator($this->headers); | |
276 } | |
277 | |
278 /** | |
279 * Returns the number of headers. | |
280 * | |
281 * @return int The number of headers | |
282 */ | |
283 public function count() | |
284 { | |
285 return count($this->headers); | |
286 } | |
287 | |
288 protected function getCacheControlHeader() | |
289 { | |
290 $parts = array(); | |
291 ksort($this->cacheControl); | |
292 foreach ($this->cacheControl as $key => $value) { | |
293 if (true === $value) { | |
294 $parts[] = $key; | |
295 } else { | |
296 if (preg_match('#[^a-zA-Z0-9._-]#', $value)) { | |
297 $value = '"'.$value.'"'; | |
298 } | |
299 | |
300 $parts[] = "$key=$value"; | |
301 } | |
302 } | |
303 | |
304 return implode(', ', $parts); | |
305 } | |
306 | |
307 /** | |
308 * Parses a Cache-Control HTTP header. | |
309 * | |
310 * @param string $header The value of the Cache-Control HTTP header | |
311 * | |
312 * @return array An array representing the attribute values | |
313 */ | |
314 protected function parseCacheControl($header) | |
315 { | |
316 $cacheControl = array(); | |
317 preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER); | |
318 foreach ($matches as $match) { | |
319 $cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true); | |
320 } | |
321 | |
322 return $cacheControl; | |
323 } | |
324 } |