Test Setup Failed
Push — master ( 38d0ab...76b332 )
by Alexey
03:25
created

AbstractApi::checkResponse()   D

Complexity

Conditions 10
Paths 10

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
rs 4.8196
cc 10
eloc 18
nc 10
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 DTO objects
56
     *
57
     * @return array|object
58
     */
59
    public function getGetJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null)
60
    {
61
        return $this->serializer->deserialize(
62
            $this->getGetResponseBody($path, $parameters),
63
            $type,
64
            'json',
65
            $context
66
        );
67
    }
68
69
    /**
70
     * Make POST request and return DTO objects
71
     *
72
     * @return array|object
73
     */
74
    public function getPostJsonData(string $path, array $parameters = [], string $type, DeserializationContext $context = null)
75
    {
76
        return $this->serializer->deserialize(
77
            $this->getPostResponseBody($path, $parameters),
78
            $type,
79
            'json',
80
            $context
81
        );
82
    }
83
84
    /**
85
     * Make GET request and return response body
86
     */
87
    public function getGetResponseBody($path, array $parameters = []): StreamInterface
88
    {
89
        return $this->sendGetRequest($path, $parameters)->getBody();
90
    }
91
92
    /**
93
     * Make POST request and return response body
94
     */
95
    public function getPostResponseBody(string $path, array $parameters = []): StreamInterface
96
    {
97
        return $this->sendPostRequest($path, $parameters)->getBody();
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
        // @todo remove after fix
155
        // Temporary fix until @arts fixes this bug
156
        if ('{"error": "UserNotFound"}' === (string) $response->getBody()) {
157
            throw new NotFoundException($reason, $code);
158
        }
159
160
        switch ($code) {
161
            case SymfonyResponse::HTTP_UNAUTHORIZED:
162
                throw new UnauthorizedException($reason, $code);
163
            case SymfonyResponse::HTTP_FORBIDDEN:
164
                throw new ForbiddenException($reason, $code);
165
            case SymfonyResponse::HTTP_NOT_FOUND:
166
                throw new NotFoundException($reason, $code);
167
            case SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR:
168
            case SymfonyResponse::HTTP_NOT_IMPLEMENTED:
169
            case SymfonyResponse::HTTP_BAD_GATEWAY:
170
            case SymfonyResponse::HTTP_SERVICE_UNAVAILABLE:
171
            case SymfonyResponse::HTTP_GATEWAY_TIMEOUT:
172
                throw new ServerProblemException($reason, $code);
173
        }
174
    }
175
}
176