Passed
Push — master ( fca16e...a09e23 )
by Alexander
04:10
created

HttpStatusCode::isInvalid()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
nc 2
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Lenevor Framework
5
 *
6
 * LICENSE
7
 *
8
 * This source file is subject to the new BSD license that is bundled
9
 * with this package in the file license.md.
10
 * It is also available through the world-wide-web at this URL:
11
 * https://lenevor.com/license
12
 * If you did not receive a copy of the license and are unable to
13
 * obtain it through the world-wide-web, please send an email
14
 * to [email protected] so we can send you a copy immediately.
15
 *
16
 * @package     Lenevor
17
 * @subpackage  Base
18
 * @link        https://lenevor.com
19
 * @copyright   Copyright (c) 2019 - 2023 Alexander Campo <[email protected]>
20
 * @license     https://opensource.org/licenses/BSD-3-Clause New BSD license or see https://lenevor.com/license or see /license.md
21
 */
22
 
23
namespace Syscodes\Components\Http\Resources;
24
25
use BadMethodCallException;
26
use InvalidArgumentException;
27
28
/**
29
 * This trait is responsible for loading the different HTTP status codes existing.
30
 */
31
trait HttpStatusCode
32
{
33
	/**
34
	 * The HTTP status code.
35
	 *
36
	 * @var int $statusCode
37
	 */
38
	protected $statusCode = 200;
39
40
	/**
41
	 * An array of status codes and messages.
42
	 *
43
	 * @var array $statusCodeTexts
44
	 */
45
	public static $statusCodeTexts = [
46
		// 1xx: Informational
47
		100 => 'Continue',
48
		101 => 'Switching Protocols',
49
		102 => 'Processing',
50
51
		// 2xx: Success
52
		200 => 'OK',
53
		201 => 'Created',
54
		202 => 'Accepted',
55
		203 => 'Non-Authoritative Information',
56
		204 => 'No Content',
57
		205 => 'Reset Content',
58
		206 => 'Partial Content',
59
		207 => 'Multi-Status',
60
		208 => 'Already Reported',
61
		226 => 'IM Used',
62
63
		// 3xx: Redirection
64
		300 => 'Multiple Choices',
65
		301 => 'Moved Permanently',
66
		302 => 'Found',
67
		303 => 'See Other',
68
		304 => 'Not Modified',
69
		305 => 'Use Proxy',
70
		307 => 'Temporary Redirect',
71
		308 => 'Permanent Redirect',
72
73
		// 4xx: Client error
74
		400 => 'Bad Request',
75
		401 => 'Unauthorized',
76
		402 => 'Payment Required',
77
		403 => 'Forbidden',
78
		404 => 'Not Found',
79
		405 => 'Method Not Allowed',
80
		406 => 'Not Acceptable',
81
		407 => 'Proxy Authentication Required',
82
		408 => 'Request Timeout',
83
		409 => 'Conflict',
84
		410 => 'Gone',
85
		411 => 'Length Required',
86
		412 => 'Precondition Failed',
87
		413 => 'Request Entity Too Large',
88
		414 => 'Request-URI Too Long',
89
		415 => 'Unsupported Media Type',
90
		416 => 'Requested Range Not Satisfiable',
91
		417 => 'Expectation Failed',
92
		418 => 'I\'m a Teapot',
93
		// 419 (Authentication Timeout) is a non-standard status code with unknown origin
94
		421 => 'Misdirected Request',
95
		422 => 'Unprocessable Entity',
96
		423 => 'Locked',
97
		424 => 'Failed Dependency',
98
		426 => 'Upgrade Required',
99
		428 => 'Precondition Required',
100
		429 => 'Too Many Requests',
101
		431 => 'Request Header Fields Too Large',
102
		451 => 'Unavailable For Legal Reasons',
103
104
		// 5xx: Server error
105
		500 => 'Internal Server Error',
106
		501 => 'Not Implemented',
107
		502 => 'Bad Gateway',
108
		503 => 'Service Unavailable',
109
		504 => 'Gateway Timeout',
110
		505 => 'HTTP Version Not Supported',
111
		506 => 'Variant Also Negotiates',
112
		507 => 'Insufficient Storage',
113
		508 => 'Loop Detected',
114
		509 => 'Bandwidth Limit Exceeded',
115
		510 => 'Not Extended',
116
		511 => 'Network Authentication Required'
117
	];
118
119
	/**
120
	 * Gets string of status code.
121
	 * 
122
	 * @var string $statusText
123
	 */
124
	protected $statusText;
125
126
	/**
127
	 * Gets the response status code.
128
	 *
129
	 * The status code is a 3-digit code to specify server response results to the browser.
130
	 *
131
	 * @return int
132
	 *
133
	 * @throws \BadMethodCallException
134
	 */
135
	public function getStatusCode(): int
136
	{
137
		if (empty($this->statusCode)) {
138
			throw new BadMethodCallException('HTTP Response is missing a status code');
139
		}
140
141
		return $this->statusCode;
142
	}
143
144
	/**
145
	* Sets the response status code.
146
	*
147
	* @param  int  $code  The status code
148
	* @param  string|null  $text  The status text
149
	*
150
	* @return static
151
	*
152
	* @throws \InvalidArgumentException
153
	*/
154
	public function setStatusCode(int $code, $text = null): static
155
	{
156
		$this->statusCode = $code; 
157
158
		// Valid range?
159
		if ($this->isInvalid()) {
160
			throw new InvalidArgumentException(__('response.statusCodeNotValid', ['code' => $code]));			
0 ignored issues
show
Bug introduced by
It seems like __('response.statusCodeN...array('code' => $code)) can also be of type array; however, parameter $message of InvalidArgumentException::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

160
			throw new InvalidArgumentException(/** @scrutinizer ignore-type */ __('response.statusCodeNotValid', ['code' => $code]));			
Loading history...
161
		}
162
163
		// Check if you have an accepted status code if not shows to a message of unknown status
164
		if (null === $text) {
165
			$this->statusText = self::$statusCodeTexts[$code] ?? __('response.UnknownStatus');
0 ignored issues
show
Documentation Bug introduced by
It seems like self::statusCodeTexts[$c...esponse.UnknownStatus') can also be of type array. However, the property $statusText is declared as type string. 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...
166
167
			return $this;
168
		}
169
170
		if (false === $text) {
0 ignored issues
show
introduced by
The condition false === $text is always false.
Loading history...
171
			$this->statusText = '';
172
173
			return $this;
174
		}
175
176
		$this->statusText = $text;
177
178
		return $this;
179
	}
180
181
	/**
182
	 * Is response invalid?
183
	 * 
184
	 * @final
185
	 * 
186
	 * @return bool
187
	 */
188
	public function isInvalid(): bool
189
	{
190
		return $this->statusCode < 100 || $this->statusCode >= 600;
191
	}
192
193
	/**
194
	 * Is response informative?
195
	 * 
196
	 * @final
197
	 * 
198
	 * @return bool
199
	 */
200
	public function isInformational(): bool
201
	{
202
		return $this->statusCode >= 100 && $this->statusCode < 200;
203
	}
204
	
205
	/**
206
	 * Is the response a redirect?
207
	 * 
208
	 * @final
209
	 * 
210
	 * @return void
211
	 */
212
	public function isRedirection(): bool
213
	{
214
		return $this->statusCode >= 300 && $this->statusCode < 400;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->statusCode...$this->statusCode < 400 returns the type boolean which is incompatible with the documented return type void.
Loading history...
215
	}
216
	
217
	/**
218
	 * Is the response empty?
219
	 * 
220
	 * @final
221
	 * 
222
	 * @return bool
223
	 */
224
	public function isEmpty(): bool
225
	{
226
		return in_array($this->statusCode, [204, 304]);
227
	}
228
	
229
	/**
230
	 * Is the response a redirect of some form?
231
	 * 
232
	 * @return bool
233
	 */
234
	public function isRedirect(): bool
235
	{
236
		return in_array($this->statusCode, [301, 302, 303, 307, 308]);
237
	}
238
}