Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
147 / 147
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
HttpStatusCode
100.00% covered (success)
100.00%
147 / 147
100.00% covered (success)
100.00%
11 / 11
14
100.00% covered (success)
100.00%
1 / 1
 reasonPhrase
100.00% covered (success)
100.00%
64 / 64
100.00% covered (success)
100.00%
1 / 1
1
 label
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 labelList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toArray
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 toArrayWithLabels
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 isInformational
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 isSuccess
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 isRedirection
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 isClientError
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
1
 isServerError
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 isError
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace DevToolbelt\Enums\Http;
6
7use DevToolbelt\Enums\EnumInterface;
8
9enum HttpStatusCode: int implements EnumInterface
10{
11    // 1xx Informational
12    case CONTINUE = 100;
13    case SWITCHING_PROTOCOLS = 101;
14    case PROCESSING = 102;
15    case EARLY_HINTS = 103;
16
17    // 2xx Success
18    case OK = 200;
19    case CREATED = 201;
20    case ACCEPTED = 202;
21    case NON_AUTHORITATIVE_INFORMATION = 203;
22    case NO_CONTENT = 204;
23    case RESET_CONTENT = 205;
24    case PARTIAL_CONTENT = 206;
25    case MULTI_STATUS = 207;
26    case ALREADY_REPORTED = 208;
27    case IM_USED = 226;
28
29    // 3xx Redirection
30    case MULTIPLE_CHOICES = 300;
31    case MOVED_PERMANENTLY = 301;
32    case FOUND = 302;
33    case SEE_OTHER = 303;
34    case NOT_MODIFIED = 304;
35    case USE_PROXY = 305;
36    case TEMPORARY_REDIRECT = 307;
37    case PERMANENT_REDIRECT = 308;
38
39    // 4xx Client Error
40    case BAD_REQUEST = 400;
41    case UNAUTHORIZED = 401;
42    case PAYMENT_REQUIRED = 402;
43    case FORBIDDEN = 403;
44    case NOT_FOUND = 404;
45    case METHOD_NOT_ALLOWED = 405;
46    case NOT_ACCEPTABLE = 406;
47    case PROXY_AUTHENTICATION_REQUIRED = 407;
48    case REQUEST_TIMEOUT = 408;
49    case CONFLICT = 409;
50    case GONE = 410;
51    case LENGTH_REQUIRED = 411;
52    case PRECONDITION_FAILED = 412;
53    case PAYLOAD_TOO_LARGE = 413;
54    case URI_TOO_LONG = 414;
55    case UNSUPPORTED_MEDIA_TYPE = 415;
56    case RANGE_NOT_SATISFIABLE = 416;
57    case EXPECTATION_FAILED = 417;
58    case IM_A_TEAPOT = 418;
59    case MISDIRECTED_REQUEST = 421;
60    case UNPROCESSABLE_ENTITY = 422;
61    case LOCKED = 423;
62    case FAILED_DEPENDENCY = 424;
63    case TOO_EARLY = 425;
64    case UPGRADE_REQUIRED = 426;
65    case PRECONDITION_REQUIRED = 428;
66    case TOO_MANY_REQUESTS = 429;
67    case REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
68    case UNAVAILABLE_FOR_LEGAL_REASONS = 451;
69
70    // 5xx Server Error
71    case INTERNAL_SERVER_ERROR = 500;
72    case NOT_IMPLEMENTED = 501;
73    case BAD_GATEWAY = 502;
74    case SERVICE_UNAVAILABLE = 503;
75    case GATEWAY_TIMEOUT = 504;
76    case HTTP_VERSION_NOT_SUPPORTED = 505;
77    case VARIANT_ALSO_NEGOTIATES = 506;
78    case INSUFFICIENT_STORAGE = 507;
79    case LOOP_DETECTED = 508;
80    case NOT_EXTENDED = 510;
81    case NETWORK_AUTHENTICATION_REQUIRED = 511;
82
83    public function reasonPhrase(): string
84    {
85        return match ($this) {
86            self::CONTINUE => 'Continue',
87            self::SWITCHING_PROTOCOLS => 'Switching Protocols',
88            self::PROCESSING => 'Processing',
89            self::EARLY_HINTS => 'Early Hints',
90            self::OK => 'OK',
91            self::CREATED => 'Created',
92            self::ACCEPTED => 'Accepted',
93            self::NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information',
94            self::NO_CONTENT => 'No Content',
95            self::RESET_CONTENT => 'Reset Content',
96            self::PARTIAL_CONTENT => 'Partial Content',
97            self::MULTI_STATUS => 'Multi-Status',
98            self::ALREADY_REPORTED => 'Already Reported',
99            self::IM_USED => 'IM Used',
100            self::MULTIPLE_CHOICES => 'Multiple Choices',
101            self::MOVED_PERMANENTLY => 'Moved Permanently',
102            self::FOUND => 'Found',
103            self::SEE_OTHER => 'See Other',
104            self::NOT_MODIFIED => 'Not Modified',
105            self::USE_PROXY => 'Use Proxy',
106            self::TEMPORARY_REDIRECT => 'Temporary Redirect',
107            self::PERMANENT_REDIRECT => 'Permanent Redirect',
108            self::BAD_REQUEST => 'Bad Request',
109            self::UNAUTHORIZED => 'Unauthorized',
110            self::PAYMENT_REQUIRED => 'Payment Required',
111            self::FORBIDDEN => 'Forbidden',
112            self::NOT_FOUND => 'Not Found',
113            self::METHOD_NOT_ALLOWED => 'Method Not Allowed',
114            self::NOT_ACCEPTABLE => 'Not Acceptable',
115            self::PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
116            self::REQUEST_TIMEOUT => 'Request Timeout',
117            self::CONFLICT => 'Conflict',
118            self::GONE => 'Gone',
119            self::LENGTH_REQUIRED => 'Length Required',
120            self::PRECONDITION_FAILED => 'Precondition Failed',
121            self::PAYLOAD_TOO_LARGE => 'Payload Too Large',
122            self::URI_TOO_LONG => 'URI Too Long',
123            self::UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
124            self::RANGE_NOT_SATISFIABLE => 'Range Not Satisfiable',
125            self::EXPECTATION_FAILED => 'Expectation Failed',
126            self::IM_A_TEAPOT => "I'm a teapot",
127            self::MISDIRECTED_REQUEST => 'Misdirected Request',
128            self::UNPROCESSABLE_ENTITY => 'Unprocessable Entity',
129            self::LOCKED => 'Locked',
130            self::FAILED_DEPENDENCY => 'Failed Dependency',
131            self::TOO_EARLY => 'Too Early',
132            self::UPGRADE_REQUIRED => 'Upgrade Required',
133            self::PRECONDITION_REQUIRED => 'Precondition Required',
134            self::TOO_MANY_REQUESTS => 'Too Many Requests',
135            self::REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large',
136            self::UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons',
137            self::INTERNAL_SERVER_ERROR => 'Internal Server Error',
138            self::NOT_IMPLEMENTED => 'Not Implemented',
139            self::BAD_GATEWAY => 'Bad Gateway',
140            self::SERVICE_UNAVAILABLE => 'Service Unavailable',
141            self::GATEWAY_TIMEOUT => 'Gateway Timeout',
142            self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version Not Supported',
143            self::VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
144            self::INSUFFICIENT_STORAGE => 'Insufficient Storage',
145            self::LOOP_DETECTED => 'Loop Detected',
146            self::NOT_EXTENDED => 'Not Extended',
147            self::NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required',
148        };
149    }
150
151    public function label(): string
152    {
153        return $this->value . ' ' . $this->reasonPhrase();
154    }
155
156    /**
157     * @return string[]
158     */
159    public function labelList(): array
160    {
161        return array_map(fn (self $case) => $case->label(), self::cases());
162    }
163
164    /**
165     * @return array<int, int>
166     */
167    public static function toArray(): array
168    {
169        $result = [];
170
171        foreach (self::cases() as $status) {
172            $result[$status->value] = $status->value;
173        }
174
175        return $result;
176    }
177
178    /**
179     * @return array<int, string>
180     */
181    public static function toArrayWithLabels(): array
182    {
183        $result = [];
184
185        foreach (self::cases() as $status) {
186            $result[$status->value] = $status->label();
187        }
188
189        return $result;
190    }
191
192    public function isInformational(): bool
193    {
194        return in_array($this, [
195            self::CONTINUE,
196            self::SWITCHING_PROTOCOLS,
197            self::PROCESSING,
198            self::EARLY_HINTS,
199        ], true);
200    }
201
202    public function isSuccess(): bool
203    {
204        return in_array($this, [
205            self::OK,
206            self::CREATED,
207            self::ACCEPTED,
208            self::NON_AUTHORITATIVE_INFORMATION,
209            self::NO_CONTENT,
210            self::RESET_CONTENT,
211            self::PARTIAL_CONTENT,
212            self::MULTI_STATUS,
213            self::ALREADY_REPORTED,
214            self::IM_USED,
215        ], true);
216    }
217
218    public function isRedirection(): bool
219    {
220        return in_array($this, [
221            self::MULTIPLE_CHOICES,
222            self::MOVED_PERMANENTLY,
223            self::FOUND,
224            self::SEE_OTHER,
225            self::NOT_MODIFIED,
226            self::USE_PROXY,
227            self::TEMPORARY_REDIRECT,
228            self::PERMANENT_REDIRECT,
229        ], true);
230    }
231
232    public function isClientError(): bool
233    {
234        return in_array($this, [
235            self::BAD_REQUEST,
236            self::UNAUTHORIZED,
237            self::PAYMENT_REQUIRED,
238            self::FORBIDDEN,
239            self::NOT_FOUND,
240            self::METHOD_NOT_ALLOWED,
241            self::NOT_ACCEPTABLE,
242            self::PROXY_AUTHENTICATION_REQUIRED,
243            self::REQUEST_TIMEOUT,
244            self::CONFLICT,
245            self::GONE,
246            self::LENGTH_REQUIRED,
247            self::PRECONDITION_FAILED,
248            self::PAYLOAD_TOO_LARGE,
249            self::URI_TOO_LONG,
250            self::UNSUPPORTED_MEDIA_TYPE,
251            self::RANGE_NOT_SATISFIABLE,
252            self::EXPECTATION_FAILED,
253            self::IM_A_TEAPOT,
254            self::MISDIRECTED_REQUEST,
255            self::UNPROCESSABLE_ENTITY,
256            self::LOCKED,
257            self::FAILED_DEPENDENCY,
258            self::TOO_EARLY,
259            self::UPGRADE_REQUIRED,
260            self::PRECONDITION_REQUIRED,
261            self::TOO_MANY_REQUESTS,
262            self::REQUEST_HEADER_FIELDS_TOO_LARGE,
263            self::UNAVAILABLE_FOR_LEGAL_REASONS,
264        ], true);
265    }
266
267    public function isServerError(): bool
268    {
269        return in_array($this, [
270            self::INTERNAL_SERVER_ERROR,
271            self::NOT_IMPLEMENTED,
272            self::BAD_GATEWAY,
273            self::SERVICE_UNAVAILABLE,
274            self::GATEWAY_TIMEOUT,
275            self::HTTP_VERSION_NOT_SUPPORTED,
276            self::VARIANT_ALSO_NEGOTIATES,
277            self::INSUFFICIENT_STORAGE,
278            self::LOOP_DETECTED,
279            self::NOT_EXTENDED,
280            self::NETWORK_AUTHENTICATION_REQUIRED,
281        ], true);
282    }
283
284    public function isError(): bool
285    {
286        return $this->isClientError() || $this->isServerError();
287    }
288}