GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

BaseApi::execute()   A
last analyzed

Complexity

Conditions 6
Paths 23

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 28
rs 9.1111
cc 6
nc 23
nop 2
1
<?php
2
3
/**
4
 * Part of Dear package.
5
 *
6
 * @package Dear
7
 * @version 1.0
8
 * @author Umair Mahmood
9
 * @license MIT
10
 * @copyright Copyright (c) 2019 Umair Mahmood
11
 *
12
 */
13
14
namespace UmiMood\Dear\Api;
15
16
use GuzzleHttp\Client;
17
use GuzzleHttp\Exception\ClientException;
18
use GuzzleHttp\Exception\ServerException;
19
use UmiMood\Dear\Api\Contracts\DeleteMethodAllowed;
20
use UmiMood\Dear\Api\Contracts\PostMethodAllowed;
21
use UmiMood\Dear\Api\Contracts\PutMethodAllowed;
22
use UmiMood\Dear\Config;
23
use UmiMood\Dear\Exception\BadRequestException;
24
use UmiMood\Dear\Exception\DearApiException;
25
use UmiMood\Dear\Exception\ForbiddenRequestException;
26
use UmiMood\Dear\Exception\InternalServerErrorException;
27
use UmiMood\Dear\Exception\MethodNotAllowedException;
28
use UmiMood\Dear\Exception\NotFoundException;
29
use UmiMood\Dear\Exception\ServiceUnavailableException;
30
use UmiMood\Dear\Helper;
31
use UmiMood\Dear\RESTApi;
32
33
abstract class BaseApi implements RESTApi
34
{
35
    /**
36
     * Default limit
37
     */
38
    const LIMIT = 100;
39
    /**
40
     * Default page
41
     */
42
    const PAGE = 1;
43
44
    /**
45
     * HTTP request content type
46
     */
47
    const CONTENT_TYPE = 'application/json';
48
49
    /**
50
     * @var Config
51
     */
52
    protected $config;
53
54
    /**
55
     * BaseApi constructor.
56
     * @param $config
57
     */
58
    public function __construct(Config $config)
59
    {
60
        $this->config = $config;
61
    }
62
63
    /**
64
     * Provide endpoint's action name
65
     * @return string
66
     */
67
    abstract protected function getAction();
68
69
    /**
70
     * Represents the GUID column name
71
     * @var string
72
     */
73
    abstract protected function getGUID();
74
75
    /**
76
     * GUID column name for delete action
77
     * @return string
78
     */
79
    protected function deleteGUID()
80
    {
81
        return 'ID';
82
    }
83
84
    /**
85
     * Returns required headers
86
     * @return array
87
     */
88
    protected function getHeaders()
89
    {
90
        return [
91
            'Content-Type' => self::CONTENT_TYPE,
92
            'api-auth-accountid' => $this->config->getAccountId(),
93
            'api-auth-applicationkey' => $this->config->getApplicationKey()
94
        ];
95
    }
96
97
    /**
98
     * @return Client
99
     */
100
    protected function getClient()
101
    {
102
        $client = new Client([
103
            'base_uri' => $this->getBaseUrl()
104
        ]);
105
106
        return $client;
107
    }
108
109
    /**
110
     * @return string
111
     */
112
    final protected function getBaseUrl()
113
    {
114
        return 'https://inventory.dearsystems.com/ExternalApi/v2/';
115
    }
116
117
    final public function get($parameters = [])
118
    {
119
        return $this->execute('GET', Helper::prepareParameters($parameters));
120
    }
121
122
    final public function find($guid, $parameters = [])
123
    {
124
        $parameters[$this->getGUID()] = $guid;
125
        return $this->execute('GET', Helper::prepareParameters($parameters));
126
    }
127
128
    final public function create($parameters = [])
129
    {
130
        if (!$this instanceof PostMethodAllowed) {
131
            throw new MethodNotAllowedException('Method not allowed.');
132
        }
133
134
        return $this->execute('POST', $parameters);
135
    }
136
137
    final public function update($guid, $parameters = [])
138
    {
139
        if (!$this instanceof PutMethodAllowed) {
140
            throw new MethodNotAllowedException('Method not allowed.');
141
        }
142
143
        $parameters[$this->getGUID()] = $guid;
144
        return $this->execute('PUT', $parameters);
145
    }
146
147
    final public function delete($guid, $parameters = [])
148
    {
149
        if (!$this instanceof DeleteMethodAllowed) {
150
            throw new MethodNotAllowedException('Method not allowed.');
151
        }
152
153
        $parameters[$this->deleteGUID()] = $guid;
154
        return $this->execute('DELETE', Helper::prepareParameters($parameters));
155
    }
156
157
    /**
158
     * @param $httpMethod
159
     * @param array $parameters
160
     * @return array
161
     * @throws \GuzzleHttp\Exception\GuzzleException
162
     */
163
    protected function execute($httpMethod, array $parameters)
164
    {
165
        try {
166
            $requestParams = [
167
                'headers' => $this->getHeaders()
168
            ];
169
170
            if ($httpMethod == 'POST' || $httpMethod == 'PUT') {
171
                $requestParams['body'] = json_encode($parameters);
172
            } else {
173
                $requestParams['query'] = $parameters;
174
            }
175
176
            $response = $this->getClient()->request($httpMethod, $this->getAction(), $requestParams);
177
            return \GuzzleHttp\json_decode((string)$response->getBody(), true);
178
179
        } catch (ClientException $clientException) {
180
            return $this->handleClientException($clientException);
181
182
        } catch (ServerException $serverException) {
183
            if ($serverException->getResponse()->getStatusCode() === 503) {
184
                // API limit exceeded
185
                sleep(5);
186
187
                return $this->execute($httpMethod, $parameters);
188
            }
189
190
            return $this->handleServerException($serverException);
191
        }
192
    }
193
194
    /**
195
     * @param ClientException $e
196
     */
197
    protected function handleClientException(ClientException $e)
198
    {
199
        $response = $e->getResponse();
200
        switch ($response->getStatusCode()) {
201
            case 400:
202
                $exceptionClass = BadRequestException::class;
203
                break;
204
205
            case 403:
206
                $exceptionClass = ForbiddenRequestException::class;
207
                break;
208
209
            case 404:
210
                $exceptionClass = NotFoundException::class;
211
                break;
212
213
            case 405:
214
                $exceptionClass = MethodNotAllowedException::class;
215
                break;
216
217
            default:
218
                $exceptionClass = DearApiException::class;
219
                break;
220
        }
221
222
        $exceptionInstance = new $exceptionClass($e->getMessage());
223
        $exceptionInstance->setStatusCode($response->getStatusCode());
224
225
        throw $exceptionInstance;
226
    }
227
228
    /**
229
     * @param ServerException $e
230
     */
231
    protected function handleServerException(ServerException $e)
232
    {
233
        $response = $e->getResponse();
234
        switch ($response->getStatusCode()) {
235
236
237
            case 500:
238
                $exceptionClass = InternalServerErrorException::class;
239
                break;
240
241
            case 503:
242
                $exceptionClass = ServiceUnavailableException::class;
243
                break;
244
245
            default:
246
                $exceptionClass = DearApiException::class;
247
                break;
248
        }
249
250
        $exceptionInstance = new $exceptionClass($e->getMessage());
251
        $exceptionInstance->setStatusCode($response->getStatusCode());
252
253
        throw $exceptionInstance;
254
    }
255
}