Passed
Push — develop ( a6f0fe...5308a3 )
by Daniel
24:47 queued 09:44
created

HttpTransporter::requestObject()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 15
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 28
rs 9.4555
1
<?php
2
3
declare(strict_types=1);
4
5
namespace InShore\Bookwhen\Transporters;
6
7
use Closure;
8
use JsonException;
9
use InShore\Bookwhen\Contracts\TransporterContract;
10
use InShore\Bookwhen\Exceptions\ErrorException;
11
use InShore\Bookwhen\Exceptions\TransporterException;
12
use InShore\Bookwhen\Exceptions\UnserializableResponse;
13
use InShore\Bookwhen\ValueObjects\Transporter\BaseUri;
14
use InShore\Bookwhen\ValueObjects\Transporter\Headers;
15
use InShore\Bookwhen\ValueObjects\Transporter\Payload;
16
use InShore\Bookwhen\ValueObjects\Transporter\QueryParams;
17
use Psr\Http\Client\ClientExceptionInterface;
18
use Psr\Http\Client\ClientInterface;
19
use Psr\Http\Message\ResponseInterface;
20
21
/**
22
 * @internal
23
 */
24
final class HttpTransporter implements TransporterContract
25
{
26
    /**
27
     * Creates a new Http Transporter instance.
28
     */
29
    public function __construct(
30
        private readonly ClientInterface $client,
31
        private readonly BaseUri $baseUri,
32
        private readonly Headers $headers,
33
        private readonly QueryParams $queryParams,
34
        private readonly Closure $streamHandler,
35
    ) {
36
        // ..
37
    }
38
39
    /**
40
     * {@inheritDoc}
41
     */
42
    public function requestObject(Payload $payload): array|string
43
    {
44
        $request = $payload->toRequest($this->baseUri, $this->headers, $this->queryParams);
45
46
        try {
47
            $response = $this->client->sendRequest($request);
48
        } catch (ClientExceptionInterface $clientException) {
49
            throw new TransporterException($clientException);
50
        }
51
52
        $contents = (string) $response->getBody();
53
54
        if ($response->getHeader('Content-Type')[0] === 'text/plain; charset=utf-8') {
55
            return $contents;
56
        }
57
58
        try {
59
            /** @var array{error?: array{message: string, type: string, code: string}} $response */
60
            $response = json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
61
        } catch (JsonException $jsonException) {
62
            throw new UnserializableResponse($jsonException);
63
        }
64
65
        if (isset($response['error'])) {
66
            throw new ErrorException($response['error']);
67
        }
68
69
        return $response;
70
    }
71
72
    /**
73
     * {@inheritDoc}
74
     */
75
    public function requestContent(Payload $payload): string
76
    {
77
        $request = $payload->toRequest($this->baseUri, $this->headers, $this->queryParams);
78
79
        try {
80
            $response = $this->client->sendRequest($request);
81
        } catch (ClientExceptionInterface $clientException) {
82
            throw new TransporterException($clientException);
83
        }
84
85
        $contents = $response->getBody()->getContents();
86
87
        try {
88
            /** @var array{error?: array{message: string, type: string, code: string}} $response */
89
            $response = json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
90
91
            if (isset($response['error'])) {
92
                throw new ErrorException($response['error']);
93
            }
94
        } catch (JsonException) {
95
            // ..
96
        }
97
98
        return $contents;
99
    }
100
101
    /**
102
     * {@inheritDoc}
103
     */
104
    public function requestStream(Payload $payload): ResponseInterface
105
    {
106
        $request = $payload->toRequest($this->baseUri, $this->headers, $this->queryParams);
107
108
        try {
109
            $response = ($this->streamHandler)($request);
110
        } catch (ClientExceptionInterface $clientException) {
111
            throw new TransporterException($clientException);
112
        }
113
114
        return $response;
115
    }
116
}
117