Passed
Pull Request — master (#38)
by Dante
02:47 queued 53s
created

BEditaClient::deleteObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2022 Atlas Srl, ChannelWeb Srl, Chialab Srl
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 */
10
11
namespace BEdita\SDK;
12
13
/**
14
 * BEdita4 API Client class
15
 */
16
class BEditaClient extends BaseClient
17
{
18
    /**
19
     * Classic authentication via POST /auth using username and password
20
     *
21
     * @param string $username username
22
     * @param string $password password
23
     * @return array|null Response in array format
24
     */
25
    public function authenticate(string $username, string $password): ?array
26
    {
27
        $this->unsetAuthorization();
28
        $body = json_encode(compact('username', 'password'));
29
30
        return $this->post('/auth', $body, ['Content-Type' => 'application/json']);
31
    }
32
33
    /**
34
     * Send a GET request a list of resources or objects or a single resource or object
35
     *
36
     * @param string $path Endpoint URL path to invoke
37
     * @param array|null $query Optional query string
38
     * @param array|null $headers Headers
39
     * @return array|null Response in array format
40
     */
41
    public function get(string $path, ?array $query = null, ?array $headers = null): ?array
42
    {
43
        $this->sendRequestRetry('GET', $path, $query, $headers);
44
45
        return $this->getResponseBody();
46
    }
47
48
    /**
49
     * GET a list of resources or objects of a given type
50
     *
51
     * @param string $type Object type name
52
     * @param array|null $query Optional query string
53
     * @param array|null $headers Custom request headers
54
     * @return array|null Response in array format
55
     */
56
    public function getObjects(string $type = 'objects', ?array $query = null, ?array $headers = null): ?array
57
    {
58
        return $this->get(sprintf('/%s', $type), $query, $headers);
59
    }
60
61
    /**
62
     * GET a single object of a given type
63
     *
64
     * @param int|string $id Object id
65
     * @param string $type Object type name
66
     * @param array|null $query Optional query string
67
     * @param array|null $headers Custom request headers
68
     * @return array|null Response in array format
69
     */
70
    public function getObject($id, string $type = 'objects', ?array $query = null, ?array $headers = null): ?array
71
    {
72
        return $this->get(sprintf('/%s/%s', $type, $id), $query, $headers);
73
    }
74
75
    /**
76
     * Get a list of related resources or objects
77
     *
78
     * @param int|string $id Resource id or object uname/id
79
     * @param string $type Type name
80
     * @param string $relation Relation name
81
     * @param array|null $query Optional query string
82
     * @param array|null $headers Custom request headers
83
     * @return array|null Response in array format
84
     */
85
    public function getRelated($id, string $type, string $relation, ?array $query = null, ?array $headers = null): ?array
86
    {
87
        return $this->get(sprintf('/%s/%s/%s', $type, $id, $relation), $query, $headers);
88
    }
89
90
    /**
91
     * Add a list of related resources or objects
92
     *
93
     * @param int|string $id Resource id or object uname/id
94
     * @param string $type Type name
95
     * @param string $relation Relation name
96
     * @param array $data Related resources or objects to add, MUST contain id and type
97
     * @param array|null $headers Custom request headers
98
     * @return array|null Response in array format
99
     */
100
    public function addRelated($id, string $type, string $relation, array $data, ?array $headers = null): ?array
101
    {
102
        $body = compact('data');
103
104
        return $this->post(sprintf('/%s/%s/relationships/%s', $type, $id, $relation), json_encode($body), $headers);
105
    }
106
107
    /**
108
     * Remove a list of related resources or objects
109
     *
110
     * @param int|string $id Resource id or object uname/id
111
     * @param string $type Type name
112
     * @param string $relation Relation name
113
     * @param array $data Related resources or objects to remove from relation
114
     * @param array|null $headers Custom request headers
115
     * @return array|null Response in array format
116
     */
117
    public function removeRelated($id, string $type, string $relation, array $data, ?array $headers = null): ?array
118
    {
119
        $body = compact('data');
120
121
        return $this->delete(sprintf('/%s/%s/relationships/%s', $type, $id, $relation), json_encode($body), $headers);
122
    }
123
124
    /**
125
     * Replace a list of related resources or objects: previuosly related are removed and replaced with these.
126
     *
127
     * @param int|string $id Object id
128
     * @param string $type Object type name
129
     * @param string $relation Relation name
130
     * @param array $data Related resources or objects to insert
131
     * @param array|null $headers Custom request headers
132
     * @return array|null Response in array format
133
     */
134
    public function replaceRelated($id, string $type, string $relation, array $data, ?array $headers = null): ?array
135
    {
136
        $body = compact('data');
137
138
        return $this->patch(sprintf('/%s/%s/relationships/%s', $type, $id, $relation), json_encode($body), $headers);
139
    }
140
141
    /**
142
     * Create a new object or resource (POST) or modify an existing one (PATCH)
143
     *
144
     * @param string $type Object or resource type name
145
     * @param array $data Object or resource data to save
146
     * @param array|null $headers Custom request headers
147
     * @return array|null Response in array format
148
     */
149
    public function save(string $type, array $data, ?array $headers = null): ?array
150
    {
151
        $id = null;
152
        if (array_key_exists('id', $data)) {
153
            $id = $data['id'];
154
            unset($data['id']);
155
        }
156
157
        $body = [
158
            'data' => [
159
                'type' => $type,
160
                'attributes' => $data,
161
            ],
162
        ];
163
        if (!$id) {
164
            return $this->post(sprintf('/%s', $type), json_encode($body), $headers);
165
        }
166
        $body['data']['id'] = $id;
167
168
        return $this->patch(sprintf('/%s/%s', $type, $id), json_encode($body), $headers);
169
    }
170
171
    /**
172
     * [DEPRECATED] Create a new object (POST) or modify an existing one (PATCH)
173
     *
174
     * @param string $type Object type name
175
     * @param array $data Object data to save
176
     * @param array|null $headers Custom request headers
177
     * @return array|null Response in array format
178
     * @deprecated Use `save()` method instead
179
     * @codeCoverageIgnore
180
     */
181
    public function saveObject(string $type, array $data, ?array $headers = null): ?array
182
    {
183
        return $this->save($type, $data, $headers);
184
    }
185
186
    /**
187
     * Delete an object (DELETE) => move to trashcan.
188
     *
189
     * @param int|string $id Object id
190
     * @param string $type Object type name
191
     * @return array|null Response in array format
192
     */
193
    public function deleteObject($id, string $type): ?array
194
    {
195
        return $this->delete(sprintf('/%s/%s', $type, $id));
196
    }
197
198
    /**
199
     * Remove an object => permanently remove object from trashcan.
200
     *
201
     * @param int|string $id Object id
202
     * @return array|null Response in array format
203
     */
204
    public function remove($id): ?array
205
    {
206
        return $this->delete(sprintf('/trash/%s', $id));
207
    }
208
209
    /**
210
     * Upload file (POST)
211
     *
212
     * @param string $filename The file name
213
     * @param string $filepath File full path: could be on a local filesystem or a remote reachable URL
214
     * @param array|null $headers Custom request headers
215
     * @return array|null Response in array format
216
     * @throws BEditaClientException
217
     */
218
    public function upload(string $filename, string $filepath, ?array $headers = null): ?array
219
    {
220
        if (!file_exists($filepath)) {
221
            throw new BEditaClientException('File not found', 500);
222
        }
223
        $file = file_get_contents($filepath);
224
        if (!$file) {
225
            throw new BEditaClientException('File get contents failed', 500);
226
        }
227
        if (empty($headers['Content-Type'])) {
228
            $headers['Content-Type'] = mime_content_type($filepath);
229
        }
230
231
        return $this->post(sprintf('/streams/upload/%s', $filename), $file, $headers);
232
    }
233
234
    /**
235
     * Create media by type and body data and link it to a stream:
236
     *  - `POST /:type` with `$body` as payload, create media object
237
     *  - `PATCH /streams/:stream_id/relationships/object` modify stream adding relation to media
238
     *  - `GET /:type/:id` get media data
239
     *
240
     * @param string $streamId The stream identifier
241
     * @param string $type The type
242
     * @param array $body The body data
243
     * @return array|null Response in array format
244
     * @throws BEditaClientException
245
     */
246
    public function createMediaFromStream($streamId, string $type, array $body): ?array
247
    {
248
        $id = $this->createMedia($type, $body);
249
        $this->addStreamToMedia($streamId, $id, $type);
250
251
        return $this->getObject($id, $type);
252
    }
253
254
    /**
255
     * Create media.
256
     *
257
     * @param string $type The type
258
     * @param array $body The body
259
     * @return string
260
     * @throws BEditaClientException
261
     */
262
    public function createMedia(string $type, array $body): string
263
    {
264
        $response = $this->post(sprintf('/%s', $type), json_encode($body));
265
        if (empty($response)) {
266
            throw new BEditaClientException('Invalid response from POST ' . sprintf('/%s', $type));
267
        }
268
269
        return (string)$response['data']['id'];
270
    }
271
272
    /**
273
     * Add stream to media using patch /streams/%s/relationships/object.
274
     *
275
     * @param string $streamId The stream ID
276
     * @param string $id The object ID
277
     * @param string $type The type
278
     * @return void
279
     * @throws BEditaClientException
280
     */
281
    public function addStreamToMedia(string $streamId, string $id, string $type): void
282
    {
283
        $body = [
284
            'data' => [
285
                'id' => $id,
286
                'type' => $type,
287
            ],
288
        ];
289
        $response = $this->patch(sprintf('/streams/%s/relationships/object', $streamId), json_encode($body));
290
        if (empty($response)) {
291
            throw new BEditaClientException('Invalid response from PATCH ' . sprintf('/streams/%s/relationships/object', $id));
292
        }
293
    }
294
295
    /**
296
     * Thumbnail request using `GET /media/thumbs` endpoint
297
     *
298
     *  Usage:
299
     *          thumbs(123) => `GET /media/thumbs/123`
300
     *          thumbs(123, ['preset' => 'glide']) => `GET /media/thumbs/123&preset=glide`
301
     *          thumbs(null, ['ids' => '123,124,125']) => `GET /media/thumbs?ids=123,124,125`
302
     *          thumbs(null, ['ids' => '123,124,125', 'preset' => 'async']) => `GET /media/thumbs?ids=123,124,125&preset=async`
303
     *          thumbs(123, ['options' => ['w' => 100, 'h' => 80, 'fm' => 'jpg']]) => `GET /media/thumbs/123/options[w]=100&options[h]=80&options[fm]=jpg` (these options could be not available... just set in preset(s))
304
     *
305
     * @param int|null $id the media Id.
306
     * @param array $query The query params for thumbs call.
307
     * @return array|null Response in array format
308
     */
309
    public function thumbs($id = null, $query = []): ?array
310
    {
311
        if (empty($id) && empty($query['ids'])) {
312
            throw new BEditaClientException('Invalid empty id|ids for thumbs');
313
        }
314
        $endpoint = '/media/thumbs';
315
        if (!empty($id)) {
316
            $endpoint .= sprintf('/%d', $id);
317
        }
318
319
        return $this->get($endpoint, $query);
320
    }
321
322
    /**
323
     * Get JSON SCHEMA of a resource or object
324
     *
325
     * @param string $type Object or resource type name
326
     * @return array|null JSON SCHEMA in array format
327
     */
328
    public function schema(string $type): ?array
329
    {
330
        $h = ['Accept' => 'application/schema+json'];
331
332
        return $this->get(sprintf('/model/schema/%s', $type), null, $h);
333
    }
334
335
    /**
336
     * Get info of a relation (data, params) and get left/right object types
337
     *
338
     * @param string $name relation name
339
     * @return array|null relation data in array format
340
     */
341
    public function relationData(string $name): ?array
342
    {
343
        $query = [
344
            'include' => 'left_object_types,right_object_types',
345
        ];
346
347
        return $this->get(sprintf('/model/relations/%s', $name), $query);
348
    }
349
350
    /**
351
     * Restore object from trash
352
     *
353
     * @param int|string $id Object id
354
     * @param string $type Object type name
355
     * @return array|null Response in array format
356
     */
357
    public function restoreObject($id, string $type): ?array
358
    {
359
        $body = [
360
            'data' => [
361
                'id' => $id,
362
                'type' => $type,
363
            ],
364
        ];
365
366
        return $this->patch(sprintf('/%s/%s', 'trash', $id), json_encode($body));
367
    }
368
369
    /**
370
     * Send a PATCH request to modify a single resource or object
371
     *
372
     * @param string $path Endpoint URL path to invoke
373
     * @param mixed $body Request body
374
     * @param array|null $headers Custom request headers
375
     * @return array|null Response in array format
376
     */
377
    public function patch(string $path, $body, ?array $headers = null): ?array
378
    {
379
        $this->sendRequestRetry('PATCH', $path, null, $headers, $body);
380
381
        return $this->getResponseBody();
382
    }
383
384
    /**
385
     * Send a POST request for creating resources or objects or other operations like /auth
386
     *
387
     * @param string $path Endpoint URL path to invoke
388
     * @param mixed $body Request body
389
     * @param array|null $headers Custom request headers
390
     * @return array|null Response in array format
391
     */
392
    public function post(string $path, $body, ?array $headers = null): ?array
393
    {
394
        $this->sendRequestRetry('POST', $path, null, $headers, $body);
395
396
        return $this->getResponseBody();
397
    }
398
399
    /**
400
     * Send a DELETE request
401
     *
402
     * @param string $path Endpoint URL path to invoke.
403
     * @param mixed $body Request body
404
     * @param array|null $headers Custom request headers
405
     * @return array|null Response in array format.
406
     */
407
    public function delete(string $path, $body = null, ?array $headers = null): ?array
408
    {
409
        $this->sendRequestRetry('DELETE', $path, null, $headers, $body);
410
411
        return $this->getResponseBody();
412
    }
413
}
414