Completed
Push — master ( d9f7fe...0d6725 )
by Igor
02:53
created

Response   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 0
dl 0
loc 194
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B send() 0 18 10
A setContent() 0 4 1
A header() 0 8 4
A setContentTypeJson() 0 4 1
A setContentTypeXml() 0 4 1
B setStatusCode() 0 76 3
A redirect() 0 27 4
1
<?php
2
/**
3
 * @license MIT
4
 */
5
namespace Pivasic\Core;
6
7
/**
8
 * Represents a HTTP response.
9
 *
10
 * Class Response
11
 * @package Pivasic\Core
12
 */
13
class Response
14
{
15
    public function __construct()
16
    {
17
        $this->content = '';
18
    }
19
20
    /**
21
     * Send response.
22
     */
23
    public function send()
24
    {
25
        echo $this->content;
26
27
        if (function_exists('fastcgi_finish_request')) {
28
            fastcgi_finish_request();
29
        } elseif ('cli' !== php_sapi_name()) {
30
            $level = ob_get_level();
31
            if (0 < $level) {
32
                $status = ob_get_status(true);
33
                // PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3
34
                $flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | PHP_OUTPUT_HANDLER_FLUSHABLE : -1;
35
                while ($level-- > 0 && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) {
36
                    ob_end_flush();
37
                }
38
            }
39
        }
40
    }
41
42
    /**
43
     * Set response body.
44
     *
45
     * @param string $content
46
     */
47
    public function setContent($content)
48
    {
49
        $this->content = $content;
50
    }
51
52
    /**
53
     * Set response header.
54
     *
55
     * @param string $name
56
     * @param string $value
57
     *
58
     * @return bool
59
     */
60
    public function header($name, $value)
61
    {
62
        if (!empty($name) && !empty($value) && !headers_sent()) {
63
            header($name . ': ' . $value);
64
            return true;
65
        }
66
        return false;
67
    }
68
69
    /**
70
     * @return bool
71
     */
72
    public function setContentTypeJson()
73
    {
74
        return $this->header('Content-Type', 'application/json; charset=utf-8');
75
    }
76
77
    /**
78
     * @return bool
79
     */
80
    public function setContentTypeXml()
81
    {
82
        return $this->header('Content-Type', 'text/xml; charset=utf-8');
83
    }
84
85
    /**
86
     * Set response status.
87
     *
88
     * @param integer $statusCode       - status
89
     * @param string $version           - HTTP version
90
     * @param string|null $statusText   - status text
91
     *
92
     * @return bool
93
     */
94
    public function setStatusCode($statusCode, $version = '1.1', $statusText = null)
95
    {
96
        if (!headers_sent()) {
97
            $statusCode = intval($statusCode);
98
99
            if (null === $statusText) {
100
                $statusTexts = [
101
                    100 => 'Continue',
102
                    101 => 'Switching Protocols',
103
                    102 => 'Processing',            // RFC2518
104
                    200 => 'OK',
105
                    201 => 'Created',
106
                    202 => 'Accepted',
107
                    203 => 'Non-Authoritative Information',
108
                    204 => 'No Content',
109
                    205 => 'Reset Content',
110
                    206 => 'Partial Content',
111
                    207 => 'Multi-Status',          // RFC4918
112
                    208 => 'Already Reported',      // RFC5842
113
                    226 => 'IM Used',               // RFC3229
114
                    300 => 'Multiple Choices',
115
                    301 => 'Moved Permanently',
116
                    302 => 'Found',
117
                    303 => 'See Other',
118
                    304 => 'Not Modified',
119
                    305 => 'Use Proxy',
120
                    307 => 'Temporary Redirect',
121
                    308 => 'Permanent Redirect',    // RFC7238
122
                    400 => 'Bad Request',
123
                    401 => 'Unauthorized',
124
                    402 => 'Payment Required',
125
                    403 => 'Forbidden',
126
                    404 => 'Not Found',
127
                    405 => 'Method Not Allowed',
128
                    406 => 'Not Acceptable',
129
                    407 => 'Proxy Authentication Required',
130
                    408 => 'Request Timeout',
131
                    409 => 'Conflict',
132
                    410 => 'Gone',
133
                    411 => 'Length Required',
134
                    412 => 'Precondition Failed',
135
                    413 => 'Payload Too Large',
136
                    414 => 'URI Too Long',
137
                    415 => 'Unsupported Media Type',
138
                    416 => 'Range Not Satisfiable',
139
                    417 => 'Expectation Failed',
140
                    418 => 'I\'m a teapot',                                               // RFC2324
141
                    422 => 'Unprocessable Entity',                                        // RFC4918
142
                    423 => 'Locked',                                                      // RFC4918
143
                    424 => 'Failed Dependency',                                           // RFC4918
144
                    425 => 'Reserved for WebDAV advanced collections expired proposal',   // RFC2817
145
                    426 => 'Upgrade Required',                                            // RFC2817
146
                    428 => 'Precondition Required',                                       // RFC6585
147
                    429 => 'Too Many Requests',                                           // RFC6585
148
                    431 => 'Request Header Fields Too Large',                             // RFC6585
149
                    500 => 'Internal Server Error',
150
                    501 => 'Not Implemented',
151
                    502 => 'Bad Gateway',
152
                    503 => 'Service Unavailable',
153
                    504 => 'Gateway Timeout',
154
                    505 => 'HTTP Version Not Supported',
155
                    506 => 'Variant Also Negotiates (Experimental)',                      // RFC2295
156
                    507 => 'Insufficient Storage',                                        // RFC4918
157
                    508 => 'Loop Detected',                                               // RFC5842
158
                    510 => 'Not Extended',                                                // RFC2774
159
                    511 => 'Network Authentication Required',                             // RFC6585
160
                ];
161
                $statusText = $statusTexts[$statusCode];
162
            }
163
164
            header(sprintf('HTTP/%s %s %s', $version, $statusCode, $statusText), true, $statusCode);
165
            return true;
166
        }
167
168
        return false;
169
    }
170
171
    /**
172
     * Redirect to url with statusCode and terminate.
173
     *
174
     * @param null|string $url
175
     * @param int $statusCode
176
     */
177
    public function redirect($url = null, $statusCode = 302)
178
    {
179
        $server = filter_input_array(INPUT_SERVER);
180
        if (null === $url && isset($server['REQUEST_URI'])) {
181
            $url = '/' . trim($server['REQUEST_URI'], '/');
182
            preg_match('/^[\\a-zA-Z0-9-\._~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=%]*$/iD', $url, $match);
183
            $url = $match[1] ?? '';
184
        }
185
186
        if (!headers_sent()) {
187
            header('Location: ' . $url, true, $statusCode);
188
        }
189
190
        echo sprintf('<!DOCTYPE html>
191
<html>
192
    <head>
193
        <meta charset="UTF-8" />
194
        <meta http-equiv="refresh" content="0;url=%1$s" />
195
        <title>Redirecting to %1$s</title>
196
    </head>
197
    <body>
198
        <script type="text/javascript"> window.location.href = "%1$s"; </script>
199
        Redirecting to <a href="%1$s">%1$s</a>.
200
    </body>
201
</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8'));
202
203
    }
204
205
    private $content;
206
}