Response   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 14
eloc 93
c 2
b 0
f 0
dl 0
loc 173
ccs 0
cts 29
cp 0
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __toString() 0 12 3
A __construct() 0 10 4
A setStatus() 0 18 5
A getStatus() 0 3 1
A getStatusText() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SteamMarketProviders\ParserManager\Http;
6
7
use SteamMarketProviders\ParserManager\Contract\Http\ResponseInterface;
8
9
class Response extends AbstractMessage implements ResponseInterface
10
{
11
    /**
12
     * This is the list of currently registered HTTP status codes.
13
     *
14
     * @var array
15
     */
16
    public static $statusCodes = [
17
        100 => 'Continue',
18
        101 => 'Switching Protocols',
19
        102 => 'Processing',
20
        200 => 'OK',
21
        201 => 'Created',
22
        202 => 'Accepted',
23
        203 => 'Non-Authorative Information',
24
        204 => 'No Content',
25
        205 => 'Reset Content',
26
        206 => 'Partial Content',
27
        207 => 'Multi-Status', // RFC 4918
28
        208 => 'Already Reported', // RFC 5842
29
        226 => 'IM Used', // RFC 3229
30
        300 => 'Multiple Choices',
31
        301 => 'Moved Permanently',
32
        302 => 'Found',
33
        303 => 'See Other',
34
        304 => 'Not Modified',
35
        305 => 'Use Proxy',
36
        307 => 'Temporary Redirect',
37
        308 => 'Permanent Redirect',
38
        400 => 'Bad Request',
39
        401 => 'Unauthorized',
40
        402 => 'Payment Required',
41
        403 => 'Forbidden',
42
        404 => 'Not Found',
43
        405 => 'Method Not Allowed',
44
        406 => 'Not Acceptable',
45
        407 => 'Proxy Authentication Required',
46
        408 => 'Request Timeout',
47
        409 => 'Conflict',
48
        410 => 'Gone',
49
        411 => 'Length Required',
50
        412 => 'Precondition failed',
51
        413 => 'Request Entity Too Large',
52
        414 => 'Request-URI Too Long',
53
        415 => 'Unsupported Media Type',
54
        416 => 'Requested Range Not Satisfiable',
55
        417 => 'Expectation Failed',
56
        418 => 'I\'m a teapot', // RFC 2324
57
        421 => 'Misdirected Request', // RFC7540 (HTTP/2)
58
        422 => 'Unprocessable Entity', // RFC 4918
59
        423 => 'Locked', // RFC 4918
60
        424 => 'Failed Dependency', // RFC 4918
61
        426 => 'Upgrade Required',
62
        428 => 'Precondition Required', // RFC 6585
63
        429 => 'Too Many Requests', // RFC 6585
64
        431 => 'Request Header Fields Too Large', // RFC 6585
65
        451 => 'Unavailable For Legal Reasons', // draft-tbray-http-legally-restricted-status
66
        500 => 'Internal Server Error',
67
        501 => 'Not Implemented',
68
        502 => 'Bad Gateway',
69
        503 => 'Service Unavailable',
70
        504 => 'Gateway Timeout',
71
        505 => 'HTTP Version not supported',
72
        506 => 'Variant Also Negotiates',
73
        507 => 'Insufficient Storage', // RFC 4918
74
        508 => 'Loop Detected', // RFC 5842
75
        509 => 'Bandwidth Limit Exceeded', // non-standard
76
        510 => 'Not extended',
77
        511 => 'Network Authentication Required', // RFC 6585
78
    ];
79
80
    /**
81
     * HTTP status code.
82
     *
83
     * @var int
84
     */
85
    protected int $status;
86
87
    /**
88
     * HTTP status text.
89
     *
90
     * @var string
91
     */
92
    protected string $statusText;
93
94
    /**
95
     * Creates the response object.
96
     *
97
     * @param string|int $status
98
     * @param array      $headers
99
     * @param resource   $body
100
     */
101
    public function __construct($status = 500, array $headers = null, $body = null)
102
    {
103
        if (null !== $status) {
0 ignored issues
show
introduced by
The condition null !== $status is always true.
Loading history...
104
            $this->setStatus($status);
105
        }
106
        if (null !== $headers) {
107
            $this->setHeaders($headers);
108
        }
109
        if (null !== $body) {
110
            $this->setBody($body);
111
        }
112
    }
113
114
    /**
115
     * Returns the current HTTP status code.
116
     */
117
    public function getStatus(): int
118
    {
119
        return $this->status;
120
    }
121
122
    /**
123
     * Returns the human-readable status string.
124
     *
125
     * In the case of a 200, this may for example be 'OK'.
126
     */
127
    public function getStatusText(): string
128
    {
129
        return $this->statusText;
130
    }
131
132
    /**
133
     * Sets the HTTP status code.
134
     *
135
     * This can be either the full HTTP status code with human readable string,
136
     * for example: "403 I can't let you do that, Dave".
137
     *
138
     * Or just the code, in which case the appropriate default message will be
139
     * added.
140
     *
141
     * @param string|int $status
142
     *
143
     * @throws \InvalidArgumentException
144
     */
145
    public function setStatus($status)
146
    {
147
        if (is_int($status) || ctype_digit($status)) {
148
            $statusCode = $status;
149
            $statusText = self::$statusCodes[$status] ?? 'Unknown';
150
        } else {
151
            list(
152
                $statusCode,
153
                $statusText
154
                ) = explode(' ', $status, 2);
155
            $statusCode = (int) $statusCode;
156
        }
157
        if ($statusCode < 100 || $statusCode > 999) {
158
            throw new \InvalidArgumentException('The HTTP status code must be exactly 3 digits');
159
        }
160
161
        $this->status = $statusCode;
0 ignored issues
show
Documentation Bug introduced by
It seems like $statusCode can also be of type string. However, the property $status is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
162
        $this->statusText = $statusText;
163
    }
164
165
    /**
166
     * Serializes the response object as a string.
167
     *
168
     * This is useful for debugging purposes.
169
     */
170
    public function __toString(): string
171
    {
172
        $str = 'HTTP/'.$this->httpVersion.' '.$this->getStatus().' '.$this->getStatusText()."\r\n";
173
        foreach ($this->getHeaders() as $key => $value) {
174
            foreach ($value as $v) {
175
                $str .= $key.': '.$v."\r\n";
176
            }
177
        }
178
        $str .= "\r\n";
179
        $str .= $this->getBodyAsString();
180
181
        return $str;
182
    }
183
}
184