Passed
Pull Request — master (#305)
by Tobias
02:01
created

ResponseBuilder::setBody()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Buzz\Message;
6
7
use Buzz\Exception\ClientException;
8
use Buzz\Exception\InvalidArgumentException;
9
use Http\Message\ResponseFactory as HTTPlugResponseFactory;
10
use Interop\Http\Factory\ResponseFactoryInterface as InteropResponseFactory;
11
use Psr\Http\Message\ResponseInterface;
12
13
/**
14
 * @author Tobias Nyholm <[email protected]>
15
 */
16
class ResponseBuilder
17
{
18
    /**
19
     * @var ResponseInterface
20
     */
21
    private $response;
22
23
    /**
24
     * @var null|resource
25
     */
26
    private $stream = null;
0 ignored issues
show
introduced by
The private property $stream is not used, and could be removed.
Loading history...
27
28
    /**
29
     * @var null|string
30
     */
31
    private $body = null;
0 ignored issues
show
introduced by
The private property $body is not used, and could be removed.
Loading history...
32
33
    private $protocolVersion;
0 ignored issues
show
introduced by
The private property $protocolVersion is not used, and could be removed.
Loading history...
34
    private $statusCode;
0 ignored issues
show
introduced by
The private property $statusCode is not used, and could be removed.
Loading history...
35
    private $reasonPhrase;
0 ignored issues
show
introduced by
The private property $reasonPhrase is not used, and could be removed.
Loading history...
36
    private $headers = [];
0 ignored issues
show
introduced by
The private property $headers is not used, and could be removed.
Loading history...
37
38
    /**
39
     * @param HTTPlugResponseFactory|InteropResponseFactory $responseFactory
40
     */
41
    public function __construct($responseFactory)
42
    {
43
        if (!$responseFactory instanceof HTTPlugResponseFactory && !$responseFactory instanceof InteropResponseFactory) {
0 ignored issues
show
introduced by
$responseFactory is always a sub-type of Interop\Http\Factory\ResponseFactoryInterface.
Loading history...
44
            throw new InvalidArgumentException('First parameter to ResponseBuilder must be a response factory');
45
        }
46
47
        $this->response = $responseFactory->createResponse();
48
    }
49
50
    public function setStatus(string $input): void
51
    {
52
        $parts = explode(' ', $input, 3);
53
        if (count($parts) < 2 || 0 !== strpos(strtolower($parts[0]), 'http/')) {
54
            throw new InvalidArgumentException(sprintf('"%s" is not a valid HTTP status line', $input));
55
        }
56
57
        $this->response = $this->response->withStatus((int) $parts[1]);
58
        $this->response = $this->response->withProtocolVersion((string) substr($parts[0], 5));
59
60
        if (isset($parts[2])) {
61
            $this->response = $this->response->getReasonPhrase($parts[2]);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->response->getReasonPhrase($parts[2]) of type string is incompatible with the declared type Psr\Http\Message\ResponseInterface of property $response.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Unused Code introduced by
The call to Psr\Http\Message\Respons...face::getReasonPhrase() has too many arguments starting with $parts[2]. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
            /** @scrutinizer ignore-call */ 
62
            $this->response = $this->response->getReasonPhrase($parts[2]);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
62
        }
63
    }
64
65
    /**
66
     * Add a single HTTP header line.
67
     *
68
     * @param string $input
69
     */
70
    public function addHeader(string $input): void
71
    {
72
        list($key, $value) = explode(':', $input, 2);
73
        $this->response = $this->response->withAddedHeader(trim($key), trim($value));
74
    }
75
76
    /**
77
     * Add HTTP headers. The input array is all the header lines from the HTTP message. Optionally including the
78
     * status line.
79
     *
80
     * @param array $headers
81
     */
82
    public function parseHttpHeaders(array $headers): void
83
    {
84
        $statusLine = array_shift($headers);
85
        try {
86
            $this->setStatus($statusLine);
87
        } catch (InvalidArgumentException $e) {
88
            array_unshift($headers, $statusLine);
89
        }
90
91
        foreach ($headers as $header) {
92
            $this->addHeader($header);
93
        }
94
    }
95
96
    /**
97
     * Add some content to the body. This function writes the $input to a stream.
98
     *
99
     * @param string $input
100
     *
101
     * @return int returns the number of bytes written
102
     */
103
    public function writeBody(string $input): int
104
    {
105
        return $this->response->getBody()->write($input);
106
    }
107
    
108
    public function getResponse(): ResponseInterface
109
    {
110
        $this->response->getBody()->rewind();
111
112
        return $this->response;
113
    }
114
}
115