Passed
Push — main ( 189a60...255c0f )
by Yevhenii
02:11
created

Response   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

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