Completed
Push — master ( cecf3a...936e1d )
by
unknown
22:35
created

AbstractApiClient::getCorporateTubeMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 1
nc 1
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\CorporateTubeMetaData;
14
use MovingImage\Client\VMPro\Entity\EmbedCode;
15
use MovingImage\Client\VMPro\Entity\Keyword;
16
use MovingImage\Client\VMPro\Entity\Player;
17
use MovingImage\Client\VMPro\Entity\Thumbnail;
18
use MovingImage\Client\VMPro\Entity\Transcode;
19
use MovingImage\Client\VMPro\Entity\UserInfo;
20
use MovingImage\Client\VMPro\Entity\Video;
21
use MovingImage\Client\VMPro\Entity\VideoDownloadUrl;
22
use MovingImage\Client\VMPro\Entity\VideoManager;
23
use MovingImage\Client\VMPro\Entity\VideoRequestParameters;
24
use MovingImage\Client\VMPro\Entity\VideosRequestParameters;
25
use MovingImage\Client\VMPro\Interfaces\ApiClientInterface;
26
use MovingImage\Client\VMPro\Util\ChannelTrait;
27
use MovingImage\Client\VMPro\Util\Logging\Traits\LoggerAwareTrait;
28
use MovingImage\Client\VMPro\Util\SearchEndpointTrait;
29
use MovingImage\Meta\Interfaces\ThumbnailInterface;
30
31
abstract class AbstractApiClient extends AbstractCoreApiClient implements ApiClientInterface
32
{
33
    use LoggerAwareTrait;
34
    use SearchEndpointTrait;
35
    use ChannelTrait;
36
37
    /**
38
     * @throws \Exception
39
     */
40
    public function getChannels(int $videoManagerId): Channel
41
    {
42
        $response = $this->makeRequest('GET', 'channels', [
43
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
44
        ]);
45
46
        $rootChannel = $this->deserialize($response->getBody()->getContents(), Channel::class);
47
        $rootChannel->setChildren($this->sortChannels($rootChannel->getChildren()));
48
49
        return $rootChannel;
50
    }
51
52
    /**
53
     * Since the VMPro API doesn't sort any more the returned channels, we have to do it on our side.
54
     *
55
     * @throws \Exception
56
     */
57
    protected function sortChannels(ArrayCollection $channels)
58
    {
59
        $channels->map(function ($channel) {
60
            $channel->setChildren($this->sortChannels($channel->getChildren()));
61
        });
62
63
        $iterator = $channels->getIterator();
64
        $iterator->uasort(function ($a, $b) {
65
            /* @var Channel $a */
66
            /* @var Channel $b */
67
            return $a->getName() > $b->getName();
68
        });
69
70
        return new ArrayCollection(iterator_to_array($iterator));
71
    }
72
73
    public function createVideo(
74
        int $videoManagerId,
75
        string $fileName,
76
        ?string $title = '',
77
        ?string $description = '',
78
        ?int $channel = null,
79
        ?string $group = null,
80
        ?array $keywords = [],
81
        ?bool $autoPublish = null
82
    ): string {
83
        $response = $this->makeRequest('POST', 'videos', [
84
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
85
            'json' => $this->buildJsonParameters(
86
                compact('fileName'), // Required parameters
87
                compact('title', 'description', 'channel', 'group', 'keywords', 'autoPublish') // Optional parameters
88
            ),
89
        ]);
90
91
        $videoLocation = $response->getHeader('location')[0];
92
93
        $pieces = explode('/', $videoLocation);
94
95
        return end($pieces);
96
    }
97
98
    public function getVideos(int $videoManagerId, ?VideosRequestParameters $parameters = null): ArrayCollection
99
    {
100
        $options = [
101
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
102
        ];
103
104
        if ($parameters) {
105
            $query = http_build_query($parameters->getContainer(), '', '&', PHP_QUERY_RFC3986);
106
            $options['query'] = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
107
            $options['query'] = str_replace('channel_id%5B%5D', 'channel_id', $options['query']);
108
        }
109
110
        $response = $this->makeRequest('GET', 'videos', $options);
111
        $response = json_encode(json_decode($response->getBody()->getContents(), true)['videos']);
112
113
        return $this->deserialize($response, 'ArrayCollection<'.Video::class.'>');
114
    }
115
116
    public function getCount(int $videoManagerId, ?VideosRequestParameters $parameters = null): int
117
    {
118
        $options = [
119
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
120
        ];
121
122
        if ($parameters) {
123
            $query = http_build_query($parameters->getContainer(), '', '&', PHP_QUERY_RFC3986);
124
            $options['query'] = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
125
            $options['query'] = str_replace('channel_id%5B%5D', 'channel_id', $options['query']);
126
        }
127
128
        $response = $this->makeRequest('GET', 'videos', $options);
129
130
        return json_decode($response->getBody()->getContents(), true)['total'];
131
    }
132
133
    public function getVideoUploadUrl(int $videoManagerId, string $videoId): string
134
    {
135
        $response = $this->makeRequest('GET', sprintf('videos/%s/url', $videoId), [
136
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
137
        ]);
138
139
        return $response->getHeader('location')[0];
140
    }
141
142
    public function updateVideo(
143
        int $videoManagerId,
144
        string $videoId,
145
        string $title,
146
        string $description,
147
        ?bool $autoPublish = null
148
    ): void {
149
        $this->makeRequest('PATCH', sprintf('videos/%s', $videoId), [
150
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
151
            'json' => $this->buildJsonParameters([], compact('title', 'description', 'autoPublish')),
152
        ]);
153
    }
154
155
    public function addVideoToChannel(int $videoManagerId, string $videoId, int $channelId): void
156
    {
157
        $this->makeRequest('POST', sprintf('channels/%u/videos/%s', $channelId, $videoId), [
158
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
159
        ]);
160
    }
161
162
    public function removeVideoFromChannel(int $videoManagerId, string $videoId, int $channelId): void
163
    {
164
        $this->makeRequest('DELETE', sprintf('channels/%u/videos/%s', $channelId, $videoId), [
165
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
166
        ]);
167
    }
168
169
    public function setCustomMetaData(int $videoManagerId, string $videoId, array $metadata): void
170
    {
171
        $this->makeRequest('PATCH', sprintf('videos/%s/metadata', $videoId), [
172
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
173
            'json' => $metadata,
174
        ]);
175
    }
176
177
    public function getEmbedCode(
178
        int $videoManagerId,
179
        string $videoId,
180
        string $playerDefinitionId,
181
        string $embedType = 'html'
182
    ): EmbedCode {
183
        $url = sprintf(
184
            'videos/%s/embed-codes?player_definition_id=%s&embed_type=%s',
185
            $videoId,
186
            $playerDefinitionId,
187
            $embedType
188
        );
189
190
        if ($this->cacheTtl) {
191
            $url = sprintf('%s&token_lifetime_in_seconds=%s', $url, $this->cacheTtl);
192
        }
193
194
        $response = $this->makeRequest('GET', $url, [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]);
195
196
        $data = \json_decode($response->getBody()->getContents(), true);
197
        $embedCode = new EmbedCode();
198
        $embedCode->setCode($data['embedCode']);
199
200
        return $embedCode;
201
    }
202
203
    public function deleteVideo(int $videoManagerId, string $videoId): void
204
    {
205
        $this->makeRequest('DELETE', sprintf('videos/%s', $videoId), [
206
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
207
        ]);
208
    }
209
210
    public function getVideo(int $videoManagerId, string $videoId, ?VideoRequestParameters $parameters = null): Video
211
    {
212
        $options = [
213
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
214
        ];
215
216
        if ($parameters) {
217
            $options['query'] = $parameters->getContainer();
218
        }
219
220
        $response = $this->makeRequest(
221
            'GET',
222
            sprintf('videos/%s', $videoId),
223
            $options
224
        );
225
226
        return $this->deserialize($response->getBody()->getContents(), Video::class);
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232
    public function getAttachments(int $videoManagerId, string $videoId): ArrayCollection
233
    {
234
        $response = $this->makeRequest(
235
            'GET',
236
            sprintf('videos/%s/attachments', $videoId),
237
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
238
        );
239
240
        $response = $this->normalizeGetAttachmentsResponse($response->getBody()->getContents());
241
242
        return $this->deserialize($response, 'ArrayCollection<'.Attachment::class.'>');
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248
    public function getChannelAttachments(int $videoManagerId, int $channelId): ArrayCollection
249
    {
250
        $response = $this->makeRequest(
251
            'GET',
252
            sprintf('channels/%u/attachments', $channelId),
253
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
254
        );
255
256
        $response = $this->normalizeGetAttachmentsResponse($response->getBody()->getContents());
257
258
        return $this->deserialize($response, 'ArrayCollection<'.Attachment::class.'>');
259
    }
260
261
    /**
262
     * {@inheritdoc}
263
     */
264
    public function getKeywords(int $videoManagerId, ?string $videoId): ArrayCollection
265
    {
266
        $uri = is_null($videoId)
267
            ? 'keyword/find'
268
            : sprintf('videos/%s/keywords', $videoId);
269
270
        $response = $this->makeRequest(
271
            'GET',
272
            $uri,
273
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
274
        );
275
276
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.Keyword::class.'>');
277
    }
278
279
    public function updateKeywords(int $videoManagerId, string $videoId, array $keywords): void
280
    {
281
        //remove all keywords
282
        foreach ($this->getKeywords($videoManagerId, $videoId) as $keyword) {
283
            $this->deleteKeyword($videoManagerId, $videoId, $keyword->getId());
284
        }
285
286
        //add new
287
        foreach ($keywords as $keyword) {
288
            $this->makeRequest('POST', sprintf('videos/%s/keywords', $videoId), [
289
                self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
290
                'json' => ['text' => $keyword],
291
            ]);
292
        }
293
    }
294
295
    public function deleteKeyword(int $videoManagerId, string $videoId, int $keywordId): void
296
    {
297
        $this->makeRequest('DELETE', sprintf('videos/%s/keywords/%s', $videoId, $keywordId), [
298
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
299
        ]);
300
    }
301
302
    public function searchVideos(
303
        int $videoManagerId,
304
        ?VideosRequestParameters $parameters = null,
305
        ?string $searchQuery = null
306
    ): VideoCollection {
307
        $options = $this->getRequestOptionsForSearchVideosEndpoint($videoManagerId, $parameters);
308
        if ($searchQuery) {
309
            $options['query'] = sprintf('(%s) AND (%s)', $options['query'], $searchQuery);
310
        }
311
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
312
        $response = $this->normalizeSearchVideosResponse($response->getBody()->getContents());
313
314
        return $this->deserialize($response, VideoCollection::class);
315
    }
316
317
    public function searchChannels(
318
        int $videoManagerId,
319
        ?ChannelsRequestParameters $parameters = null
320
    ): ChannelCollection {
321
        $options = $this->getRequestOptionsForSearchChannelsEndpoint($videoManagerId, $parameters);
322
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
323
        $response = $this->normalizeSearchChannelsResponse($response->getBody()->getContents());
324
        /** @var ChannelCollection $collection */
325
        $collection = $this->deserialize($response, ChannelCollection::class);
326
327
        //builds parent/children relations on all channels
328
        $channels = $this->setChannelRelations($collection->getChannels());
329
        $collection->setChannels($channels);
330
331
        return $collection;
332
    }
333
334
    /**
335
     * {@inheritdoc}
336
     */
337
    public function getVideoManagers(): ArrayCollection
338
    {
339
        $response = $this->makeRequest('GET', '', []);
340
341
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.VideoManager::class.'>');
342
    }
343
344
    /**
345
     * {@inheritdoc}
346
     */
347
    public function getVideoDownloadUrls(int $videoManagerId, string $videoId): ArrayCollection
348
    {
349
        $options = [
350
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
351
        ];
352
353
        $response = $this->makeRequest(
354
            'GET',
355
            sprintf('videos/%s/download-urls', $videoId),
356
            $options
357
        );
358
359
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.VideoDownloadUrl::class.'>');
360
    }
