Message   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 52
dl 0
loc 158
rs 10
c 2
b 0
f 0
wmc 20

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getHeaders() 0 2 1
A getProtocolVersion() 0 2 1
A withHeader() 0 18 3
A __construct() 0 2 1
A hasHeader() 0 2 1
A withProtocolVersion() 0 10 2
A getHeaderLine() 0 2 1
A getHeader() 0 7 2
A withBody() 0 10 2
A getBody() 0 2 1
A withAddedHeader() 0 20 3
A withoutHeader() 0 13 2
1
<?php
2
/**
3
 * Class Message
4
 *
5
 * @created      11.08.2018
6
 * @author       smiley <[email protected]>
7
 * @copyright    2018 smiley
8
 * @license      MIT
9
 *
10
 * @phan-file-suppress PhanParamSignatureMismatch
11
 */
12
13
namespace chillerlan\HTTP\Psr7;
14
15
use chillerlan\HTTP\Utils\HeaderUtil;
16
use Psr\Http\Message\{MessageInterface, StreamInterface};
17
18
use function array_merge, fopen, implode, is_array, strtolower;
19
20
abstract class Message implements MessageInterface{
21
22
	protected array $headers = [];
23
	/** @var string[] */
24
	protected array $headerNames = [];
25
26
	protected string $version = '1.1';
27
28
	protected StreamInterface $body;
29
30
	/**
31
	 * Message constructor.
32
	 */
33
	public function __construct(){
34
		$this->body = new Stream(fopen('php://temp', 'r+'));
35
	}
36
37
	/**
38
	 * @inheritDoc
39
	 */
40
	public function getProtocolVersion():string{
41
		return $this->version;
42
	}
43
44
	/**
45
	 * @inheritDoc
46
	 */
47
	public function withProtocolVersion($version):MessageInterface{
48
49
		if($this->version === $version){
50
			return $this;
51
		}
52
53
		$clone          = clone $this;
54
		$clone->version = $version;
55
56
		return $clone;
57
	}
58
59
	/**
60
	 * @inheritDoc
61
	 */
62
	public function getHeaders():array{
63
		return $this->headers;
64
	}
65
66
	/**
67
	 * @inheritDoc
68
	 */
69
	public function hasHeader($name):bool{
70
		return isset($this->headerNames[strtolower($name)]);
71
	}
72
73
	/**
74
	 * @inheritDoc
75
	 */
76
	public function getHeader($name):array{
77
78
		if(!$this->hasHeader($name)){
79
			return [];
80
		}
81
82
		return $this->headers[$this->headerNames[strtolower($name)]];
83
	}
84
85
	/**
86
	 * @inheritDoc
87
	 */
88
	public function getHeaderLine($name):string{
89
		return implode(', ', $this->getHeader($name));
90
	}
91
92
	/**
93
	 * @inheritDoc
94
	 */
95
	public function withHeader($name, $value):MessageInterface{
96
97
		if(!is_array($value)){
98
			$value = [$value];
99
		}
100
101
		$value      = HeaderUtil::trimValues($value);
102
		$normalized = strtolower($name);
103
		$clone      = clone $this;
104
105
		if(isset($clone->headerNames[$normalized])){
106
			unset($clone->headers[$clone->headerNames[$normalized]]);
107
		}
108
109
		$clone->headerNames[$normalized] = $name;
110
		$clone->headers[$name]           = $value;
111
112
		return $clone;
113
	}
114
115
	/**
116
	 * @inheritDoc
117
	 */
118
	public function withAddedHeader($name, $value):MessageInterface{
119
120
		if(!is_array($value)){
121
			$value = [$value];
122
		}
123
124
		$value      = HeaderUtil::trimValues($value);
125
		$normalized = strtolower($name);
126
		$clone      = clone $this;
127
128
		if(isset($clone->headerNames[$normalized])){
129
			$name                  = $this->headerNames[$normalized];
130
			$clone->headers[$name] = array_merge($this->headers[$name], $value);
131
		}
132
		else{
133
			$clone->headerNames[$normalized] = $name;
134
			$clone->headers[$name]           = $value;
135
		}
136
137
		return $clone;
138
	}
139
140
	/**
141
	 * @inheritDoc
142
	 */
143
	public function withoutHeader($name):MessageInterface{
144
		$normalized = strtolower($name);
145
146
		if(!isset($this->headerNames[$normalized])){
147
			return $this;
148
		}
149
150
		$name  = $this->headerNames[$normalized];
151
		$clone = clone $this;
152
153
		unset($clone->headers[$name], $clone->headerNames[$normalized]);
154
155
		return $clone;
156
	}
157
158
	/**
159
	 * @inheritDoc
160
	 */
161
	public function getBody():StreamInterface{
162
		return $this->body;
163
	}
164
165
	/**
166
	 * @inheritDoc
167
	 */
168
	public function withBody(StreamInterface $body):MessageInterface{
169
170
		if($body === $this->body){
171
			return $this;
172
		}
173
174
		$clone       = clone $this;
175
		$clone->body = $body;
176
177
		return $clone;
178
	}
179
180
}
181