Test Failed
Branch master (f83914)
by Rasul
07:02
created

Message   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 135
rs 10
c 0
b 0
f 0
wmc 21
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Furious\Psr7;
6
7
use Furious\Psr7\Header\HeaderTrimmer;
8
use Furious\Psr7\Header\HeaderValidator;
9
use Psr\Http\Message\MessageInterface;
10
use Psr\Http\Message\StreamInterface;
11
use Furious\Psr7\Exception\InvalidArgumentException;
12
use function mb_strtolower;
13
use function implode;
14
use function is_integer;
15
use function array_merge;
16
17
class Message implements MessageInterface
18
{
19
    protected string $protocolVersion = '1.1';
1 ignored issue
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
20
    protected array $headers = [];
21
    protected array $headerNames = [];
22
    protected ?StreamInterface $stream = null;
23
24
    // Protocol version
25
26
    public function getProtocolVersion(): string
27
    {
28
        return $this->protocolVersion;
29
    }
30
31
    public function withProtocolVersion($version): self
32
    {
33
        $message = clone $this;
34
        $message->protocolVersion = $version;
35
        return $message;
36
    }
37
38
    // Headers
39
40
    public function getHeaders(): array
41
    {
42
        return $this->headers;
43
    }
44
45
    public function hasHeader($name): bool
46
    {
47
        $header = mb_strtolower($name);
48
        return isset($this->headerNames[$header]);
49
    }
50
51
    public function getHeader($name): array
52
    {
53
        $header = mb_strtolower($name);
54
        if ($this->hasHeader($header)) {
55
            $header = $this->headerNames[$header];
56
            return $this->headers[$header];
57
        }
58
59
        return [];
60
    }
61
62
    public function getHeaderLine($name): string
63
    {
64
        $header = $this->getHeader($name);
65
        return implode(', ', $header);
66
    }
67
68
    public function withHeader($name, $value): self
69
    {
70
        (new HeaderValidator())->validate($name, $value);
71
        $value = (new HeaderTrimmer())->trim($value);
72
        $lowerHeader = mb_strtolower($name);
73
74
        $message = clone $this;
75
76
        if (isset($message->headerNames[$lowerHeader])) {
77
            unset($message->headers[$message->headerNames[$lowerHeader]]);
78
        }
79
80
        $message->headerNames[$lowerHeader] = $name;
81
        $message->headers[$name] = $value;
82
83
        return $message;
84
    }
85
86
    public function withAddedHeader($name, $value): self
87
    {
88
        if (!is_string($name) or empty($name)) {
89
            throw new InvalidArgumentException('Header name must be an RFC 7230 compatible string.');
90
        }
91
92
        $message = clone $this;
93
        $message->setHeaders([
94
            $name => $value
95
        ]);
96
97
        return $message;
98
    }
99
100
    public function withoutHeader($name): self
101
    {
102
        $header = mb_strtolower($name);
103
        if (!$this->hasHeader($header)) {
104
            return $this;
105
        }
106
107
        $headerName = $this->headerNames[$header];
108
109
        $message = clone $this;
110
111
        unset($message->headers[$headerName]);
112
        unset($message->headerNames[$header]);
113
114
        return $message;
115
    }
116
117
    // Body
118
119
    public function getBody(): StreamInterface
120
    {
121
        if (null === $this->stream) {
122
            $this->stream = Stream::new();
123
        }
124
125
        return $this->stream;
126
    }
127
128
    public function withBody(StreamInterface $body): self
129
    {
130
        $message = clone $this;
131
        $message->stream = $body;
132
        return $message;
133
    }
134
135
    protected function setHeaders(array $headers): void
136
    {
137
        foreach ($headers as $header => $value) {
138
            if (is_integer($header)) {
139
                $header = (string) $header;
140
            }
141
142
            (new HeaderValidator())->validate($header, $value);
143
            $value = (new HeaderTrimmer())->trim($value);
144
            $lowerHeader = mb_strtolower($header);
145
146
            if ($this->hasHeader($lowerHeader)) {
147
                $header = $this->headerNames[$lowerHeader];
148
                $this->headers[$header] = array_merge($this->getHeader($header), $value);
149
            } else {
150
                $this->headerNames[$lowerHeader] = $header;
151
                $this->headers[$header] = $value;
152
            }
153
        }
154
    }
155
}