Passed
Pull Request — master (#2)
by Andreas
11:41
created

RestClient::getUri()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 6
c 2
b 0
f 1
dl 0
loc 11
ccs 6
cts 7
cp 0.8571
rs 10
cc 3
nc 4
nop 1
crap 3.0261
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Larium\Pay\Client;
6
7
use Http\Discovery\Psr17FactoryDiscovery;
8
use Http\Message\Authentication\BasicAuth;
9
use Psr\Http\Message\RequestInterface;
10
use Psr\Http\Message\ResponseInterface;
11
12
class RestClient extends AbstractClient
13
{
14
    private string $username;
15
16
    private string $pass;
17
18
    private array $headerAuthentication = [];
19
20 2
    public function __construct(
21
        private readonly string $baseUri,
22
        private readonly string $resource,
23
        private readonly array $headers = [],
24
        array $options = []
25
    ) {
26 2
        $this->options = $options;
27
    }
28
29
    public function addHeader(string $name, string $value): void
30
    {
31
        $this->headers[$name] = $value;
0 ignored issues
show
Bug introduced by
The property headers is declared read-only in Larium\Pay\Client\RestClient.
Loading history...
32
    }
33
34
    public function get(string $id = null, string|array $payload = null): array
35
    {
36
        $uri = $this->getUri($id);
37
        if ($query = $this->normalizePayload($payload)) {
0 ignored issues
show
Bug introduced by
It seems like $payload can also be of type null; however, parameter $payload of Larium\Pay\Client\RestClient::normalizePayload() does only seem to accept array|string, maybe add an additional type check? ( Ignorable by Annotation )

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

37
        if ($query = $this->normalizePayload(/** @scrutinizer ignore-type */ $payload)) {
Loading history...
38
            $uri = $uri . '?' . ltrim($query, '?');
39
        }
40
41
        return $this->request($uri, 'GET');
42
    }
43
44
    public function post(string|array $payload): array
45
    {
46
        return $this->request($this->getUri(), 'POST', $payload);
47
    }
48
49
    public function put(string $id, string|array $payload = null): array
50
    {
51
        $uri = $this->getUri($id);
52
53
        return $this->request($uri, 'PUT', $payload);
54
    }
55
56
    private function request(
57
        string $uri,
58
        string $method,
59
        string|array $payload = null
60
    ): array {
61
        $factory = Psr17FactoryDiscovery::findRequestFactory();
62
        $request = $factory->createRequest(
63
            $method,
64
            $uri
65
        );
66
67
        foreach ($this->headers as $name => $value) {
68
            $request = $request->withHeader($name, $value);
69
        }
70
71
        if ($payload !== null) {
72
            $stream = Psr17FactoryDiscovery::findStreamFactory()->createStream($payload);
0 ignored issues
show
Bug introduced by
$payload of type array is incompatible with the type string expected by parameter $content of Psr\Http\Message\StreamF...terface::createStream(). ( Ignorable by Annotation )

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

72
            $stream = Psr17FactoryDiscovery::findStreamFactory()->createStream(/** @scrutinizer ignore-type */ $payload);
Loading history...
73
            $request = $request->withBody($stream);
74
        }
75
76
        $request = $this->authenticate($request);
77
78
        return $this->resolveResponse($this->sendRequest($request));
79
    }
80
81
    public function delete(string $id): array
82
    {
83
        $uri = $this->getUri($id);
84
85
        return $this->request($uri, 'DELETE');
86
    }
87
88 2
    public function getUri(string $id = null): string
89
    {
90 2
        $uri = $this->resource
91 2
            ? sprintf('%s/%s', $this->baseUri, $this->resource)
92
            : $this->baseUri;
93
94 2
        if ($id) {
95 1
            $uri = sprintf($uri, $id);
96
        }
97
98 2
        return $uri;
99
    }
100
101
    public function setBasicAuthentication(
102
        string $username,
103
        string $password
104
    ): void {
105
        $this->username = $username;
106
        $this->pass = $password;
107
    }
108
109
    public function setHeaderAuthentication(string $name, string $value): void
110
    {
111
        $this->headerAuthentication = ['name' => $name, 'value' => $value];
112
    }
113
114
    protected function authenticate(RequestInterface $request): RequestInterface
115
    {
116
        if ($this->username || $this->pass) {
117
            $authentication = new BasicAuth($this->username, $this->pass);
118
119
            return $authentication->authenticate($request);
120
        }
121
122
        if (!empty($this->headerAuthentication)) {
123
            $request = $request->withHeader(
124
                $this->headerAuthentication['name'],
125
                $this->headerAuthentication['value']
126
            );
127
128
            return $request;
129
        }
130
131
        return $request;
132
    }
133
134
    private function normalizePayload(string|array $payload): string
135
    {
136
        if (is_array($payload)) {
0 ignored issues
show
introduced by
The condition is_array($payload) is always true.
Loading history...
137
            return http_build_query($payload);
138
        }
139
140
        return $payload;
141
    }
142
143
    /**
144
     * Resolve the response from client.
145
     *
146
     * @param ResponseInterface $response
147
     * @return array An array with following values:
148
     *              'status': The Http status of response
149
     *              'headers': An array of response headers
150
     *              'body': The json decoded body response. (Since we are in
151
     *              RestClient)
152
     *              'raw_response': The raw body response for logging purposes.
153
     *              'raw_request': The raw body request for logging purposes.
154
     */
155
    protected function resolveResponse(ResponseInterface $response): array
156
    {
157
        $body = $response->getBody()->__toString();
158
        $responseBody = json_decode($body, true) ?: [];
159
160
        return [
161
            'status' => $response->getStatusCode(),
162
            'headers' => $response->getHeaders(),
163
            'body' => $responseBody,
164
            'raw_response' => $body,
165
            'raw_request' => $this->rawRequest,
166
        ];
167
    }
168
}
169