Passed
Push — master ( 9af4ec...b026ee )
by Mikael
02:25
created

Response   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 22.58%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 1
dl 0
loc 182
ccs 14
cts 62
cp 0.2258
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setStatusCode() 0 8 2
A checkIfHeadersAlreadySent() 0 6 2
A addHeader() 0 4 1
A sendHeaders() 0 21 3
A setBody() 0 13 3
A getBody() 0 4 1
A send() 0 11 3
A sendJson() 0 12 3
A redirect() 0 5 1
1
<?php
2
3
namespace Anax\Response;
4
5
/**
6
 * Handling a response.
7
 *
8
 */
9
class Response
10
{
11
    /**
12
    * Properties
13
    *
14
    */
15
    private $headers = [];  // Set all headers to send
16
    private $statusCode;    // Set statuscode to use
17
    private $body;          // Body to send with response
18
19
20
21
    /**
22
     * Set headers.
23
     *
24
     * @param string $header type of header to set
0 ignored issues
show
Bug introduced by
There is no parameter named $header. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
25
     *
26
     * @return $this
27
     */
28 1
    public function setStatusCode($value)
29
    {
30 1
        $supportedValues = [200, 403, 404, 500];
31 1
        if (!in_array($value, $supportedValues)) {
32 1
            throw new Exception("Unsupported statuscode: $value");
33
        }
34
        $this->statusCode = $value;
35
    }
36
37
38
39
    /**
40
     * Set headers.
41
     *
42
     * @param string $header type of header to set
43
     *
44
     * @return $this
45
     */
46
    public function addHeader($header)
47
    {
48
        $this->headers[] = $header;
49
    }
50
51
52
53
    /**
54
     * Check if headers are already sent and throw exception if it is.
55
     *
56
     * @return void
57
     *
58
     * @throws Exception
59
     */
60 1
    public function checkIfHeadersAlreadySent()
61
    {
62 1
        if (headers_sent($file, $line)) {
63 1
            throw new Exception("Try to send headers but headers already sent, output started at $file line $line.");
64
        }
65
    }
66
67
68
69
    /**
70
     * Send headers.
71
     *
72
     * @return $this
73
     */
74
    public function sendHeaders()
75
    {
76
        $statusHeader = [
77
            "200" => "HTTP/1.1 200 OK",
78
            "403" => "HTTP/1.1 403 Forbidden",
79
            "404" => "HTTP/1.1 404 Not Found",
80
            "500" => "HTTP/1.1 500 Internal Server Error"
81
        ];
82
83
        $this->checkIfHeadersAlreadySent();
84
85
        if (isset($statusHeader[$this->statusCode])) {
86
            header($statusHeader[$this->statusCode]);
87
        }
88
89
        foreach ($this->headers as $header) {
90
            header($header);
91
        }
92
93
        return $this;
94
    }
95
96
97
98
    /**
99
     * Set the body.
100
     *
101
     * @param callable|string $body either a string or a callable that
102
     *                              can generate the body.
103
     *
104
     * @return this
105
     */
106 1
    public function setBody($body)
107
    {
108 1
        if (is_string($body)) {
109 1
            $this->body = $body;
110 1
        } elseif (is_callable($body)) {
111
            ob_start();
112
            $res1 = call_user_func($body);
113
            $res2 = ob_get_contents();
114
            $this->body = $res2 . $res1;
115
            ob_end_clean();
116
        }
117 1
        return $this;
118
    }
119
120
121
122
    /**
123
     * Get the body.
124
     *
125
     * @return void
126
     */
127 1
    public function getBody()
128
    {
129 1
        return $this->body;
130
    }
131
132
133
134
    /**
135
     * Send response with an optional statuscode.
136
     *
137
     * @param integer $statusCode optional statuscode to send.
138
     *
139
     * @return void
140
     */
141
    public function send($statusCode = null)
142
    {
143
        if ($statusCode) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $statusCode of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
144
            $this->setStatusCode($statusCode);
145
        }
146
147
        if (!headers_sent()) {
148
            $this->sendHeaders();
149
        }
150
        echo $this->getBody();
151
    }
152
153
154
155
    /**
156
     * Send JSON response with an optional statuscode.
157
     *
158
     * @param mixed   $data       to be encoded as json.
159
     * @param integer $statusCode optional statuscode to send.
160
     *
161
     * @return void
162
     */
163
    public function sendJson($data, $statusCode = null)
164
    {
165
        if ($statusCode) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $statusCode of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
166
            $this->setStatusCode($statusCode);
167
        }
168
169
        if (!headers_sent()) {
170
            $this->addHeader("Content-Type: application/json; charset=utf8");
171
            $this->sendHeaders();
172
        }
173
        echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
174
    }
175
176
177
178
    /**
179
     * Redirect to another page.
180
     *
181
     * @param string $url to redirect to
182
     *
183
     * @return void
184
     */
185
    public function redirect($url)
186
    {
187
        $this->checkIfHeadersAlreadySent();
188
        header("Location: " . $url);
189
    }
190
}
191