Completed
Push — master ( 788697...b102ff )
by David
02:32
created

HttpMethodsClient::createRequest()   B

Complexity

Conditions 9
Paths 6

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 35.8762

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 4
cts 13
cp 0.3076
rs 8.0555
c 0
b 0
f 0
cc 9
nc 6
nop 4
crap 35.8762
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Http\Client\Common;
6
7
use Http\Message\RequestFactory;
8
use Psr\Http\Client\ClientInterface;
9
use Psr\Http\Message\RequestFactoryInterface;
10
use Psr\Http\Message\RequestInterface;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Http\Message\StreamFactoryInterface;
13
use Psr\Http\Message\StreamInterface;
14
use Psr\Http\Message\UriInterface;
15
16
final class HttpMethodsClient implements HttpMethodsClientInterface
17
{
18
    /**
19
     * @var ClientInterface
20
     */
21
    private $httpClient;
22
23
    /**
24
     * @var RequestFactory|RequestFactoryInterface
25
     */
26
    private $requestFactory;
27
28
    /**
29
     * @var StreamFactoryInterface|null
30
     */
31
    private $streamFactory;
32
33
    /**
34
     * @param RequestFactory|RequestFactoryInterface $requestFactory
35
     */
36 8
    public function __construct(ClientInterface $httpClient, $requestFactory, StreamFactoryInterface $streamFactory = null)
37
    {
38 8
        if (!$requestFactory instanceof RequestFactory && !$requestFactory instanceof RequestFactoryInterface) {
39
            throw new \TypeError(
40
                sprintf('%s::__construct(): Argument #2 ($requestFactory) must be of type %s|%s, %s given', self::class, RequestFactory::class, RequestFactoryInterface::class, get_debug_type($requestFactory))
0 ignored issues
show
Unused Code introduced by
The call to TypeError::__construct() has too many arguments starting with sprintf('%s::__construct..._type($requestFactory)).

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
41
            );
42
        }
43
44 8
        if (!$requestFactory instanceof RequestFactory && null === $streamFactory) {
45
            @trigger_error(sprintf('Passing a %s without a %s to %s::__construct() is deprecated as of version 2.3 and will be disallowed in version 3.0. A stream factory is required to create a request with a non-empty string body.', RequestFactoryInterface::class, StreamFactoryInterface::class, self::class));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
46
        }
47
48 8
        $this->httpClient = $httpClient;
49 8
        $this->requestFactory = $requestFactory;
50 8
        $this->streamFactory = $streamFactory;
51 8
    }
52
53 1
    public function get($uri, array $headers = []): ResponseInterface
54
    {
55 1
        return $this->send('GET', $uri, $headers, null);
56
    }
57
58 1
    public function head($uri, array $headers = []): ResponseInterface
59
    {
60 1
        return $this->send('HEAD', $uri, $headers, null);
61
    }
62
63 1
    public function trace($uri, array $headers = []): ResponseInterface
64
    {
65 1
        return $this->send('TRACE', $uri, $headers, null);
66
    }
67
68 1
    public function post($uri, array $headers = [], $body = null): ResponseInterface
69
    {
70 1
        return $this->send('POST', $uri, $headers, $body);
71
    }
72
73 1
    public function put($uri, array $headers = [], $body = null): ResponseInterface
74
    {
75 1
        return $this->send('PUT', $uri, $headers, $body);
76
    }
77
78 1
    public function patch($uri, array $headers = [], $body = null): ResponseInterface
79
    {
80 1
        return $this->send('PATCH', $uri, $headers, $body);
81
    }
82
83 1
    public function delete($uri, array $headers = [], $body = null): ResponseInterface
84
    {
85 1
        return $this->send('DELETE', $uri, $headers, $body);
86
    }
87
88 1
    public function options($uri, array $headers = [], $body = null): ResponseInterface
89
    {
90 1
        return $this->send('OPTIONS', $uri, $headers, $body);
91
    }
92
93 8
    public function send(string $method, $uri, array $headers = [], $body = null): ResponseInterface
94
    {
95 8 View Code Duplication
        if (!is_string($uri) && !$uri instanceof UriInterface) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
            throw new \TypeError(
97
                sprintf('%s::send(): Argument #2 ($uri) must be of type string|%s, %s given', self::class, UriInterface::class, get_debug_type($uri))
0 ignored issues
show
Unused Code introduced by
The call to TypeError::__construct() has too many arguments starting with sprintf('%s::send(): Arg..., get_debug_type($uri)).

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
98
            );
99
        }
100
101 8 View Code Duplication
        if (!is_string($body) && !$body instanceof StreamInterface && null !== $body) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
            throw new \TypeError(
103
                sprintf('%s::send(): Argument #4 ($body) must be of type string|%s|null, %s given', self::class, StreamInterface::class, get_debug_type($body))
0 ignored issues
show
Unused Code introduced by
The call to TypeError::__construct() has too many arguments starting with sprintf('%s::send(): Arg... get_debug_type($body)).

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
104
            );
105
        }
106
107 8
        return $this->sendRequest(
108 8
            self::createRequest($method, $uri, $headers, $body)
109
        );
110
    }
111
112
    /**
113
     * @param string|UriInterface         $uri
114
     * @param string|StreamInterface|null $body
115
     */
116 8
    private function createRequest(string $method, $uri, array $headers = [], $body = null): RequestInterface
117
    {
118 8
        if ($this->requestFactory instanceof RequestFactory) {
119 8
            return $this->requestFactory->createRequest(
120 8
                $method,
121
                $uri,
122
                $headers,
123
                $body
124
            );
125
        }
126
127
        if (is_string($body) && '' !== $body && null === $this->streamFactory) {
128
            throw new \RuntimeException('Cannot create request: A stream factory is required to create a request with a non-empty string body.');
129
        }
130
131
        $request = $this->requestFactory->createRequest($method, $uri);
132
133
        foreach ($headers as $key => $value) {
134
            $request = $request->withHeader($key, $value);
135
        }
136
137
        if (null !== $body && '' !== $body) {
138
            $request = $request->withBody(
139
                is_string($body) ? $this->streamFactory->createStream($body) : $body
140
            );
141
        }
142
143
        return $request;
144
    }
145
146 8
    public function sendRequest(RequestInterface $request): ResponseInterface
147
    {
148 8
        return $this->httpClient->sendRequest($request);
149
    }
150
}
151