Completed
Push — master ( 009e6e...8f3b04 )
by Mikael
03:35
created

Response::addHeader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
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
    public function setStatusCode(int $value = null)
29
    {
30
        if (is_null($value)) {
31
            return $this;
32
        }
33
34
        $this->statusCode = $value;
35
        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
    public function getStatusCode()
46
    {
47
        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
    public function addHeader($header)
60
    {
61
        $this->headers[] = $header;
62
        return $this;
63
    }
64
65
66
67
    /**
68
     * Send headers.
69
     *
70
     * @return self
71
     */
72
    public function sendHeaders()
73
    {
74
        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
        http_response_code($this->statusCode);
79
80
        foreach ($this->headers as $header) {
81
            if (php_sapi_name() !== "cli") {
82
                header($header);
83
            }
84
        }
85
86
        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
    public function setBody($body)
100
    {
101
        if (is_string($body)) {
102
            $this->body = $body;
103
        } elseif (is_array($body)) {
104
            $this->setJsonBody($body);
105
        } elseif (is_callable($body)) {
106
            ob_start();
107
            $res1 = call_user_func($body);
108
            $res2 = ob_get_contents();
109
            $this->body = $res2 . $res1;
110
            ob_end_clean();
111
        }
112
        return $this;
113
    }
114
115
116
117
    /**
118
     * Get the body.
119
     *
120
     * @return string
121
     */
122
    public function getBody()
123
    {
124
        return $this->body;
125
    }
126
127
128
129
    /**
130
     * Send response supporting several ways of receiving response $data.
131
     *
132
     * @param mixed $data to use as optional base for creating response.
133
     *
134
     * @return self
135
     */
136
    public function send($data = null)
137
    {
138
        $statusCode = null;
139
140
        if ($data instanceof self) {
141
            return $data->send();
142
        }
143
144
        if (is_string($data)) {
145
            $this->setBody($data);
146
        }
147
148
        if (is_array($data) && isset($data[0])) {
149
            $this->setBody($data[0]);
150
        }
151
152
        if (is_array($data) && isset($data[1]) && is_numeric($data[1])) {
153
            $statusCode = $data[1];
154
        }
155
156
        $this->setStatusCode($statusCode);
157
158
        if (!headers_sent()) {
159
            $this->sendHeaders();
160
        }
161
162
        echo $this->getBody();
163
        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
    public function sendJson($data, $statusCode = null)
177
    {
178
        return $this->setStatusCode($statusCode)
179
                    ->setJsonBody($data)
180
                    ->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
    public function setJsonBody($data)
193
    {
194
        $this->addHeader("Content-Type: application/json; charset=utf8");
195
        $this->setBody(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
196
        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
    public function redirect($url)
211
    {
212
        if (!headers_sent()) {
213
            header("Location: " . $url);
214
            exit;
215
        }
216
    }
217
}
218