Passed
Pull Request — master (#56)
by Charis
01:50
created

Message   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 193
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 25
eloc 70
dl 0
loc 193
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getHeaders() 0 3 1
A withoutHeader() 0 10 2
A getBody() 0 6 2
A getHeaderLine() 0 3 1
A withAddedHeader() 0 16 3
A getProtocolVersion() 0 3 1
A hasHeader() 0 3 1
A setHeaders() 0 15 4
A trimHeaderValues() 0 5 1
A withProtocolVersion() 0 11 2
A getHeader() 0 9 2
A withBody() 0 8 2
A withHeader() 0 14 3
1
<?php
2
3
namespace One\Http;
4
5
use Psr\Http\Message\StreamInterface;
6
7
/**
8
 *
9
 */
10
class Message implements \Psr\Http\Message\MessageInterface
11
{
12
    protected $headers = [];
13
14
    protected $headerNames = [];
15
16
    protected $protocol = '1.1';
17
18
    protected $stream;
19
20
    /**
21
     * @inheritDoc
22
     */
23
    public function getProtocolVersion()
24
    {
25
        return $this->protocol;
26
    }
27
  
28
    /**
29
     * @inheritDoc
30
     */
31
    public function withProtocolVersion($version)
32
    {
33
        if ($this->protocol == $version) {
34
            return $this;
35
        }
36
37
        $new = clone $this;
38
39
        $new->protocol = $version;
40
41
        return $new;
42
    }
43
  
44
    /**
45
     * @inheritDoc
46
     */
47
    public function getHeaders()
48
    {
49
        return $this->headers;
50
    }
51
  
52
    /**
53
     * @inheritDoc
54
     */
55
    public function hasHeader($name)
56
    {
57
        return isset($this->headerNames[strtolower($name)]);
58
    }
59
  
60
    /**
61
     * @inheritDoc
62
     */
63
    public function getHeader($name)
64
    {
65
        $lower = strtolower($name);
66
67
        if (!isset($this->headerNames[$lower])) {
68
            return array();
69
        }
70
71
        return $this->headers[$this->headerNames[$lower]];
72
    }
73
  
74
    /**
75
     * @inheritDoc
76
     */
77
    public function getHeaderLine($header)
78
    {
79
        return implode(', ', $this->getHeader($header));
80
    }
81
  
82
    /**
83
     * @inheritDoc
84
     */
85
    public function withHeader($header, $value)
86
    {
87
        if (!is_array($value)) {
88
            $value = [$value];
89
        }
90
        $value      = $this->trimHeaderValues($value);
91
        $normalized = strtolower($header);
92
        $new        = clone $this;
93
        if (isset($new->headerNames[$normalized])) {
94
            unset($new->headers[$new->headerNames[$normalized]]);
95
        }
96
        $new->headerNames[$normalized] = $header;
97
        $new->headers[$header]         = $value;
98
        return $new;
99
    }
100
  
101
    /**
102
     * @inheritDoc
103
     */
104
    public function withAddedHeader($header, $value)
105
    {
106
        if (!is_array($value)) {
107
            $value = [$value];
108
        }
109
        $value      = $this->trimHeaderValues($value);
110
        $normalized = strtolower($header);
111
        $new        = clone $this;
112
        if (isset($new->headerNames[$normalized])) {
113
            $header                = $this->headerNames[$normalized];
114
            $new->headers[$header] = array_merge($this->headers[$header], $value);
115
        } else {
116
            $new->headerNames[$normalized] = $header;
117
            $new->headers[$header]         = $value;
118
        }
119
        return $new;
120
    }
121
  
122
    /**
123
     * @inheritDoc
124
     */
125
    public function withoutHeader($header)
126
    {
127
        $normalized = strtolower($header);
128
        if (!isset($this->headerNames[$normalized])) {
129
            return $this;
130
        }
131
        $header = $this->headerNames[$normalized];
132
        $new    = clone $this;
133
        unset($new->headers[$header], $new->headerNames[$normalized]);
134
        return $new;
135
    }
136
  
137
    /**
138
     * @inheritDoc
139
     */
140
    public function getBody()
141
    {
142
        if (!$this->stream) {
143
            $this->stream = \One\stream_for('');
144
        }
145
        return $this->stream;
146
    }
147
  
148
    /**
149
     * @inheritDoc
150
     */
151
    public function withBody(\Psr\Http\Message\StreamInterface $body)
152
    {
153
        if ($body === $this->stream) {
154
            return $this;
155
        }
156
        $new = clone $this;
157
        $new->stream = $body;
158
        return $new;
159
    }
160
  
161
    /**
162
     * Set header
163
     * @param array $headers
164
     */
165
    protected function setHeaders(array $headers)
166
    {
167
        $this->headerNames = $this->headers = [];
168
        foreach ($headers as $header => $value) {
169
            if (!is_array($value)) {
170
                $value = [$value];
171
            }
172
            $value = $this->trimHeaderValues($value);
173
            $normalized = strtolower($header);
174
            if (isset($this->headerNames[$normalized])) {
175
                $header = $this->headerNames[$normalized];
176
                $this->headers[$header] = array_merge($this->headers[$header], $value);
177
            } else {
178
                $this->headerNames[$normalized] = $header;
179
                $this->headers[$header] = $value;
180
            }
181
        }
182
    }
183
    
184
    /**
185
     * Trims whitespace from the header values.
186
     *
187
     * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
188
     *
189
     * header-field = field-name ":" OWS field-value OWS
190
     * OWS          = *( SP / HTAB )
191
     *
192
     * @param string[] $values Header values
193
     *
194
     * @return string[] Trimmed header values
195
     *
196
     * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
197
     */
198
    protected function trimHeaderValues(array $values)
199
    {
200
        return array_map(function ($value) {
201
            return trim($value, " \t");
202
        }, $values);
203
    }
204
}
205