Passed
Push — gh-pages ( 22b0fe...eb2d91 )
by
unknown
12:27 queued 10:15
created

Response   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 87
c 1
b 0
f 0
dl 0
loc 143
rs 10
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getReasonPhrase() 0 2 1
A __construct() 0 9 3
A withStatus() 0 13 3
A getStatusCode() 0 2 1
1
<?php
2
/**
3
 * Class Response
4
 *
5
 * @created      11.08.2018
6
 * @author       smiley <[email protected]>
7
 * @copyright    2018 smiley
8
 * @license      MIT
9
 */
10
11
namespace chillerlan\HTTP\Psr7;
12
13
use Fig\Http\Message\StatusCodeInterface;
14
use Psr\Http\Message\ResponseInterface;
15
16
final class Response extends Message implements ResponseInterface, StatusCodeInterface{
17
18
	/**
19
	 * Status codes and reason phrases
20
	 *
21
	 * @var array
22
	 */
23
	public const REASON_PHRASES = [
24
		//Informational 1xx
25
		self::STATUS_CONTINUE                        => 'Continue',
26
		self::STATUS_SWITCHING_PROTOCOLS             => 'Switching Protocols',
27
		self::STATUS_PROCESSING                      => 'Processing',
28
		self::STATUS_EARLY_HINTS                     => 'Early Hints',
29
		//Successful 2xx
30
		self::STATUS_OK                              => 'OK',
31
		self::STATUS_CREATED                         => 'Created',
32
		self::STATUS_ACCEPTED                        => 'Accepted',
33
		self::STATUS_NON_AUTHORITATIVE_INFORMATION   => 'Non-Authoritative Information',
34
		self::STATUS_NO_CONTENT                      => 'No Content',
35
		self::STATUS_RESET_CONTENT                   => 'Reset Content',
36
		self::STATUS_PARTIAL_CONTENT                 => 'Partial Content',
37
		self::STATUS_MULTI_STATUS                    => 'Multi-Status',
38
		self::STATUS_ALREADY_REPORTED                => 'Already Reported',
39
		self::STATUS_IM_USED                         => 'IM Used',
40
		//Redirection 3xx
41
		self::STATUS_MULTIPLE_CHOICES                => 'Multiple Choices',
42
		self::STATUS_MOVED_PERMANENTLY               => 'Moved Permanently',
43
		self::STATUS_FOUND                           => 'Found',
44
		self::STATUS_SEE_OTHER                       => 'See Other',
45
		self::STATUS_NOT_MODIFIED                    => 'Not Modified',
46
		self::STATUS_USE_PROXY                       => 'Use Proxy',
47
		self::STATUS_RESERVED                        => 'Reserved',
48
		self::STATUS_TEMPORARY_REDIRECT              => 'Temporary Redirect',
49
		self::STATUS_PERMANENT_REDIRECT              => 'Permanent Redirect',
50
		//Client Error 4xx
51
		self::STATUS_BAD_REQUEST                     => 'Bad Request',
52
		self::STATUS_UNAUTHORIZED                    => 'Unauthorized',
53
		self::STATUS_PAYMENT_REQUIRED                => 'Payment Required',
54
		self::STATUS_FORBIDDEN                       => 'Forbidden',
55
		self::STATUS_NOT_FOUND                       => 'Not Found',
56
		self::STATUS_METHOD_NOT_ALLOWED              => 'Method Not Allowed',
57
		self::STATUS_NOT_ACCEPTABLE                  => 'Not Acceptable',
58
		self::STATUS_PROXY_AUTHENTICATION_REQUIRED   => 'Proxy Authentication Required',
59
		self::STATUS_REQUEST_TIMEOUT                 => 'Request Timeout',
60
		self::STATUS_CONFLICT                        => 'Conflict',
61
		self::STATUS_GONE                            => 'Gone',
62
		self::STATUS_LENGTH_REQUIRED                 => 'Length Required',
63
		self::STATUS_PRECONDITION_FAILED             => 'Precondition Failed',
64
		self::STATUS_PAYLOAD_TOO_LARGE               => 'Request Entity Too Large',
65
		self::STATUS_URI_TOO_LONG                    => 'Request-URI Too Long',
66
		self::STATUS_UNSUPPORTED_MEDIA_TYPE          => 'Unsupported Media Type',
67
		self::STATUS_RANGE_NOT_SATISFIABLE           => 'Requested Range Not Satisfiable',
68
		self::STATUS_EXPECTATION_FAILED              => 'Expectation Failed',
69
		self::STATUS_IM_A_TEAPOT                     => 'I\'m a teapot',
70
		420                                          => 'Enhance Your Calm', // https://http.cat/420
71
		self::STATUS_MISDIRECTED_REQUEST             => 'Misdirected Request',
72
		self::STATUS_UNPROCESSABLE_ENTITY            => 'Unprocessable Entity',
73
		self::STATUS_LOCKED                          => 'Locked',
74
		self::STATUS_FAILED_DEPENDENCY               => 'Failed Dependency',
75
		self::STATUS_TOO_EARLY                       => 'Too Early',
76
		self::STATUS_UPGRADE_REQUIRED                => 'Upgrade Required',
77
		self::STATUS_PRECONDITION_REQUIRED           => 'Precondition Required',
78
		self::STATUS_TOO_MANY_REQUESTS               => 'Too Many Requests',
79
		self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large',
80
		444                                          => 'Connection Closed Without Response',
81
		self::STATUS_UNAVAILABLE_FOR_LEGAL_REASONS   => 'Unavailable For Legal Reasons',
82
		499                                          => 'Client Closed Request',
83
		//Server Error 5xx
84
		self::STATUS_INTERNAL_SERVER_ERROR           => 'Internal Server Error',
85
		self::STATUS_NOT_IMPLEMENTED                 => 'Not Implemented',
86
		self::STATUS_BAD_GATEWAY                     => 'Bad Gateway',
87
		self::STATUS_SERVICE_UNAVAILABLE             => 'Service Unavailable',
88
		self::STATUS_GATEWAY_TIMEOUT                 => 'Gateway Timeout',
89
		self::STATUS_VERSION_NOT_SUPPORTED           => 'HTTP Version Not Supported',
90
		self::STATUS_VARIANT_ALSO_NEGOTIATES         => 'Variant Also Negotiates',
91
		self::STATUS_INSUFFICIENT_STORAGE            => 'Insufficient Storage',
92
		self::STATUS_LOOP_DETECTED                   => 'Loop Detected',
93
		self::STATUS_NOT_EXTENDED                    => 'Not Extended',
94
		self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required',
95
		599                                          => 'Network Connect Timeout Error',
96
	];
97
98
	/**
99
	 * @var string
100
	 */
101
	private string $reasonPhrase;
102
103
	/**
104
	 * @var int
105
	 */
106
	private int $statusCode;
107
108
	/**
109
	 * Response constructor.
110
	 *
111
	 * @param int|null                                               $status
112
	 * @param array|null                                             $headers
113
	 * @param string|null|resource|\Psr\Http\Message\StreamInterface $body
114
	 * @param string|null                                            $version
115
	 * @param string|null                                            $reason
116
	 */
117
	public function __construct(int $status = null, array $headers = null, $body = null, string $version = null, string $reason = null){
118
		parent::__construct($headers, $body, $version);
119
120
		$reason = $reason ?? '';
121
122
		$this->statusCode   = $status ?? $this::STATUS_OK;
123
		$this->reasonPhrase = $reason === '' && isset($this::REASON_PHRASES[$this->statusCode])
124
			? $this::REASON_PHRASES[$this->statusCode]
125
			: $reason;
126
127
	}
128
129
	/**
130
	 * @inheritDoc
131
	 */
132
	public function getStatusCode():int{
133
		return $this->statusCode;
134
	}
135
136
	/**
137
	 * @inheritDoc
138
	 */
139
	public function withStatus($code, $reasonPhrase = ''):ResponseInterface{
140
		$code         = (int)$code;
141
		$reasonPhrase = (string)$reasonPhrase;
142
143
		if($reasonPhrase === '' && isset($this::REASON_PHRASES[$code])){
144
			$reasonPhrase = $this::REASON_PHRASES[$code];
145
		}
146
147
		$clone               = clone $this;
148
		$clone->statusCode   = $code;
149
		$clone->reasonPhrase = $reasonPhrase;
150
151
		return $clone;
152
	}
153
154
	/**
155
	 * @inheritDoc
156
	 */
157
	public function getReasonPhrase():string{
158
		return $this->reasonPhrase;
159
	}
160
161
}
162