Completed
Pull Request — master (#82)
by
unknown
20:55
created

AbstractApiClient::getAttachments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MovingImage\Client\VMPro\ApiClient;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use MovingImage\Client\VMPro\Collection\ChannelCollection;
9
use MovingImage\Client\VMPro\Collection\VideoCollection;
10
use MovingImage\Client\VMPro\Entity\Attachment;
11
use MovingImage\Client\VMPro\Entity\Channel;
12
use MovingImage\Client\VMPro\Entity\ChannelsRequestParameters;
13
use MovingImage\Client\VMPro\Entity\EmbedCode;
14
use MovingImage\Client\VMPro\Entity\Keyword;
15
use MovingImage\Client\VMPro\Entity\Player;
16
use MovingImage\Client\VMPro\Entity\Thumbnail;
17
use MovingImage\Client\VMPro\Entity\Transcode;
18
use MovingImage\Client\VMPro\Entity\UserInfo;
19
use MovingImage\Client\VMPro\Entity\Video;
20
use MovingImage\Client\VMPro\Entity\VideoDownloadUrl;
21
use MovingImage\Client\VMPro\Entity\VideoManager;
22
use MovingImage\Client\VMPro\Entity\VideoRequestParameters;
23
use MovingImage\Client\VMPro\Entity\VideosRequestParameters;
24
use MovingImage\Client\VMPro\Interfaces\ApiClientInterface;
25
use MovingImage\Client\VMPro\Util\ChannelTrait;
26
use MovingImage\Client\VMPro\Util\Logging\Traits\LoggerAwareTrait;
27
use MovingImage\Client\VMPro\Util\SearchEndpointTrait;
28
use MovingImage\Meta\Interfaces\ThumbnailInterface;
29
30
abstract class AbstractApiClient extends AbstractCoreApiClient implements ApiClientInterface
31
{
32
    use LoggerAwareTrait;
33
    use SearchEndpointTrait;
34
    use ChannelTrait;
35
36
    /**
37
     * @throws \Exception
38
     */
39
    public function getChannels(int $videoManagerId): Channel
40
    {
41
        $response = $this->makeRequest('GET', 'channels', [
42
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
43
        ]);
44
45
        $rootChannel = $this->deserialize($response->getBody()->getContents(), Channel::class);
46
        $rootChannel->setChildren($this->sortChannels($rootChannel->getChildren()));
47
48
        return $rootChannel;
49
    }
50
51
    /**
52
     * Since the VMPro API doesn't sort any more the returned channels, we have to do it on our side.
53
     *
54
     * @throws \Exception
55
     */
56
    protected function sortChannels(ArrayCollection $channels)
57
    {
58
        $channels->map(function ($channel) {
59
            $channel->setChildren($this->sortChannels($channel->getChildren()));
60
        });
61
62
        $iterator = $channels->getIterator();
63
        $iterator->uasort(function ($a, $b) {
64
            /* @var Channel $a */
65
            /* @var Channel $b */
66
            return $a->getName() > $b->getName();
67
        });
68
69
        return new ArrayCollection(iterator_to_array($iterator));
70
    }
71
72
    public function createVideo(
73
        int $videoManagerId,
74
        string $fileName,
75
        ?string $title = '',
76
        ?string $description = '',
77
        ?int $channel = null,
78
        ?string $group = null,
79
        ?array $keywords = [],
80
        ?bool $autoPublish = null
81
    ): string {
82
        $response = $this->makeRequest('POST', 'videos', [
83
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
84
            'json' => $this->buildJsonParameters(
85
                compact('fileName'), // Required parameters
86
                compact('title', 'description', 'channel', 'group', 'keywords', 'autoPublish') // Optional parameters
87
            ),
88
        ]);
89
90
        $videoLocation = $response->getHeader('location')[0];
91
92
        $pieces = explode('/', $videoLocation);
93
94
        return end($pieces);
95
    }
96
97
    public function getVideos(int $videoManagerId, ?VideosRequestParameters $parameters = null): ArrayCollection
98
    {
99
        $options = [
100
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
101
        ];
102
103
        if ($parameters) {
104
            $query = http_build_query($parameters->getContainer(), '', '&', PHP_QUERY_RFC3986);
105
            $options['query'] = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
106
        }
107
108
        $response = $this->makeRequest('GET', 'videos', $options);
109
        $response = json_encode(json_decode($response->getBody()->getContents(), true)['videos']);
110
111
        return $this->deserialize($response, 'ArrayCollection<'.Video::class.'>');
112
    }
113
114
    public function getCount(int $videoManagerId, ?VideosRequestParameters $parameters = null): int
115
    {
116
        $options = [
117
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
118
        ];
119
120
        if ($parameters) {
121
            $query = http_build_query($parameters->getContainer(), '', '&', PHP_QUERY_RFC3986);
122
            $options['query'] = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
123
        }
124
125
        $response = $this->makeRequest('GET', 'videos', $options);
126
127
        return json_decode($response->getBody()->getContents(), true)['total'];
128
    }
129
130
    public function getVideoUploadUrl(int $videoManagerId, string $videoId): string
131
    {
132
        $response = $this->makeRequest('GET', sprintf('videos/%s/url', $videoId), [
133
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
134
        ]);
135
136
        return $response->getHeader('location')[0];
137
    }
138
139
    public function updateVideo(
140
        int $videoManagerId,
141
        string $videoId,
142
        string $title,
143
        string $description,
144
        ?bool $autoPublish = null
145
    ): void {
146
        $this->makeRequest('PATCH', sprintf('videos/%s', $videoId), [
147
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
148
            'json' => $this->buildJsonParameters([], compact('title', 'description', 'autoPublish')),
149
        ]);
150
    }
151
152
    public function addVideoToChannel(int $videoManagerId, string $videoId, int $channelId): void
153
    {
154
        $this->makeRequest('POST', sprintf('channels/%u/videos/%s', $channelId, $videoId), [
155
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
156
        ]);
157
    }
158
159
    public function removeVideoFromChannel(int $videoManagerId, string $videoId, int $channelId): void
160
    {
161
        $this->makeRequest('DELETE', sprintf('channels/%u/videos/%s', $channelId, $videoId), [
162
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
163
        ]);
164
    }
165
166
    public function setCustomMetaData(int $videoManagerId, string $videoId, array $metadata): void
167
    {
168
        $this->makeRequest('PATCH', sprintf('videos/%s/metadata', $videoId), [
169
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
170
            'json' => $metadata,
171
        ]);
172
    }
173
174
    public function getEmbedCode(
175
        int $videoManagerId,
176
        string $videoId,
177
        string $playerDefinitionId,
178
        string $embedType = 'html'
179
    ): EmbedCode {
180
        $url = sprintf(
181
            'videos/%s/embed-codes?player_definition_id=%s&embed_type=%s',
182
            $videoId,
183
            $playerDefinitionId,
184
            $embedType
185
        );
186
187
        if ($this->cacheTtl) {
188
            $url = sprintf('%s&token_lifetime_in_seconds=%s', $url, $this->cacheTtl);
189
        }
190
191
        $response = $this->makeRequest('GET', $url, [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]);
192
193
        $data = \json_decode($response->getBody()->getContents(), true);
194
        $embedCode = new EmbedCode();
195
        $embedCode->setCode($data['embedCode']);
196
197
        return $embedCode;
198
    }
199
200
    public function deleteVideo(int $videoManagerId, string $videoId): void
201
    {
202
        $this->makeRequest('DELETE', sprintf('videos/%s', $videoId), [
203
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
204
        ]);
205
    }
206
207
    public function getVideo(int $videoManagerId, string $videoId, ?VideoRequestParameters $parameters = null): Video
208
    {
209
        $options = [
210
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
211
        ];
212
213
        if ($parameters) {
214
            $options['query'] = $parameters->getContainer();
215
        }
216
217
        $response = $this->makeRequest(
218
            'GET',
219
            sprintf('videos/%s', $videoId),
220
            $options
221
        );
222
223
        return $this->deserialize($response->getBody()->getContents(), Video::class);
224
    }
225
226
    private function buildAttachment(array $data): ?Attachment
227
    {
228
        if (isset($data['data']['id'], $data['data']['fileName'], $data['data']['downloadUrl'], $data['data']['fileSize'], $data['type']['name'])) {
229
            $attachment = new Attachment();
230
            $attachment->setId($data['data']['id']);
231
            $attachment->setFileName($data['data']['fileName']);
232
            $attachment->setDownloadUrl($data['data']['downloadUrl']);
233
            $attachment->setFileSize($data['data']['fileSize']);
234
            $attachment->setType($data['type']['name']);
235
236
            return $attachment;
237
        }
238
239
        return null;
240
    }
241
242
    /**
243
     * {@inheritDoc}
244
     */
245
    public function getAttachments(int $videoManagerId, string $videoId): ArrayCollection
246
    {
247
        $response = $this->makeRequest(
248
            'GET',
249
            sprintf('videos/%s/attachments', $videoId),
250
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
251
        );
252
253
        $collection = new ArrayCollection();
254
255
        foreach (json_decode($response->getBody()->getContents(), true) as $row) {
256
            if ($attachment = $this->buildAttachment($row)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $attachment is correct as $this->buildAttachment($row) (which targets MovingImage\Client\VMPro...ient::buildAttachment()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
257
                $collection->add($attachment);
258
            }
259
        }
260
261
        return $collection;
262
    }
263
264
    /**
265
     * {@inheritDoc}
266
     */
267
    public function getChannelAttachments(int $videoManagerId, int $channelId): ArrayCollection
268
    {
269
        $response = $this->makeRequest(
270
            'GET',
271
            sprintf('channels/%u/attachments', $channelId),
272
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
273
        );
274
275
        $collection = new ArrayCollection();
276
277
        foreach (json_decode($response->getBody()->getContents(), true) as $row) {
278
            if ($attachment = $this->buildAttachment($row)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $attachment is correct as $this->buildAttachment($row) (which targets MovingImage\Client\VMPro...ient::buildAttachment()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
279
                $collection->add($attachment);
280
            }
281
        }
282
283
        return $collection;
284
    }
285
286
    /**
287
     * {@inheritDoc}
288
     */
289
    public function getKeywords(int $videoManagerId, ?string $videoId): ArrayCollection
290
    {
291
        $uri = is_null($videoId)
292
            ? 'keyword/find'
293
            : sprintf('videos/%s/keywords', $videoId);
294
295
        $response = $this->makeRequest(
296
            'GET',
297
            $uri,
298
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
299
        );
300
301
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.Keyword::class.'>');
302
    }
303
304
    public function updateKeywords(int $videoManagerId, string $videoId, array $keywords): void
305
    {
306
        //remove all keywords
307
        foreach ($this->getKeywords($videoManagerId, $videoId) as $keyword) {
308
            $this->deleteKeyword($videoManagerId, $videoId, $keyword->getId());
309
        }
310
311
        //add new
312
        foreach ($keywords as $keyword) {
313
            $this->makeRequest('POST', sprintf('videos/%s/keywords', $videoId), [
314
                self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
315
                'json' => ['text' => $keyword],
316
            ]);
317
        }
318
    }
319
320
    public function deleteKeyword(int $videoManagerId, string $videoId, int $keywordId): void
321
    {
322
        $this->makeRequest('DELETE', sprintf('videos/%s/keywords/%s', $videoId, $keywordId), [
323
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
324
        ]);
325
    }
326
327
    public function searchVideos(
328
        int $videoManagerId,
329
        ?VideosRequestParameters $parameters = null,
330
        ?string $searchQuery = null
331
    ): VideoCollection {
332
        $options = $this->getRequestOptionsForSearchVideosEndpoint($videoManagerId, $parameters);
333
        if ($searchQuery) {
334
            $options['query'] = sprintf('(%s) AND (%s)', $options['query'], $searchQuery);
335
        }
336
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
337
        $response = $this->normalizeSearchVideosResponse($response->getBody()->getContents());
338
339
        return $this->deserialize($response, VideoCollection::class);
340
    }
341
342
    public function searchChannels(
343
        int $videoManagerId,
344
        ?ChannelsRequestParameters $parameters = null
345
    ): ChannelCollection {
346
        $options = $this->getRequestOptionsForSearchChannelsEndpoint($videoManagerId, $parameters);
347
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
348
        $response = $this->normalizeSearchChannelsResponse($response->getBody()->getContents());
349
        /** @var ChannelCollection $collection */
350
        $collection = $this->deserialize($response, ChannelCollection::class);
351
352
        //builds parent/children relations on all channels
353
        $channels = $this->setChannelRelations($collection->getChannels());
354
        $collection->setChannels($channels);
355
356
        return $collection;
357
    }
358
359
    /**
360
     * {@inheritDoc}
361
     */
362
    public function getVideoManagers(): ArrayCollection
363
    {
364
        $response = $this->makeRequest('GET', '', []);
365
366
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.VideoManager::class.'>');
367
    }
368
369
    /**
370
     * {@inheritDoc}
371
     */
372
    public function getVideoDownloadUrls(int $videoManagerId, string $videoId): ArrayCollection
373
    {
374
        $options = [
375
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
376
        ];
377
378
        $response = $this->makeRequest(
379
            'GET',
380
            sprintf('videos/%s/download-urls', $videoId),
381
            $options
382
        );
383
384
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.VideoDownloadUrl::class.'>');
385
    }
386
387
    public function createThumbnailByTimestamp(int $videoManagerId, string $videoId, int $timestamp): ?ThumbnailInterface
388
    {
389
        $options = [
390
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
391
        ];
392
393
        $response = $this->makeRequest(
394
            'POST',
395
            'videos/'.$videoId.'/thumbnails?timestamp='.$timestamp,
396
            $options
397
        );
398
399
        if (preg_match('/\/thumbnails\/([0-9]*)/', $response->getHeader('Location')[0], $match)) {
400
            return (new Thumbnail())->setId(intval($match[1]));
401
        }
402
403
        return null;
404
    }
405
406
    public function getThumbnail(int $videoManagerId, string $videoId, int $thumbnailId): ?ThumbnailInterface
407
    {
408
        $options = [
409
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
410
        ];
411
412
        $response = $this->makeRequest(
413
            'GET',
414
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId.'/url',
415
            $options
416
        );
417
418
        $result = \json_decode($response->getBody()->getContents(), true);
419
420
        if (isset($result['downloadUrl'])) {
421
            return (new Thumbnail())
422
                ->setId($thumbnailId)
423
                ->setUrl($result['downloadUrl']);
424
        }
425
426
        return null;
427
    }
428
429
    public function updateThumbnail(int $videoManagerId, string $videoId, int $thumbnailId, bool $active): void
430
    {
431
        $options = [
432
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
433
            'json' => ['active' => $active],
434
        ];
435
436
        $this->makeRequest(
437
            'PATCH',
438
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId,
439
            $options
440
        );
441
    }
442
443
    public function getUserInfo(string $token): UserInfo
444
    {
445
        $options = [
446
            'body' => json_encode(['jwt_id_token' => $token]),
447
            'headers' => [
448
                'Content-Type' => 'application/json',
449
            ],
450
        ];
451
452
        $response = $this->makeRequest('POST', 'corp-tube-admin/user-info', $options);
453
454
        /** @var UserInfo $userInfo */
455
        $userInfo = $this->deserialize($response->getBody()->getContents(), UserInfo::class);
456
457
        $userInfo->validate();
458
459
        return $userInfo;
460
    }
461
462
    /**
463
     * {@inheritdoc}
464
     */
465
    public function getTranscodingStatus(int $videoManagerId, string $videoId): ArrayCollection
466
    {
467
        $options = [
468
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
469
        ];
470
471
        $response = $this->makeRequest(
472
            'GET',
473
            'videos/'.$videoId.'/transcoding-status',
474
            $options
475
        );
476
477
        $response = $response->getBody()->getContents();
478
479
        return $this->deserialize($response, 'ArrayCollection<'.Transcode::class.'>');
480
    }
481
482
    public function getPlayers(int $videoManagerId): ArrayCollection
483
    {
484
        $options = [self::OPT_VIDEO_MANAGER_ID => $videoManagerId];
485
486
        $response = $this->makeRequest(
487
            'GET',
488
            'players',
489
            $options
490
        );
491
492
        $response = $response->getBody()->getContents();
493
494
        return $this->deserialize($response, 'ArrayCollection<'.Player::class.'>');
495
    }
496
}
497