361
362
    public function createThumbnailByTimestamp(int $videoManagerId, string $videoId, int $timestamp): ?ThumbnailInterface
363
    {
364
        $options = [
365
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
366
        ];
367
368
        $response = $this->makeRequest(
369
            'POST',
370
            'videos/'.$videoId.'/thumbnails?timestamp='.$timestamp,
371
            $options
372
        );
373
374
        if (preg_match('/\/thumbnails\/([0-9]*)/', $response->getHeader('Location')[0], $match)) {
375
            return (new Thumbnail())->setId(intval($match[1]));
376
        }
377
378
        return null;
379
    }
380
381
    public function getThumbnail(int $videoManagerId, string $videoId, int $thumbnailId): ?ThumbnailInterface
382
    {
383
        $options = [
384
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
385
        ];
386
387
        $response = $this->makeRequest(
388
            'GET',
389
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId.'/url',
390
            $options
391
        );
392
393
        $result = \json_decode($response->getBody()->getContents(), true);
394
395
        if (isset($result['downloadUrl'])) {
396
            return (new Thumbnail())
397
                ->setId($thumbnailId)
398
                ->setUrl($result['downloadUrl']);
399
        }
400
401
        return null;
402
    }
403
404
    public function updateThumbnail(int $videoManagerId, string $videoId, int $thumbnailId, bool $active): void
