Passed
Push — master ( 157485...b7615a )
by Nikolaos
09:23
created

Response::getPhrases()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 91
Code Lines 89

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 89
dl 0
loc 91
ccs 0
cts 24
cp 0
rs 8.24
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file is part of the Phalcon Framework.
5
 *
6
 * (c) Phalcon Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 *
11
 * Implementation of this file has been influenced by Zend Diactoros
12
 * @link    https://github.com/zendframework/zend-diactoros
13
 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md
14
 */
15
16
declare(strict_types=1);
17
18
namespace Phalcon\Http\Message;
19
20
use Phalcon\Helper\Number;
21
use Phalcon\Http\Message\Exception\InvalidArgumentException;
22
use Psr\Http\Message\ResponseInterface;
23
24
use function is_int;
25
use function is_string;
26
27
/**
28
 * PSR-7 Response
29
 *
30
 * @property string $reasonPhrase
31
 * @property int    $statusCode
32
 */
33
final class Response extends AbstractMessage implements ResponseInterface
34
{
35
    /**
36
     * Gets the response reason phrase associated with the status code.
37
     *
38
     * Because a reason phrase is not a required element in a response
39
     * status line, the reason phrase value MAY be empty. Implementations MAY
40
     * choose to return the default RFC 7231 recommended reason phrase (or
41
     * those
42
     * listed in the IANA HTTP Status Code Registry) for the response's
43
     * status code.
44
     *
45
     * @see http://tools.ietf.org/html/rfc7231#section-6
46
     * @see http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
47
     *
48
     * @var string
49
     */
50
    protected $reasonPhrase = "";
51
52
    /**
53
     * Gets the response status code.
54
     *
55
     * The status code is a 3-digit integer result code of the server's attempt
56
     * to understand and satisfy the request.
57
     *
58
     * @var int
59
     */
60
    protected $statusCode = 200;
61
62
    /**
63
     * Response constructor.
64
     *
65
     * @param string $body
66
     * @param int    $code
67
     * @param array  $headers
68
     */
69
    public function __construct(
70
        $body = "php://memory",
71
        int $code = 200,
72
        array $headers = []
73
    ) {
74
        $this->processCode($code);
75
76
        $this->headers = $this->processHeaders($headers);
77
        $this->body    = $this->processBody($body, "w+b");
78
    }
79
80
    /**
81
     * @return string
82
     */
83
    public function getReasonPhrase(): string
84
    {
85
        return $this->reasonPhrase;
86
    }
87
88
    /**
89
     * @return int
90
     */
91
    public function getStatusCode()
92
    {
93
        return $this->statusCode;
94
    }
95
96
    /**
97
     * Return an instance with the specified status code and, optionally,
98
     * reason phrase.
99
     *
100
     * If no reason phrase is specified, implementations MAY choose to default
101
     * to the RFC 7231 or IANA recommended reason phrase for the response's
102
     * status code.
103
     *
104
     * This method MUST be implemented in such a way as to retain the
105
     * immutability of the message, and MUST return an instance that has the
106
     * updated status and reason phrase.
107
     *
108
     * @see http://tools.ietf.org/html/rfc7231#section-6
109
     * @see http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
110
     *
111
     * @param int    $code
112
     * @param string $reasonPhrase
113
     *
114
     * @return Response
115
     */
116
    public function withStatus($code, $reasonPhrase = ""): Response
117
    {
118
        $newInstance = clone $this;
119
120
        $newInstance->processCode($code, $reasonPhrase);
121
122
        return $newInstance;
123
    }
124
125
    /**
126
     * Checks if a code is integer or string
127
     *
128
     * @param mixed $code
129
     */
130
    private function checkCodeType($code): void
131
    {
132
        if (!is_int($code) && !is_string($code)) {
133
            throw new InvalidArgumentException(
134
                "Invalid status code; it must be an integer or string"
135
            );
136
        }
137
    }
138
139
    /**
140
     * Checks if a code is integer or string
141
     *
142
     * @param int $code
143
     */
144
    private function checkCodeValue(int $code): void
145
    {
146
        if (true !== Number::between($code, 100, 599)) {
147
            throw new InvalidArgumentException(
148
                "Invalid status code '" . $code . "', (allowed values 100-599)"
149
            );
150
        }
151
    }
152
153
    /**
154
     * Returns the list of status codes available
155
     */
156
    private function getPhrases(): array
157
    {
158
        return [
159
            100 => "Continue",                                         // Information - RFC 7231, 6.2.1
160
            101 => "Switching Protocols",                              // Information - RFC 7231, 6.2.2
161
            102 => "Processing",                                       // Information - RFC 2518, 10.1
162
            103 => "Early Hints",
163
            200 => "OK",                                               // Success - RFC 7231, 6.3.1
164
            201 => "Created",                                          // Success - RFC 7231, 6.3.2
165
            202 => "Accepted",                                         // Success - RFC 7231, 6.3.3
166
            203 => "Non-Authoritative Information",                    // Success - RFC 7231, 6.3.4
167
            204 => "No Content",                                       // Success - RFC 7231, 6.3.5
168
            205 => "Reset Content",                                    // Success - RFC 7231, 6.3.6
169
            206 => "Partial Content",                                  // Success - RFC 7233, 4.1
170
            207 => "Multi-status",                                     // Success - RFC 4918, 11.1
171
            208 => "Already Reported",                                 // Success - RFC 5842, 7.1
172
            218 => "This is fine",                                     // Unofficial - Apache Web Server
173
            419 => "Page Expired",                                     // Unofficial - Laravel Framework
174
            226 => "IM Used",                                          // Success - RFC 3229, 10.4.1
175
            300 => "Multiple Choices",                                 // Redirection - RFC 7231, 6.4.1
176
            301 => "Moved Permanently",                                // Redirection - RFC 7231, 6.4.2
177
            302 => "Found",                                            // Redirection - RFC 7231, 6.4.3
178
            303 => "See Other",                                        // Redirection - RFC 7231, 6.4.4
179
            304 => "Not Modified",                                     // Redirection - RFC 7232, 4.1
180
            305 => "Use Proxy",                                        // Redirection - RFC 7231, 6.4.5
181
            306 => "Switch Proxy",                                     // Redirection - RFC 7231, 6.4.6 (Deprecated)
182
            307 => "Temporary Redirect",                               // Redirection - RFC 7231, 6.4.7
183
            308 => "Permanent Redirect",                               // Redirection - RFC 7538, 3
184
            400 => "Bad Request",                                      // Client Error - RFC 7231, 6.5.1
185
            401 => "Unauthorized",                                     // Client Error - RFC 7235, 3.1
186
            402 => "Payment Required",                                 // Client Error - RFC 7231, 6.5.2
187
            403 => "Forbidden",                                        // Client Error - RFC 7231, 6.5.3
188
            404 => "Not Found",                                        // Client Error - RFC 7231, 6.5.4
189
            405 => "Method Not Allowed",                               // Client Error - RFC 7231, 6.5.5
190
            406 => "Not Acceptable",                                   // Client Error - RFC 7231, 6.5.6
191
            407 => "Proxy Authentication Required",                    // Client Error - RFC 7235, 3.2
192
            408 => "Request Time-out",                                 // Client Error - RFC 7231, 6.5.7
193
            409 => "Conflict",                                         // Client Error - RFC 7231, 6.5.8
194
            410 => "Gone",                                             // Client Error - RFC 7231, 6.5.9
195
            411 => "Length Required",                                  // Client Error - RFC 7231, 6.5.10
196
            412 => "Precondition Failed",                              // Client Error - RFC 7232, 4.2
197
            413 => "Request Entity Too Large",                         // Client Error - RFC 7231, 6.5.11
198
            414 => "Request-URI Too Large",                            // Client Error - RFC 7231, 6.5.12
199
            415 => "Unsupported Media Type",                           // Client Error - RFC 7231, 6.5.13
200
            416 => "Requested range not satisfiable",                  // Client Error - RFC 7233, 4.4
201
            417 => "Expectation Failed",                               // Client Error - RFC 7231, 6.5.14
202
            418 => "I'm a teapot",                                     // Client Error - RFC 7168, 2.3.3
203
            420 => "Method Failure",                                   // Unofficial - Spring Framework
204
            421 => "Misdirected Request",
205
            422 => "Unprocessable Entity",                             // Client Error - RFC 4918, 11.2
206
            423 => "Locked",                                           // Client Error - RFC 4918, 11.3
207
            424 => "Failed Dependency",                                // Client Error - RFC 4918, 11.4
208
            425 => "Unordered Collection",
209
            426 => "Upgrade Required",                                 // Client Error - RFC 7231, 6.5.15
210
            428 => "Precondition Required",                            // Client Error - RFC 6585, 3
211
            429 => "Too Many Requests",                                // Client Error - RFC 6585, 4
212
            431 => "Request Header Fields Too Large",                  // Client Error - RFC 6585, 5
213
            440 => "Login Time-out",                                   // Unofficial - IIS
214
            444 => "No Response",                                      // Unofficial - nginx
215
            449 => "Retry With",                                       // Unofficial - IIS
216
            494 => "Request header too large",                         // Unofficial - nginx
217
            495 => "SSL Certificate Error",                            // Unofficial - nginx
218
            496 => "SSL Certificate Required",                         // Unofficial - nginx
219
            497 => "HTTP Request Sent to HTTPS Port",                  // Unofficial - nginx
220
            499 => "Client Closed Request",                            // Unofficial - nginx
221
            450 => "Blocked by Windows Parental Controls (Microsoft)", // Unofficial - nginx
222
            451 => "Unavailable For Legal Reasons",                    // Client Error - RFC 7725, 3
223
            498 => "Invalid Token (Esri)",                             // Unofficial - ESRI
224
            500 => "Internal Server Error",                            // Server Error - RFC 7231, 6.6.1
225
            501 => "Not Implemented",                                  // Server Error - RFC 7231, 6.6.2
226
            502 => "Bad Gateway",                                      // Server Error - RFC 7231, 6.6.3
227
            503 => "Service Unavailable",                              // Server Error - RFC 7231, 6.6.4
228
            504 => "Gateway Time-out",                                 // Server Error - RFC 7231, 6.6.5
229
            505 => "HTTP Version not supported",                       // Server Error - RFC 7231, 6.6.6
230
            506 => "Variant Also Negotiates",                          // Server Error - RFC 2295, 8.1
231
            507 => "Insufficient Storage",                             // Server Error - RFC 4918, 11.5
232
            508 => "Loop Detected",                                    // Server Error - RFC 5842, 7.2
233
            509 => "Bandwidth Limit Exceeded",                         // Unofficial - Apache/cPanel
234
            510 => "Not Extended",                                     // Server Error - RFC 2774, 7
235
            511 => "Network Authentication Required",                  // Server Error - RFC 6585, 6
236
            520 => "Unknown Error",                                    // Unofficial - Cloudflare
237
            521 => "Web Server Is Down",                               // Unofficial - Cloudflare
238
            522 => "Connection Timed Out",                             // Unofficial - Cloudflare
239
            523 => "Origin Is Unreachable",                            // Unofficial - Cloudflare
240
            524 => "A Timeout Occurred",                               // Unofficial - Cloudflare
241
            525 => "SSL Handshake Failed",                             // Unofficial - Cloudflare
242
            526 => "Invalid SSL Certificate",                          // Unofficial - Cloudflare
243
            527 => "Railgun Error",                                    // Unofficial - Cloudflare
244
            530 => "Origin DNS Error",                                 // Unofficial - Cloudflare
245
            598 => "Network read timeout error",                       // Unofficial
246
            599 => "Network Connect Timeout Error"                     // Server Error - RFC 6585, 6
247
        ];
248
    }
249
250
    /**
251
     * Set a valid status code and phrase
252
     *
253
     * @param mixed $code
254
     * @param mixed $phrase
255
     */
256
    private function processCode($code, $phrase = ""): void
257
    {
258
        $phrases = $this->getPhrases();
259
260
        $this->checkCodeType($code);
261
262
        $code = (int) $code;
263
        $this->checkCodeValue($code);
264
265
        if (!is_string($phrase)) {
266
            throw new InvalidArgumentException("Invalid response reason");
267
        }
268
269
        if ("" === $phrase && isset($phrases[$code])) {
270
            $phrase = $phrases[$code];
271
        }
272
273
        $this->statusCode   = $code;
274
        $this->reasonPhrase = $phrase;
275
    }
276
}
277