Passed
Pull Request — master (#1)
by Gianluca
02:00
created

Client::handleRequestError()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 15
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
3
namespace ProposalPage\Sdk;
4
5
use Exception;
6
use GuzzleHttp\Client as HttpClient;
7
use ProposalPage\Sdk\Exception\FailedActionException;
8
use ProposalPage\Sdk\Exception\NotFoundException;
9
use ProposalPage\Sdk\Exception\ValidationException;
10
use Psr\Http\Message\ResponseInterface;
11
12
class Client
13
{
14
    private $apiUrl = 'https://api.proposalpage.com';
15
16
    private $token = null;
17
18
    private $httpClient;
19
20
    public function __construct(string $apiUrl = '')
21
    {
22
        if ($apiUrl) {
23
            $this->apiUrl = $apiUrl;
24
        }
25
26
        $this->httpClient = new HttpClient([
27
            'base_uri' => $this->getApiUrl(),
28
            'http_errors' => false,
29
            'timeout' => 30.0
30
        ]);
31
    }
32
33
    // Auth
34
    public function authenticate(string $username, string $password, bool $setToken = true)
35
    {
36
        $response = $this->request('POST', '/accounts/auth/token', [
37
            'username' => $username,
38
            'password' => $password
39
        ]);
40
41
        if ($setToken) {
42
            $this->token = $response->json['token'];
43
        }
44
45
        return $response;
46
    }
47
48
    public function authMe()
49
    {
50
        return $this->request('GET', '/accounts/auth/me');
51
    }
52
53
    // Templates
54
    public function listTemplates($page = 1, $itemsPerPage = 6)
55
    {
56
        return $this->request('GET', '/projects/templates', [], [
57
            'page' => $page,
58
            'itemsPerPage' => $itemsPerPage
59
        ]);
60
    }
61
62
    // Projects
63
    public function createProject(array $params)
64
    {
65
        return $this->request('POST', '/projects', $params);
66
    }
67
68
    public function createProjectFromTemplate(string $templateId)
69
    {
70
        return $this->request('POST', "/projects/${templateId}/copy");
71
    }
72
73
    public function listProjects($page = 1, $itemsPerPage = 6)
74
    {
75
        return $this->request('GET', '/projects', [], [
76
            'page' => $page,
77
            'itemsPerPage' => $itemsPerPage
78
        ]);
79
    }
80
81
    public function listProject($projectId)
82
    {
83
        return $this->request('GET', "/projects/{$projectId}");
84
    }
85
86
    public function updateProject($projectId, array $params)
87
    {
88
        return $this->request('PUT', "/projects/{$projectId}", $params);
89
    }
90
91
    public function deleteProject($projectId)
92
    {
93
        return $this->request('DELETE', "/projects/{$projectId}");
94
    }
95
96
    public function cloneProject($projectId)
97
    {
98
        return $this->request('POST', "/projects/{$projectId}/clone");
99
    }
100
101
    public function setProjectPassword($projectId, string $password)
102
    {
103
        return $this->request('POST', "/projects/{$projectId}/password", ['password' => $password]);
104
    }
105
106
    public function publishProject($projectId)
107
    {
108
        return $this->request('POST', "/projects/{$projectId}/publish");
109
    }
110
111
    public function secureProject($projectId)
112
    {
113
        return $this->request('POST', "/projects/{$projectId}/secure");
114
    }
115
116
    public function generateProjectCover($projectId)
117
    {
118
        return $this->request('GET', "/projects/{$projectId}/screenshot");
119
    }
120
121
    public function viewProjectAndNotify($projectId)
122
    {
123
        return $this->request('PUT', "/projects/{$projectId}/view-and-notify");
124
    }
125
126
    // Blocks
127
    public function createBlock($projectId, array $params)
128
    {
129
        return $this->request('POST', "/projects/{$projectId}/blocks", $params);
130
    }
131
132
    public function listBlocks($projectId)
133
    {
134
        return $this->request('GET', "/projects/{$projectId}/blocks");
135
    }
136
137
    public function listBlock($projectId, $blockId)
138
    {
139
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}");
140
    }
141
142
    public function updateBlock($projectId, $blockId, array $params)
143
    {
144
        return $this->request('PUT', "/projects/{$projectId}/blocks/{$blockId}", $params);
145
    }
146
147
    public function moveBlockForward($projectId, $blockId)
148
    {
149
        return $this->request('POST', "/projects/{$projectId}/blocks/{$blockId}/forward");
150
    }
151
152
    public function moveBlockBackward($projectId, $blockId)
153
    {
154
        return $this->request('POST', "/projects/{$projectId}/blocks/{$blockId}/backward");
155
    }
156
157
    public function cloneBlock($projectId, $blockId, string $position = '')
158
    {
159
        return $this->request('POST', "/projects/{$projectId}/blocks/{$blockId}/clone/{$position}");
160
    }
161
162
    public function deleteBlock($projectId, $blockId)
163
    {
164
        return $this->request('DELETE', "/projects/{$projectId}/blocks/{$blockId}");
165
    }
166
167
    // Rows
168
    public function createRow($projectId, $blockId, array $params)
169
    {
170
        return $this->request('POST', "/projects/{$projectId}/blocks/{$blockId}/rows", $params);
171
    }
172
173
    public function listRows($projectId, $blockId)
174
    {
175
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}/rows");
176
    }
