Response   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 83
dl 0
loc 126
rs 10
c 3
b 0
f 0
wmc 6

4 Methods

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