1 <?php
2 3 4 5 6 7
8
9 namespace Hawk;
10
11 12 13 14 15
16 final class Response extends Singleton{
17 18 19 20 21
22 private $body,
23
24 25 26 27 28
29 $status = 200,
30
31 32 33 34 35
36 $headers = array(),
37
38 39 40 41 42
43 $cookies = array(),
44
45 46 47 48 49
50 $contentType = 'html';
51
52
53 54 55 56 57
58 protected static $instance;
59
60 61 62 63 64
65 private static $contentTypes = array(
66 'html' => 'text/html',
67 'json' => 'application/json',
68 'javascript' => 'application/javascript',
69 'css' => 'text/css',
70 'text' => 'text/plain',
71 'xml' => 'application/xml',
72 'stream' => 'application/octet-stream'
73 );
74
75 76 77
78 protected function __construct(){
79 $this->setContentType('html');
80 }
81
82
83 84 85 86 87
88 public function getBody(){
89 return $this->body;
90 }
91
92
93 94 95 96 97
98 public function setBody($body){
99 $this->body = $body;
100 }
101
102 103 104 105 106 107
108 public function header($name, $value){
109 $this->headers[$name] = $value;
110 }
111
112 113 114 115 116 117 118
119 public function setCookie($name, $data){
120 if(is_string($data)) {
121 $data = array(
122 'value' => $data,
123 );
124 }
125
126 if(empty($data['path'])) {
127 $data['path'] = '/';
128 }
129
130 $this->cookies[$name] = $data;
131 }
132
133 134 135 136 137
138 public function setContentType($type){
139 App::logger()->debug('change content type of response to ' . $type);
140
141 $this->contentType = $type;
142 if(isset(self::$contentTypes[$type])) {
143 $type = self::$contentTypes[$type];
144 }
145 $this->header('Content-type', $type);
146 }
147
148
149 150 151
152 public function setHtml(){
153 $this->setContentType('html');
154 }
155
156 157 158
159 public function setJson(){
160 $this->setContentType('json');
161 }
162
163 164 165
166 public function setScript(){
167 $this->setContentType('javascript');
168 }
169
170 171 172
173 public function getContentType(){
174 return $this->contentType;
175 }
176
177
178 179 180 181 182
183 public function setStatus($code){
184 $this->status = $code;
185 }
186
187 188 189 190 191
192 public function getStatus(){
193 return $this->status;
194 }
195
196
197
198 199 200 201 202
203 public function end($content = null){
204 http_response_code($this->status);
205
206
207 $lines = array();
208 foreach($this->cookies as $name => $data){
209 $line = $name . '=' . $data['value'];
210 if(!empty($data['expires'])) {
211 $line .= ';expires=' . gmdate('D, d M Y H:i:s \G\M\T', $data['expires']);
212 }
213 if(!empty($data['path'])) {
214 $line .= ';path=' . $data['path'];
215 }
216 if(!empty($data['domain'])) {
217 $line .= ';domain=' . $data['domain'];
218 }
219 if(!empty($data['secure'])) {
220 $line .= ';secure';
221 }
222 if(!empty($data['httponly'])) {
223 $line .= ';httponly';
224 }
225
226 $lines[] = $line;
227 }
228 if(!empty($lines)) {
229 $this->header('Set-Cookie', implode(PHP_EOL, $lines));
230 }
231
232
233
234 foreach($this->headers as $name => $value){
235 header($name .': ' . $value);
236 }
237
238
239
240 if($content !== null) {
241 $this->setBody($content);
242 }
243
244
245 switch($this->contentType){
246 case 'json' :
247 echo json_encode($this->body, JSON_HEX_APOS | JSON_HEX_QUOT | JSON_NUMERIC_CHECK);
248 break;
249 default :
250 echo $this->body;
251 break;
252 }
253
254 App::logger()->debug('script execution time : ' . ((microtime(true) - SCRIPT_START_TIME) * 1000) . ' ms');
255 exit();
256 }
257
258
259 260 261 262 263
264 public function redirect($url){
265 App::logger()->debug('redirect to ' . $url);
266 $this->header('Location', $url);
267 $this->end();
268 }
269
270 271 272 273 274 275
276 public function redirectToAction($route, $vars = array()){
277 $url = App::router()->getUri($route, $vars = array());
278 $this->redirect($url);
279 }
280 }
281