Connection::post()   A
last analyzed

Complexity

Conditions 4
Paths 11

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 21
c 2
b 0
f 0
dl 0
loc 30
ccs 17
cts 17
cp 1
rs 9.584
cc 4
nc 11
nop 3
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SergeyNezbritskiy\NovaPoshta;
6
7
use GuzzleHttp\Client as HttpClient;
8
use GuzzleHttp\Exception\GuzzleException;
9
use GuzzleHttp\RequestOptions;
10
use GuzzleHttp\Utils;
11
use Psr\Http\Message\ResponseInterface;
12
13
/**
14
 * Class Connection
15
 */
16
class Connection
17
{
18
    private const API_URI = 'https://api.novaposhta.ua/v2.0/json/';
19
    private const ERROR_MSG_TEMPLATE = 'Connection to Nova Poshta API failed: %s';
20
    private string $apiKey;
21
    private HttpClient $client;
22
23
    /**
24
     * @param string $apiKey
25
     * @param HttpClient $client
26 7
     */
27
    public function __construct(string $apiKey, HttpClient $client)
28 7
    {
29 7
        $this->apiKey = $apiKey;
30
        $this->client = $client;
31
    }
32
33
    /**
34
     * @param string $model
35
     * @param string $method
36
     * @param array $params
37
     * @return array
38
     * @throws NovaPoshtaApiException
39 6
     * @SuppressWarnings(PHPMD.StaticAccess)
40
     */
41
    public function post(string $model, string $method, array $params = []): array
42 6
    {
43 6
        try {
44 6
            $request = array_filter([
45 6
                'apiKey' => $this->apiKey,
46 6
                'modelName' => $model,
47 6
                'calledMethod' => $method,
48 6
                'methodProperties' => $params
49 5
            ]);
50 1
            $response = $this->client->request('POST', self::API_URI, [
51
                RequestOptions::BODY => Utils::jsonEncode($request, JSON_UNESCAPED_UNICODE),
52
                RequestOptions::HEADERS => [
53 4
                    'content-type' => 'application/json',
54
                    'Accept' => 'application/json'
55 3
                ]
56 1
            ]);
57 1
            if ($response->getStatusCode() !== 200) {
58
                throw new NovaPoshtaApiException(sprintf(self::ERROR_MSG_TEMPLATE, $response->getReasonPhrase()));
59 2
            }
60 4
61 1
            $body = $this->getResponseBody($response);
62
63
            if ($body['success'] === false) {
64
                $error = $body['errors'][0] ?? $body['warnings'][0] ?? 'Unknown error';
65
                $errorCode = $body['errorCodes'][0] ?? $body['warningCodes'][0] ?? 0;
66
                throw new NovaPoshtaApiException(sprintf(self::ERROR_MSG_TEMPLATE, $error), (int)$errorCode);
67
            }
68
            return $body['data'];
69
        } catch (GuzzleException $e) {
70 4
            throw new NovaPoshtaApiException(sprintf(self::ERROR_MSG_TEMPLATE, $e->getMessage()), $e->getCode(), $e);
71
        }
72 4
    }
73 4
74 4
    /**
75 1
     * @param ResponseInterface $response
76
     * @return array
77 3
     * @throws NovaPoshtaApiException
78
     */
79
    private function getResponseBody(ResponseInterface $response): array
80
    {
81
        $content = $response->getBody()->getContents();
82
        $result = json_decode($content, true);
83
        if (empty($result)) {
84
            throw new NovaPoshtaApiException('Invalid response from Nova Poshta API');
85
        }
86
        return $result;
87
    }
88
}
89