177
178
    public function listRow($projectId, $blockId, $rowId)
179
    {
180
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}");
181
    }
182
183
    public function updateRow($projectId, $blockId, $rowId, $params)
184
    {
185
        return $this->request('PUT', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}", $params);
186
    }
187
188
    public function cloneRow($projectId, $blockId, $rowId, string $position = '')
189
    {
190
        return $this->request('POST', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/clone/${position}");
191
    }
192
193
    public function deleteRow($projectId, $blockId, $rowId)
194
    {
195
        return $this->request('DELETE', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}");
196
    }
197
198
    // Columns
199
    public function createColumn($projectId, $blockId, $rowId, array $params)
200
    {
201
        return $this->request('POST', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns", $params);
202
    }
203
204
    public function listColumns($projectId, $blockId, $rowId)
205
    {
206
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns");
207
    }
208
209
    public function listColumn($projectId, $blockId, $rowId, $columnId)
210
    {
211
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}");
212
    }
213
214
    public function updateColumn($projectId, $blockId, $rowId, $columnId, array $params)
215
    {
216
        return $this->request('PUT', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}", $params);
217
    }
218
219
    public function deleteColumn($projectId, $blockId, $rowId, $columnId)
220
    {
221
        return $this->request('DELETE', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}");
222
    }
223
224
    // Contents
225
    public function createContent($projectId, $blockId, $rowId, $columnId, array $params)
226
    {
227
        return $this->request(
228
            'POST',
229
            "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}/contents",
230
            $params
231
        );
232
    }
233
234
    public function listContents($projectId, $blockId, $rowId, $columnId)
235
    {
236
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}/contents");
237
    }
238
239
    public function listContent($projectId, $blockId, $rowId, $columnId, $contentId)
240
    {
241
        return $this->request('GET', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}/contents/{$contentId}");
242
    }
243
244
    public function updateContent($projectId, $blockId, $rowId, $columnId, $contentId, array $params)
245
    {
246
        return $this->request(
247
            'PUT',
248
            "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}/contents/{$contentId}",
249
            $params
250
        );
251
    }
252
253
    public function deleteContent($projectId, $blockId, $rowId, $columnId, $contentId)
254
    {
255
        return $this->request('DELETE', "/projects/{$projectId}/blocks/{$blockId}/rows/{$rowId}/columns/{$columnId}/contents/{$contentId}");
256
    }
257
258
    // Getters / Setters
259
    public function getApiUrl()
260
    {
261
        return $this->apiUrl;
262
    }
263
264
    public function setApiUrl(string $apiUrl)
265
    {
266
        $this->apiUrl = $apiUrl;
267
268
        return $this;
269
    }
270
271
    public function getToken()
272
    {
273
        return $this->token;
274
    }
275
276
    public function setToken(string $token)
277
    {
278
        $this->token = $token;
279
280
        return $this;
281
    }
282
283
    /**
284
     * @param string $method
285
     * @param string $path
286
     * @param array $params
287
     * @param array $queryStringParams
288
     * @return mixed|ResponseInterface
289
     * @throws FailedActionException
290
     * @throws NotFoundException
291
     * @throws ValidationException
292
     * @throws \GuzzleHttp\Exception\GuzzleException
293
     */
294
    private function request(string $method, string $path, array $params = [], array $queryStringParams = [])
295
    {
296
        $response = $this->httpClient->request($method, $path, [
297
            'json' => $params,
298
            'query' => $queryStringParams,
299
            'headers' => $this->getRequestHeaders()
300
        ]);
301
302
        if (! $this->isSuccessfulResponse($response)) {
303
            $this->handleRequestError($response);
304
        }
305
306
        $responseBody = (string) $response->getBody();
307
        $response->json = json_decode($responseBody, true) ?: $responseBody;
308
309
        return $response;
310
    }
311
312
    /**
313
     * @return array
314
     */
315
    private function getRequestHeaders()
316
    {
317
        if (!$this->token) {
318
            return [
319
                'Accept' => 'application/json',
320
                'Content-Type' => 'application/json',
321
            ];
322
        }
323
324
        return [
325
            'Authorization' => "Bearer {$this->token}",
326
            'Accept' => 'application/json',
327
            'Content-Type' => 'application/json',
328
        ];
329
    }
330
331
    private function isSuccessfulResponse($response)
332
    {
333
        if (! $response) {
334
            return false;
335
        }
336
337
        return (int) substr($response->getStatusCode(), 0, 1) === 2;
338
    }
339
340
    /**
341
     * @param ResponseInterface $response
342
     * @throws FailedActionException
343
     * @throws NotFoundException
344
     * @throws ValidationException
345
     * @throws Exception
346
     */
347
    private function handleRequestError(ResponseInterface $response)
348
    {
349
        if ($response->getStatusCode() === 422) {
350
            throw new ValidationException(json_decode((string) $response->getBody(), true));
351
        }
352
353
        if ($response->getStatusCode() === 404) {
354
            throw new NotFoundException();
355
        }
356
357
        if ($response->getStatusCode() === 400) {
358
            throw new FailedActionException((string) $response->getBody());
359
        }
360
361
        throw new Exception((string) $response->getBody());
362
    }
363
}
364