405
    {
406
        $options = [
407
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
408
            'json' => ['active' => $active],
409
        ];
410
411
        $this->makeRequest(
412
            'PATCH',
413
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId,
414
            $options
415
        );
416
    }
417
418
    public function getUserInfo(string $token): UserInfo
419
    {
420
        $options = [
421
            'body' => json_encode(['jwt_id_token' => $token]),
422
            'headers' => [
423
                'Content-Type' => 'application/json',
424
            ],
425
        ];
426
427
        $response = $this->makeRequest('POST', 'corp-tube-admin/user-info', $options);
428
429
        /** @var UserInfo $userInfo */
430
        $userInfo = $this->deserialize($response->getBody()->getContents(), UserInfo::class);
431
432
        $userInfo->validate();
433
434
        return $userInfo;
435
    }
436
437
    /**
438
     * {@inheritdoc}
439
     */
440
    public function getTranscodingStatus(int $videoManagerId, string $videoId): ArrayCollection
441
    {
442
        $options = [
443
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
444
        ];
445
446
        $response = $this->makeRequest(
447
            'GET',
448
            'videos/'.$videoId.'/transcoding-status',
449
            $options
450
        );
451
452
        $response = $response->getBody()->getContents();
453
454
        return $this->deserialize($response, 'ArrayCollection<'.Transcode::class.'>');
455
    }
