HttpStatus   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 179
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
dl 0
loc 179
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A setProtocol() 0 6 2
A __construct() 0 16 4
A header() 0 7 2
1
<?php
2
/**
3
 * HttpStatusModel.php
4
 * @author      Marc-André Appel <[email protected]>
5
 * @copyright   2018 Hybride Conseil
6
 * @license     http://opensource.org/licenses/MIT MIT
7
 * @link        https://www.hybride-conseil.fr
8
 * @created     19/06/2018
9
 */
10
11
declare(strict_types=1);
12
13
namespace MarcAndreAppel\HttpStatus;
14
15
use MarcAndreAppel\HttpStatus\Exceptions\HeaderSentException;
16
17
class HttpStatus
18
{
19
	public $code;
20
	public $title;
21
	public $message;
22
23
	private $version = 1.0;
24
25
	private static $titles = array(
26
		100 => "Continue",
27
		101 => "Switching Protocols",
28
		102 => "Processing",
29
		103 => "Early Hints",
30
31
		200 => "OK",
32
		201 => "Created",
33
		202 => "Accepted",
34
		203 => "Non-Authoritative Information",
35
		204 => "No Content",
36
		205 => "Reset Content",
37
		206 => "Partial Content",
38
		207 => "Multi-Status",
39
		208 => "Already Reported",
40
		226 => "IM Used",
41
42
		300 => "Multiple Choices",
43
		301 => "Moved Permanently",
44
		302 => "Found",
45
		303 => "See Other",
46
		304 => "Not Modified",
47
		305 => "Use Proxy",
48
		307 => "Temporary Redirect",
49
		308 => "Permanent Redirect",
50
51
		400 => "Bad Request",
52
		401 => "Unauthorized",
53
		402 => "Payment Required",
54
		403 => "Forbidden",
55
		404 => "Not Found",
56
		405 => "Method Not Allowed",
57
		406 => "Not Acceptable",
58
		407 => "Proxy Authentication Required",
59
		408 => "Request Timeout",
60
		409 => "Conflict",
61
		410 => "Gone",
62
		411 => "Length Required",
63
		412 => "Precondition Failed",
64
		413 => "Payload Too Large",
65
		414 => "URI Too Long",
66
		415 => "Unsupported Media Type",
67
		416 => "Range Not Satisfiable",
68
		417 => "Expectation Failed",
69
		418 => "I\'m a teapot",
70
		421 => "Misdirected Request",
71
		422 => "Unprocessable Entity",
72
		423 => "Locked",
73
		424 => "Failed Dependency",
74
		425 => "Reserved for WebDAV advanced collections expired proposal",
75
		426 => "Upgrade Required",
76
		428 => "Precondition Required",
77
		429 => "Too Many Requests",
78
		431 => "Request Header Fields Too Large",
79
		451 => "Unavailable For Legal Reasons",
80
		
81
		500 => "Internal Server Error",
82
		501 => "Not Implemented",
83
		502 => "Bad Gateway",
84
		503 => "Service Unavailable",
85
		504 => "Gateway Timeout",
86
		505 => "HTTP Version Not Supported",
87
		506 => "Variant Also Negotiates",
88
		507 => "Insufficient Storage",
89
		508 => "Loop Detected",
90
		510 => "Not Extended",
91
		511 => "Network Authentication Required",
92
	);
93
94
	private static $messages = array(
95
		200 => "Standard response for successful HTTP requests.",
96
		201 => "The request has been fulfilled, resulting in the creation of a new resource.",
97
		202 => "The request has been accepted for processing, but the processing has not been completed.",
98
		203 => "The server is a transforming proxy (e.g. a Web accelerator) that received a 200 OK from its origin, but is returning a modified version of the origin\"s response.",
99
		204 => "The server successfully processed the request and is not returning any content.",
100
		205 => "The server successfully processed the request, but is not returning any content.",
101
		206 => "The server is delivering only part of the resource (byte serving) due to a range header sent by the client.",
102
		207 => "The message body that follows is an XML message and can contain a number of separate response codes, depending on how many sub-requests were made.",
103
		208 => "The members of a DAV binding have already been enumerated in a previous reply to this request, and are not being included again.",
104
		226 => "The server has fulfilled a request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.",
105
		
106
		300 => "Indicates multiple options for the resource from which the client may choose.",
107
		301 => "This and all future requests should be directed to the given URI.",
108
		302 => "This is an example of industry practice contradicting the standard.",
109
		303 => "The response to the request can be found under another URI using a GET method.",
110
		304 => "Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.",
111
		305 => "The requested resource is available only through a proxy, the address for which is provided in the response.",
112
		306 => "No longer used.",
113
		307 => "In this case, the request should be repeated with another URI; however, future requests should still use the original URI.",
114
		308 => "The request and all future requests should be repeated using another URI.",
115
		
116
		400 => "The request cannot be fulfilled due to bad syntax.",
117
		401 => "Authentication is required and has failed or has not yet been provided.",
118
		402 => "Reserved for future use.",
119
		403 => "The request was a valid request, but the server is refusing to respond to it.",
120
		404 => "The requested resource could not be found but may be available again in the future.",
121
		405 => "A request was made of a resource using a request method not supported by that resource.",
122
		406 => "The requested resource is only capable of generating content not acceptable.",
123
		407 => "Proxy authentication is required to access the requested resource.",
124
		408 => "The server did not receive a complete request message in time.",
125
		409 => "The request could not be processed because of conflict in the request.",
126
		410 => "The requested resource is no longer available and will not be available again.",
127
		411 => "The request did not specify the length of its content, which is required by the resource.",
128
		412 => "The server does not meet one of the preconditions that the requester put on the request.",
129
		413 => "The server cannot process the request because the request payload is too large.",
130
		414 => "The request-target is longer than the server is willing to interpret.",
131
		415 => "The request entity has a media type which the server or resource does not support.",
132
		416 => "The client has asked for a portion of the file, but the server cannot supply that portion.",
133
		417 => "The expectation given could not be met by at least one of the inbound servers.",
134
		418 => "I\'m a teapot",
135
		421 => "The request was directed at a server that is not able to produce a response.",
136
		422 => "The request was well-formed but was unable to be followed due to semantic errors.",
137
		423 => "The resource that is being accessed is locked.",
138
		424 => "The request failed due to failure of a previous request.",
139
		426 => "The server cannot process the request using the current protocol.",
140
		428 => "The origin server requires the request to be conditional.",
141
		429 => "The user has sent too many requests in a given amount of time.",
142
		431 => "The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.",
143
		451 => "Resource access is denied for legal reasons.",
144
		
145
		500 => "An error has occurred and this resource cannot be displayed.",
146
		501 => "The server either does not recognize the request method, or it lacks the ability to fulfil the request.",
147
		502 => "The server was acting as a gateway or proxy and received an invalid response from the upstream server.",
148
		503 => "The server is currently unavailable. It may be overloaded or down for maintenance.",
149
		504 => "The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.",
150
		505 => "The server does not support the HTTP protocol version used in the request.",
151
		506 => "Transparent content negotiation for the request, results in a circular reference.",
152
		507 => "The method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request. There is insufficient free space left in your storage allocation.",
153
		508 => "The server detected an infinite loop while processing the request.",
154
		510 => "Further extensions to the request are required for the server to fulfill it.A mandatory extension policy in the request is not accepted by the server for this resource.",
155
		511 => "The client needs to authenticate to gain network access.",
156
	);
157
158
	public function __construct(int $code = null)
159
	{
160
		if (is_null($code)) {
161
			throw new \InvalidArgumentException("Cannot be null nor empty");
162
		}
163
		if ( ! key_exists($code, self::$titles) || ! is_int($code)) {
164
			throw new \OutOfBoundsException("Not a valid integer or not a valid HTTP status code");
165
		}
166
167
		$this->code = $code;
168
		$this->title = self::$titles[$code];
169
		$this->message = self::$messages[$code] ?? null;
170
171
		$this->setProtocol();
172
173
		return $this;
174
	}
175
176
177
	/**
178
	 * @throws \MarcAndreAppel\HttpStatus\Exceptions\HeaderSentException
179
	 */
180
	public function header()
181
	{
182
		if (headers_sent()) {
183
			throw new HeaderSentException();
184
		} else {
185
			$header = sprintf("HTTP/%s %s %s", $this->version, $this->code, $this->title);
186
			header($header, true, $this->code);
187
		}
188
	}
189
190
	private function setProtocol()
191
	{
192
		if ("HTTP/1.0" != $_SERVER['SERVER_PROTOCOL']) {
193
			$this->version = 1.1;
194
		}
195
		return $this;
196
	}
197
}