Completed
Pull Request — master (#30)
by Михаил
09:24
created

ResponseBuilder::setHeadersFromString()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 10.8265

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 18
ccs 5
cts 13
cp 0.3846
rs 8.8571
cc 5
eloc 10
nc 2
nop 1
crap 10.8265
1
<?php
2
3
namespace Http\Message\Builder;
4
5
use Psr\Http\Message\ResponseInterface;
6
7
/**
8
 * Fills response object with values.
9
 */
10
class ResponseBuilder
11
{
12
    /**
13
     * The response to be built.
14
     *
15
     * @var ResponseInterface
16
     */
17
    protected $response;
18
19
    /**
20
     * Create builder for the given response.
21
     *
22
     * @param ResponseInterface $response
23
     */
24 3
    public function __construct(ResponseInterface $response)
25
    {
26 3
        $this->response = $response;
27 3
    }
28
29
    /**
30
     * Return response.
31
     *
32
     * @return ResponseInterface
33
     */
34
    public function getResponse()
35
    {
36
        return $this->response;
37
    }
38
39
    /**
40
     * Add headers represented by an array of header lines.
41
     *
42
     * @param string[] $headers Response headers as array of header lines.
43
     *
44
     * @return $this
45
     *
46
     * @throws \UnexpectedValueException For invalid header values.
47
     * @throws \InvalidArgumentException For invalid status code arguments.
48
     */
49 2
    public function setHeadersFromArray(array $headers)
50
    {
51 2
        $statusLine = trim(array_shift($headers));
52 2
        $parts = explode(' ', $statusLine, 3);
53 2
        if (count($parts) < 2 || substr(strtolower($parts[0]), 0, 5) !== 'http/') {
54
            throw new \UnexpectedValueException(
55
                sprintf('"%s" is not a valid HTTP status line', $statusLine)
56
            );
57
        }
58
59 2
        $reasonPhrase = count($parts) > 2 ? $parts[2] : '';
60 2
        $this->response = $this->response
61 2
            ->withStatus((int) $parts[1], $reasonPhrase)
62 2
            ->withProtocolVersion(substr($parts[0], 5));
63
64 2
        foreach ($headers as $headerLine) {
65 2
            $headerLine = trim($headerLine);
66 2
            if ('' === $headerLine) {
67 1
                continue;
68
            }
69
70 2
            $parts = explode(':', $headerLine, 2);
71 2
            if (count($parts) !== 2) {
72
                throw new \UnexpectedValueException(
73
                    sprintf('"%s" is not a valid HTTP header line', $headerLine)
74
                );
75
            }
76 2
            $name = trim(urldecode($parts[0]));
77 2
            $value = trim(urldecode($parts[1]));
78 2
            if ($this->response->hasHeader($name)) {
79
                $this->response = $this->response->withAddedHeader($name, $value);
80
            } else {
81 2
                $this->response = $this->response->withHeader($name, $value);
82
            }
83 2
        }
84
85 2
        return $this;
86
    }
87
88
    /**
89
     * Add headers represented by a single string.
90
     *
91
     * @param string $headers Response headers as single string.
92
     *
93
     * @return $this
94
     *
95
     * @throws \InvalidArgumentException if $headers is not a string on object with __toString()
96
     * @throws \UnexpectedValueException For invalid header values.
97
     */
98 1
    public function setHeadersFromString($headers)
99
    {
100 1
        if (!(is_string($headers)
101
            || (is_object($headers) && method_exists($headers, '__toString')))
102 1
        ) {
103
            throw new \InvalidArgumentException(
104
                sprintf(
105
                    '%s expects parameter 1 to be a string, %s given',
106
                    __METHOD__,
107
                    is_object($headers) ? get_class($headers) : gettype($headers)
108
                )
109
            );
110
        }
111
112 1
        $this->setHeadersFromArray(explode("\r\n", $headers));
113
114 1
        return $this;
115
    }
116
}
117