456
457
    public function getPlayers(int $videoManagerId): ArrayCollection
458
    {
459
        $options = [self::OPT_VIDEO_MANAGER_ID => $videoManagerId];
460
461
        $response = $this->makeRequest(
462
            'GET',
463
            'players',
464
            $options
465
        );
466
467
        $response = $response->getBody()->getContents();
468
469
        return $this->deserialize($response, 'ArrayCollection<'.Player::class.'>');
470
    }
471
472
    public function getCorporateTubeMetadata(int $videoManagerId, string $videoId): CorporateTubeMetaData
473
    {
474
        $options = [
475
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
476
        ];
477
478
        $response = $this->makeRequest(
479
            'GET',
480
            'videos/'.$videoId.'/metadata/corporate-tube',
481
            $options
482
        );
483
484
        return $this->deserialize($response->getBody()->getContents(), CorporateTubeMetaData::class);
485
    }
486
487
    public function updateCorporateTubeMetadata(
488
        int $videoManagerId,
489
        string $videoId,
490
        CorporateTubeMetaData $corporateTubeMetaData
491
    ): void {
492
        $options = [
493
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
494
            'json' => [
495
                'uploadDate' => $corporateTubeMetaData->getUploadDate()->format('c'),
496
                'uploaderUserId' => $corporateTubeMetaData->getUploaderUserId(),
497
                'inChargeUserId' => $corporateTubeMetaData->getInChargeUserId(),
498
            ],
499
        ];
500
501
        $this->makeRequest(
502
            'PATCH',
503
            'videos/'.$videoId.'/metadata/corporate-tube',
504
            $options
505
        );
506
    }
507
}
508