Client::send()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Korobovn\CloudPayments\Client;
6
7
use GuzzleHttp\Psr7\Request;
8
use Tarampampam\Wrappers\Exceptions\JsonEncodeDecodeException;
9
use Tarampampam\Wrappers\Json;
10
use GuzzleHttp\ClientInterface as GuzzleHttpClientInterface;
11
use GuzzleHttp\Exception\RequestException;
12
use Korobovn\CloudPayments\Message\Request\RequestInterface;
13
use Psr\Http\Message\RequestInterface as PsrRequestInterface;
14
use Korobovn\CloudPayments\Message\Response\ResponseInterface;
15
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
16
use Korobovn\CloudPayments\Client\Exception\InvalidHttpResponseCodeException;
17
18
class Client implements ClientInterface
19
{
20
    /**
21
     * @var GuzzleHttpClientInterface
22
     */
23
    protected $http_client;
24
25
    /**
26
     * @var string
27
     */
28
    protected $public_id;
29
30
    /**
31
     * @var string
32
     */
33
    protected $api_secret;
34
35
    /**
36
     * @param GuzzleHttpClientInterface $http_client
37
     * @param string                    $public_id
38
     * @param string                    $api_secret
39
     */
40
    public function __construct(
41
        GuzzleHttpClientInterface $http_client,
42
        string $public_id,
43
        string $api_secret
44
    )
45
    {
46
        $this->http_client = $http_client;
47
        $this->public_id   = $public_id;
48
        $this->api_secret  = $api_secret;
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function send(RequestInterface $request): ResponseInterface
55
    {
56
        $psr_request  = new Request(
57
            $request->getMethod(),
58
            $request->getUrl(),
59
            $request->getHeaders(),
60
            $request->getBody()
61
        );
62
        $psr_response = $this->sendHttpRequest($psr_request);
63
        $raw_response = $this->decodeBody($psr_response->getBody()->getContents());
64
65
        return $request->getStrategy()->prepareRawResponse($raw_response);
66
    }
67
68
    /**
69
     * @param string $body
70
     *
71
     * @return array
72
     * @throws JsonEncodeDecodeException
73
     */
74
    protected function decodeBody(string $body): array
75
    {
76
        return (array) Json::decode($body, true);
77
    }
78
79
    /**
80
     * @param PsrRequestInterface $request
81
     *
82
     * @return PsrResponseInterface
83
     * @throws InvalidHttpResponseCodeException
84
     * @throws \InvalidArgumentException
85
     *
86
     */
87
    protected function sendHttpRequest(PsrRequestInterface $request): PsrResponseInterface
88
    {
89
        $request = $this->setAuthHeader($request);
90
91
        try {
92
            $psr_response = $this->http_client->send($request);
93
        } catch (RequestException $exception) {
94
            throw new InvalidHttpResponseCodeException($exception->getMessage(), $exception->getCode(), $exception);
95
        }
96
97
        if ($psr_response->getStatusCode() !== 200) {
98
            throw new InvalidHttpResponseCodeException(
99
                sprintf('Response code is %d: %s %s',
100
                    $psr_response->getStatusCode(),
101
                    $psr_response->getReasonPhrase(),
102
                    \strip_tags($psr_response->getBody()->getContents())
103
                ), $psr_response->getStatusCode()
104
            );
105
        }
106
107
        return $psr_response;
108
    }
109
110
    /**
111
     * @param PsrRequestInterface $request
112
     *
113
     * @return PsrRequestInterface
114
     */
115
    protected function setAuthHeader(PsrRequestInterface $request): PsrRequestInterface
116
    {
117
        /** @var PsrRequestInterface $request */
118
        $request = $request->withAddedHeader('Authorization', sprintf('Basic %s',
119
            base64_encode($this->public_id . ':' . $this->api_secret)));
120
121
        return $request;
122
    }
123
}
124