Test Setup Failed
Push — master ( a816ec...1d88cc )
by Alexey
02:47
created

AbstractApi::checkResponse()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 7.756
c 0
b 0
f 0
cc 9
eloc 16
nc 9
nop 1
1
<?php
2
3
namespace Skobkin\Bundle\PointToolsBundle\Service\Api;
4
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Exception\TransferException;
7
use JMS\Serializer\DeserializationContext;
8
use JMS\Serializer\Serializer;
9
use Psr\Http\Message\ResponseInterface;
10
use Psr\Http\Message\StreamInterface;
11
use Psr\Log\LoggerInterface;
12
use Skobkin\Bundle\PointToolsBundle\Exception\Api\ForbiddenException;
13
use Skobkin\Bundle\PointToolsBundle\Exception\Api\NetworkException;
14
use Skobkin\Bundle\PointToolsBundle\Exception\Api\NotFoundException;
15
use Skobkin\Bundle\PointToolsBundle\Exception\Api\ServerProblemException;
16
use Skobkin\Bundle\PointToolsBundle\Exception\Api\UnauthorizedException;
17
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
18
19
class AbstractApi
20
{
21
    /**
22
     * @var ClientInterface HTTP-client from Guzzle
23
     */
24
    protected $client;
25
26
    /**
27
     * @var Serializer
28
     */
29
    protected $serializer;
30
31
    /**
32
     * @var LoggerInterface
33
     */
34
    protected $logger;
35
36
    /**
37
     * @var string Authentication token for API
38
     */
39
    protected $authToken;
40
41
    /**
42
     * @var string CSRF-token for API
43
     */
44
    protected $csRfToken;
45
46
47
    public function __construct(ClientInterface $httpClient, Serializer $serializer, LoggerInterface $logger)
48
    {
49
        $this->client = $httpClient;
50
        $this->serializer = $serializer;
51
        $this->logger = $logger;
52
    }
53
54
    /**
55
     * Make GET request and return response body
56
     */
57
    public function getGetResponseBody($path, array $parameters = []): StreamInterface
58
    {
59
        return $this->sendGetRequest($path, $parameters)->getBody();
60
    }
61
62
    /**
63
     * Make POST request and return response body
64
     */
65
    public function getPostResponseBody(string $path, array $parameters = []): StreamInterface
66
    {
67
        return $this->sendPostRequest($path, $parameters)->getBody();
68
    }
69
70
    /**
71
     * Make GET request and return DTO objects
72
     *
73
     * @return array|object
74
     */
75
    public function getGetJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null)
76
    {
77
        return $this->serializer->deserialize(
78
            $this->getGetResponseBody($path, $parameters),
79
            $type,
80
            'json',
81
            $context
82
        );
83
    }
84
85
    /**
86
     * Make POST request and return DTO objects
87
     *
88
     * @return array|object
89
     */
90
    public function getPostJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null)
91
    {
92
        return $this->serializer->deserialize(
93
            $this->getPostResponseBody($path, $parameters),
94
            $type,
95
            'json',
96
            $context
97
        );
98
    }
99
100
    /**
101
     * @param string $path Request path
102
     * @param array $parameters Key => Value array of query parameters
103
     *
104
     * @return ResponseInterface
105
     *
106
     * @throws NetworkException
107
     */
108
    private function sendGetRequest(string $path, array $parameters = []): ResponseInterface
109
    {
110
        $this->logger->debug('Sending GET request', ['path' => $path, 'parameters' => $parameters]);
111
112
        return $this->sendRequest('GET', $path, ['query' => $parameters]);
113
    }
114
115
    /**
116
     * @param string $path Request path
117
     * @param array $parameters Key => Value array of request data
118
     *
119
     * @return ResponseInterface
120
     *
121
     * @throws NetworkException
122
     */
123
    private function sendPostRequest(string $path, array $parameters = []): ResponseInterface
124
    {
125
        $this->logger->debug('Sending POST request', ['path' => $path, 'parameters' => $parameters]);
126
127
        return $this->sendRequest('POST', $path, ['form_params' => $parameters]);
128
    }
129
130
    private function sendRequest(string $method, string $path, array $parameters): ResponseInterface
131
    {
132
        try {
133
            $response = $this->client->request($method, $path, ['query' => $parameters]);
134
135
            $this->checkResponse($response);
136
137
            return $response;
138
        } catch (TransferException $e) {
139
            throw new NetworkException('Request error', $e->getCode(), $e);
140
        }
141
    }
142
143
    /**
144
     * @throws ForbiddenException
145
     * @throws NotFoundException
146
     * @throws ServerProblemException
147
     * @throws UnauthorizedException
148
     */
149
    private function checkResponse(ResponseInterface $response): void
150
    {
151
        $code = $response->getStatusCode();
152
        $reason = $response->getReasonPhrase();
153
154
        switch ($code) {
155
            case SymfonyResponse::HTTP_UNAUTHORIZED:
156
                throw new UnauthorizedException($reason, $code);
157
            case SymfonyResponse::HTTP_FORBIDDEN:
158
                throw new ForbiddenException($reason, $code);
159
            case SymfonyResponse::HTTP_NOT_FOUND:
160
                throw new NotFoundException($reason, $code);
161
            case SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR:
162
            case SymfonyResponse::HTTP_NOT_IMPLEMENTED:
163
            case SymfonyResponse::HTTP_BAD_GATEWAY:
164
            case SymfonyResponse::HTTP_SERVICE_UNAVAILABLE:
165
            case SymfonyResponse::HTTP_GATEWAY_TIMEOUT:
166
                throw new ServerProblemException($reason, $code);
167
        }
168
    }
169
}
170