1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* The MIT License (MIT) |
4
|
|
|
* |
5
|
|
|
* Copyright (c) 2015 zepi |
6
|
|
|
* |
7
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
8
|
|
|
* of this software and associated documentation files (the "Software"), to deal |
9
|
|
|
* in the Software without restriction, including without limitation the rights |
10
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11
|
|
|
* copies of the Software, and to permit persons to whom the Software is |
12
|
|
|
* furnished to do so, subject to the following conditions: |
13
|
|
|
* |
14
|
|
|
* The above copyright notice and this permission notice shall be included in |
15
|
|
|
* all copies or substantial portions of the Software. |
16
|
|
|
* |
17
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
23
|
|
|
* THE SOFTWARE. |
24
|
|
|
* |
25
|
|
|
*/ |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* The Response holds all information which are outputtet at the end |
29
|
|
|
* of the request. |
30
|
|
|
* |
31
|
|
|
* @package Zepi\Turbo\Response |
32
|
|
|
* @author Matthias Zobrist <[email protected]> |
33
|
|
|
* @copyright Copyright (c) 2015 zepi |
34
|
|
|
*/ |
35
|
|
|
|
36
|
|
|
namespace Zepi\Turbo\Response; |
37
|
|
|
|
38
|
|
|
use Zepi\Turbo\Request\RequestAbstract; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* The Response holds all information which are outputtet at the end |
42
|
|
|
* of the request. |
43
|
|
|
* |
44
|
|
|
* @author Matthias Zobrist <[email protected]> |
45
|
|
|
* @copyright Copyright (c) 2015 zepi |
46
|
|
|
*/ |
47
|
|
|
class Response |
48
|
|
|
{ |
49
|
|
|
/** |
50
|
|
|
* @access protected |
51
|
|
|
* @var RequestAbstract |
52
|
|
|
*/ |
53
|
|
|
protected $_request; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @access protected |
57
|
|
|
* @var array |
58
|
|
|
*/ |
59
|
|
|
protected $_data = array(); |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @access protected |
63
|
|
|
* @var array |
64
|
|
|
*/ |
65
|
|
|
protected $_outputParts = array(); |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @access protected |
69
|
|
|
* @var string |
70
|
|
|
*/ |
71
|
|
|
protected $_output; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Constructs the object |
75
|
|
|
* |
76
|
|
|
* @access public |
77
|
|
|
* @param \Zepi\Turbo\Request\RequestAbstract $request |
78
|
|
|
*/ |
79
|
|
|
public function __construct(RequestAbstract $request) |
80
|
|
|
{ |
81
|
|
|
$this->_request = $request; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Return the data for the given key. If the key does |
86
|
|
|
* not exists the function will return false. |
87
|
|
|
* |
88
|
|
|
* @access public |
89
|
|
|
* @param string $key |
90
|
|
|
* @return mixed |
91
|
|
|
*/ |
92
|
|
|
public function getData($key) |
93
|
|
|
{ |
94
|
|
|
if (!$this->hasData($key)) { |
95
|
|
|
return false; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
return $this->_data[$key]; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Returns true if the given key is set. |
103
|
|
|
* |
104
|
|
|
* @access public |
105
|
|
|
* @param string $key |
106
|
|
|
* @return boolean |
107
|
|
|
*/ |
108
|
|
|
public function hasData($key) |
109
|
|
|
{ |
110
|
|
|
return (isset($this->_data[$key])); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Saves the value for the given key in the response object. |
115
|
|
|
* |
116
|
|
|
* @access public |
117
|
|
|
* @param string $key |
118
|
|
|
* @param mixed $value |
119
|
|
|
*/ |
120
|
|
|
public function setData($key, $value) |
121
|
|
|
{ |
122
|
|
|
$this->_data[$key] = $value; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Returns the output for the given key. If the key does |
127
|
|
|
* not exists the function will return false. |
128
|
|
|
* |
129
|
|
|
* @access public |
130
|
|
|
* @param string $key |
131
|
|
|
* @return false|string |
132
|
|
|
*/ |
133
|
|
|
public function getOutputPart($key) |
134
|
|
|
{ |
135
|
|
|
if (!$this->hasOutputPart($key)) { |
136
|
|
|
return false; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
return $this->_outputParts[$key]; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Returns true if the given key exists as output key. |
144
|
|
|
* |
145
|
|
|
* @access public |
146
|
|
|
* @param string $key |
147
|
|
|
* @return boolean |
148
|
|
|
*/ |
149
|
|
|
public function hasOutputPart($key) |
150
|
|
|
{ |
151
|
|
|
return (isset($this->_outputParts[$key])); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Saves the output for the given key in the Response object. |
156
|
|
|
* |
157
|
|
|
* @access public |
158
|
|
|
* @param string $key |
159
|
|
|
* @param string $output |
160
|
|
|
*/ |
161
|
|
|
public function setOutputPart($key, $output) |
162
|
|
|
{ |
163
|
|
|
$this->_outputParts[$key] = $output; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Returns all output parts of the Response object. |
168
|
|
|
* |
169
|
|
|
* @access public |
170
|
|
|
* @return array |
171
|
|
|
*/ |
172
|
|
|
public function getOutputParts() |
173
|
|
|
{ |
174
|
|
|
return $this->_outputParts; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Returns the output of the response. |
179
|
|
|
* |
180
|
|
|
* @access public |
181
|
|
|
* @return string |
182
|
|
|
*/ |
183
|
|
|
public function getOutput() |
184
|
|
|
{ |
185
|
|
|
return $this->_output; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Returns true if the response has an output. |
190
|
|
|
* |
191
|
|
|
* @access public |
192
|
|
|
* @return boolean |
193
|
|
|
*/ |
194
|
|
|
public function hasOutput() |
195
|
|
|
{ |
196
|
|
|
return ($this->_output != ''); |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* Sets the output of the response. |
201
|
|
|
* |
202
|
|
|
* @access public |
203
|
|
|
* @param string $output |
204
|
|
|
*/ |
205
|
|
|
public function setOutput($output) |
206
|
|
|
{ |
207
|
|
|
$this->_output = $output; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Set the Location header to redirect a request |
212
|
|
|
* |
213
|
|
|
* @access public |
214
|
|
|
* @param string $target |
215
|
|
|
* @param integer $headerCode |
216
|
|
|
* @param boolean $withOrigin |
217
|
|
|
*/ |
218
|
|
|
public function redirectTo($target, $headerCode = 301, $withOrigin = false) |
219
|
|
|
{ |
220
|
|
|
if (strpos($target, 'http://') === false) { |
221
|
|
|
$target = $this->_request->getFullRoute($target); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
if ($withOrigin) { |
225
|
|
|
$origin = $this->_request->getFullRoute(); |
226
|
|
|
$additionalQuery = '_origin=' . base64_encode($origin); |
227
|
|
|
|
228
|
|
|
$parts = parse_url($target); |
229
|
|
|
|
230
|
|
|
if (!isset($parts['query'])) { |
231
|
|
|
$parts['query'] = ''; |
232
|
|
|
} else if ($parts['query'] !== '') { |
233
|
|
|
$parts['query'] .= '&'; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
$parts['query'] .= $additionalQuery; |
237
|
|
|
$target = $this->buildUrl($parts); |
|
|
|
|
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
header("Location: " . $target, true, $headerCode); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* Sends a header |
245
|
|
|
* |
246
|
|
|
* @access public |
247
|
|
|
* @param string $message |
248
|
|
|
* @param integer $code |
249
|
|
|
*/ |
250
|
|
|
public function sendHeader($message, $code = null) |
251
|
|
|
{ |
252
|
|
|
if ($code !== null) { |
253
|
|
|
header($message, true, $code); |
254
|
|
|
} else { |
255
|
|
|
header($message); |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Sends the status code for the give code |
261
|
|
|
* |
262
|
|
|
* @access public |
263
|
|
|
* @param integer $code |
264
|
|
|
* @param boolean $resetOutput |
265
|
|
|
*/ |
266
|
|
|
public function sendHttpStatus($code, $resetOutput = false) |
267
|
|
|
{ |
268
|
|
|
$codes = array( |
269
|
|
|
100 => 'Continue', |
270
|
|
|
101 => 'Switching Protocols', |
271
|
|
|
102 => 'Processing', |
272
|
|
|
200 => 'OK', |
273
|
|
|
201 => 'Created', |
274
|
|
|
202 => 'Accepted', |
275
|
|
|
203 => 'Non-Authoritative Information', |
276
|
|
|
204 => 'No Content', |
277
|
|
|
205 => 'Reset Content', |
278
|
|
|
206 => 'Partial Content', |
279
|
|
|
207 => 'Multi-Status', |
280
|
|
|
300 => 'Multiple Choices', |
281
|
|
|
301 => 'Moved Permanently', |
282
|
|
|
302 => 'Found', |
283
|
|
|
303 => 'See Other', |
284
|
|
|
304 => 'Not Modified', |
285
|
|
|
305 => 'Use Proxy', |
286
|
|
|
306 => 'Switch Proxy', |
287
|
|
|
307 => 'Temporary Redirect', |
288
|
|
|
400 => 'Bad Request', |
289
|
|
|
401 => 'Unauthorized', |
290
|
|
|
402 => 'Payment Required', |
291
|
|
|
403 => 'Forbidden', |
292
|
|
|
404 => 'Not Found', |
293
|
|
|
405 => 'Method Not Allowed', |
294
|
|
|
406 => 'Not Acceptable', |
295
|
|
|
407 => 'Proxy Authentication Required', |
296
|
|
|
408 => 'Request Timeout', |
297
|
|
|
409 => 'Conflict', |
298
|
|
|
410 => 'Gone', |
299
|
|
|
411 => 'Length Required', |
300
|
|
|
412 => 'Precondition Failed', |
301
|
|
|
413 => 'Request Entity Too Large', |
302
|
|
|
414 => 'Request-URI Too Long', |
303
|
|
|
415 => 'Unsupported Media Type', |
304
|
|
|
416 => 'Requested Range Not Satisfiable', |
305
|
|
|
417 => 'Expectation Failed', |
306
|
|
|
418 => 'I\'m a teapot', |
307
|
|
|
422 => 'Unprocessable Entity', |
308
|
|
|
423 => 'Locked', |
309
|
|
|
424 => 'Failed Dependency', |
310
|
|
|
425 => 'Unordered Collection', |
311
|
|
|
426 => 'Upgrade Required', |
312
|
|
|
449 => 'Retry With', |
313
|
|
|
450 => 'Blocked by Windows Parental Controls', |
314
|
|
|
500 => 'Internal Server Error', |
315
|
|
|
501 => 'Not Implemented', |
316
|
|
|
502 => 'Bad Gateway', |
317
|
|
|
503 => 'Service Unavailable', |
318
|
|
|
504 => 'Gateway Timeout', |
319
|
|
|
505 => 'HTTP Version Not Supported', |
320
|
|
|
506 => 'Variant Also Negotiates', |
321
|
|
|
507 => 'Insufficient Storage', |
322
|
|
|
509 => 'Bandwidth Limit Exceeded', |
323
|
|
|
510 => 'Not Extended' |
324
|
|
|
); |
325
|
|
|
|
326
|
|
|
if (!isset($codes[$code])) { |
327
|
|
|
return false; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
$message = $this->_request->getProtocol() . ' ' . $code . ' ' . $codes[$code]; |
|
|
|
|
331
|
|
|
header($message, true, $code); |
332
|
|
|
|
333
|
|
|
if ($resetOutput) { |
334
|
|
|
$this->setOutput($message); |
335
|
|
|
} |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* Returns a full url for the given url parts array |
340
|
|
|
* from the function `parse_url()`. |
341
|
|
|
* |
342
|
|
|
* @access public |
343
|
|
|
* @param array $urlParts |
344
|
|
|
* @return string |
345
|
|
|
*/ |
346
|
|
|
public function buildUrl($urlParts) |
347
|
|
|
{ |
348
|
|
|
$url = ''; |
349
|
|
|
$auth = false; |
350
|
|
|
|
351
|
|
|
if (isset($urlParts['scheme'])) { |
352
|
|
|
$url .= $urlParts['scheme'] . '://'; |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
if (isset($urlParts['user'])) { |
356
|
|
|
$url .= $urlParts['user']; |
357
|
|
|
$auth = true; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
if (isset($urlParts['pass'])) { |
361
|
|
|
$url .= ':' . $urlParts['pass']; |
362
|
|
|
$auth = true; |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
if ($auth) { |
366
|
|
|
$url .= '@'; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
if (isset($urlParts['host'])) { |
370
|
|
|
$url .= $urlParts['host']; |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
if (isset($urlParts['port'])) { |
374
|
|
|
$url .= ':' . $urlParts['port']; |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
if (isset($urlParts['path'])) { |
378
|
|
|
$url .= $urlParts['path']; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
if (isset($urlParts['query'])) { |
382
|
|
|
$url .= '?' . $urlParts['query']; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
if (isset($urlParts['fragment'])) { |
386
|
|
|
$url .= '#' . $urlParts['fragment']; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
return $url; |
390
|
|
|
} |
391
|
|
|
} |
392
|
|
|
|
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.