Completed
Push — master ( ac2bb1...65711b )
by Mikael
03:04
created

Response::send()   B

Complexity

Conditions 9
Paths 17

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 9.0239

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 14
cts 15
cp 0.9333
rs 8.0555
c 0
b 0
f 0
cc 9
nc 17
nop 1
crap 9.0239
1
<?php
2
3
namespace Anax\Response;
4
5
/**
6
 * Handling a response.
7
 */
8
class Response
9
{
10
    /**
11
    * @var array $headers    set all headers to send.
12
    * @var array $statusCode set statuscode to use.
13
    * @var array $body       body to send with response.
14
    */
15
    private $headers = [];
16
    private $statusCode = null;
17
    private $body;
18
19
20
21
    /**
22
     * Set status code to be sent as part of headers.
23
     *
24
     * @param int $value of response status code
25
     *
26
     * @return self
27
     */
28 14
    public function setStatusCode(int $value = null)
29
    {
30 14
        if (is_null($value)) {
31 6
            return $this;
32
        }
33
34 8
        $this->statusCode = $value;
35 8
        return $this;
36
    }
37
38
39
40
    /**
41
     * Get status code to be sent as part of headers.
42
     *
43
     * @return integer value as status code or null if not set.
44
     */
45 7
    public function getStatusCode()
46
    {
47 7
        return $this->statusCode;
48
    }
49
50
51
52
    /**
53
     * Set headers.
54
     *
55
     * @param string $header type of header to set
56
     *
57
     * @return self
58
     */
59 4
    public function addHeader($header)
60
    {
61 4
        $this->headers[] = $header;
62 4
        return $this;
63
    }
64
65
66
67
    /**
68
     * Send headers.
69
     *
70
     * @return self
71
     */
72 1
    public function sendHeaders()
73
    {
74 1
        if (php_sapi_name() !== "cli" && headers_sent($file, $line)) {
75
            throw new Exception("Try to send headers but headers already sent, output started at $file line $line.");
76
        }
77
78 1
        http_response_code($this->statusCode);
79
80 1
        foreach ($this->headers as $header) {
81 1
            if (php_sapi_name() !== "cli") {
82 1
                header($header);
83
            }
84
        }
85
86 1
        return $this;
87
    }
88
89
90
91
    /**
92
     * Set the body.
93
     *
94
     * @param callable|string $body either a string or a callable that
95
     *                              can generate the body.
96
     *
97
     * @return self
98
     */
99 8
    public function setBody($body)
100
    {
101 8
        if (is_string($body)) {
102 7
            $this->body = $body;
103 3
        } elseif (is_array($body)) {
104 2
            $this->setJsonBody($body);
105 1
        } elseif (is_callable($body)) {
106 1
            ob_start();
107 1
            $res1 = call_user_func($body);
108 1
            $res2 = ob_get_contents();
109 1
            $this->body = $res2 . $res1;
110 1
            ob_end_clean();
111
        }
112 8
        return $this;
113
    }
114
115
116
117
    /**
118
     * Get the body.
119
     *
120
     * @return string
121
     */
122 9
    public function getBody()
123
    {
124 9
        return $this->body;
125
    }
126
127
128
129
    /**
130
     * Send response supporting varios ways of response $data.
131
     *
132
     * @param mixed $data to use as optional base for creating response.
133
     *
134
     * @return self
135
     */
136 6
    public function send($data = null)
137
    {
138 6
        $statusCode = null;
139
140 6
        if ($data instanceof self) {
141 1
            return $data->send();
142
        }
143
144 6
        if (is_string($data)) {
145 1
            $this->setBody($data);
146
        }
147
148 6
        if (is_array($data) && isset($data[0])) {
149 2
            $this->setBody($data[0]);
150
        }
151
152 6
        if (is_array($data) && isset($data[1]) && is_numeric($data[1])) {
153 1
            $statusCode = $data[1];
154
        }
155
156 6
        $this->setStatusCode($statusCode);
157
158 6
        if (!headers_sent()) {
159
            $this->sendHeaders();
160
        }
161
162 6
        echo $this->getBody();
163 6
        return $this;
164
    }
165
166
167
168
    /**
169
     * Send JSON response with an optional statuscode.
170
     *
171
     * @param mixed   $data       to be encoded as json.
172
     * @param integer $statusCode optional statuscode to send.
173
     *
174
     * @return self
175
     */
176 1
    public function sendJson($data, $statusCode = null)
177
    {
178 1
        return $this->setStatusCode($statusCode)
179 1
                    ->setJsonBody($data)
180 1
                    ->send();
181
    }
182
183
184
185
    /**
186
     * Set body with JSON data.
187
     *
188
     * @param mixed $data to be encoded as json.
189
     *
190
     * @return self
191
     */
192 3
    public function setJsonBody($data)
193
    {
194 3
        $this->addHeader("Content-Type: application/json; charset=utf8");
195 3
        $this->setBody(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
196 3
        return $this;
197
    }
198
199
200
201
    /**
202
     * Redirect to another page.
203
     *
204
     * @param string $url to redirect to
205
     *
206
     * @return void
207
     *
208
     * @SuppressWarnings(PHPMD.ExitExpression)
209
     */
210 2
    public function redirect($url)
211
    {
212 2
        if (!headers_sent()) {
213
            header("Location: " . $url);
214
            exit;
215
        }
216 2
    }
217
}
218