Passed
Push — master ( 974e99...dba8b5 )
by
unknown
01:09 queued 11s
created

AbstractApiClient::getPlayers()   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 1
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
    /**
227
     * {@inheritDoc}
228
     */
229
    public function getAttachments(int $videoManagerId, string $videoId): ArrayCollection
230
    {
231
        $response = $this->makeRequest(
232
            'GET',
233
            sprintf('videos/%s/attachments', $videoId),
234
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
235
        );
236
237
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.Attachment::class.'>');
238
    }
239
240
    /**
241
     * {@inheritDoc}
242
     */
243
    public function getChannelAttachments(int $videoManagerId, int $channelId): ArrayCollection
244
    {
245
        $response = $this->makeRequest(
246
            'GET',
247
            sprintf('channels/%u/attachments', $channelId),
248
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
249
        );
250
251
        $response = $this->normalizeGetChannelAttachmentsResponse($response->getBody()->getContents());
252
253
        return $this->deserialize($response, 'ArrayCollection<'.Attachment::class.'>');
254
    }
255
256
    /**
257
     * {@inheritDoc}
258
     */
259
    public function getKeywords(int $videoManagerId, ?string $videoId): ArrayCollection
260
    {
261
        $uri = is_null($videoId)
262
            ? 'keyword/find'
263
            : sprintf('videos/%s/keywords', $videoId);
264
265
        $response = $this->makeRequest(
266
            'GET',
267
            $uri,
268
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
269
        );
270
271
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.Keyword::class.'>');
272
    }
273
274
    public function updateKeywords(int $videoManagerId, string $videoId, array $keywords): void
275
    {
276
        //remove all keywords
277
        foreach ($this->getKeywords($videoManagerId, $videoId) as $keyword) {
278
            $this->deleteKeyword($videoManagerId, $videoId, $keyword->getId());
279
        }
280
281
        //add new
282
        foreach ($keywords as $keyword) {
283
            $this->makeRequest('POST', sprintf('videos/%s/keywords', $videoId), [
284
                self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
285
                'json' => ['text' => $keyword],
286
            ]);
287
        }
288
    }
289
290
    public function deleteKeyword(int $videoManagerId, string $videoId, int $keywordId): void
291
    {
292
        $this->makeRequest('DELETE', sprintf('videos/%s/keywords/%s', $videoId, $keywordId), [
293
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
294
        ]);
295
    }
296
297
    public function searchVideos(
298
        int $videoManagerId,
299
        ?VideosRequestParameters $parameters = null,
300
        ?string $searchQuery = null
301
    ): VideoCollection {
302
        $options = $this->getRequestOptionsForSearchVideosEndpoint($videoManagerId, $parameters);
303
        if ($searchQuery) {
304
            $options['query'] = sprintf('(%s) AND (%s)', $options['query'], $searchQuery);
305
        }
306
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
307
        $response = $this->normalizeSearchVideosResponse($response->getBody()->getContents());
308
309
        return $this->deserialize($response, VideoCollection::class);
310
    }
311
312
    public function searchChannels(
313
        int $videoManagerId,
314
        ?ChannelsRequestParameters $parameters = null
315
    ): ChannelCollection {
316
        $options = $this->getRequestOptionsForSearchChannelsEndpoint($videoManagerId, $parameters);
317
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
318
        $response = $this->normalizeSearchChannelsResponse($response->getBody()->getContents());
319
        /** @var ChannelCollection $collection */
320
        $collection = $this->deserialize($response, ChannelCollection::class);
321
322
        //builds parent/children relations on all channels
323
        $channels = $this->setChannelRelations($collection->getChannels());
324
        $collection->setChannels($channels);
325
326
        return $collection;
327
    }
328
329
    /**
330
     * {@inheritDoc}
331
     */
332
    public function getVideoManagers(): ArrayCollection
333
    {
334
        $response = $this->makeRequest('GET', '', []);
335
336
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.VideoManager::class.'>');
337
    }
338
339
    /**
340
     * {@inheritDoc}
341
     */
342
    public function getVideoDownloadUrls(int $videoManagerId, string $videoId): ArrayCollection
343
    {
344
        $options = [
345
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
346
        ];
347
348
        $response = $this->makeRequest(
349
            'GET',
350
            sprintf('videos/%s/download-urls', $videoId),
351
            $options
352
        );
353
354
        return $this->deserialize($response->getBody()->getContents(), 'ArrayCollection<'.VideoDownloadUrl::class.'>');
355
    }
356
357
    public function createThumbnailByTimestamp(int $videoManagerId, string $videoId, int $timestamp): ?ThumbnailInterface
358
    {
359
        $options = [
360
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
361
        ];
362
363
        $response = $this->makeRequest(
364
            'POST',
365
            'videos/'.$videoId.'/thumbnails?timestamp='.$timestamp,
366
            $options
367
        );
368
369
        if (preg_match('/\/thumbnails\/([0-9]*)/', $response->getHeader('Location')[0], $match)) {
370
            return (new Thumbnail())->setId(intval($match[1]));
371
        }
372
373
        return null;
374
    }
375
376
    public function getThumbnail(int $videoManagerId, string $videoId, int $thumbnailId): ?ThumbnailInterface
377
    {
378
        $options = [
379
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
380
        ];
381
382
        $response = $this->makeRequest(
383
            'GET',
384
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId.'/url',
385
            $options
386
        );
387
388
        $result = \json_decode($response->getBody()->getContents(), true);
389
390
        if (isset($result['downloadUrl'])) {
391
            return (new Thumbnail())
392
                ->setId($thumbnailId)
393
                ->setUrl($result['downloadUrl']);
394
        }
395
396
        return null;
397
    }
398
399
    public function updateThumbnail(int $videoManagerId, string $videoId, int $thumbnailId, bool $active): void
400
    {
401
        $options = [
402
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
403
            'json' => ['active' => $active],
404
        ];
405
406
        $this->makeRequest(
407
            'PATCH',
408
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId,
409
            $options
410
        );
411
    }
412
413
    public function getUserInfo(string $token): UserInfo
414
    {
415
        $options = [
416
            'body' => json_encode(['jwt_id_token' => $token]),
417
            'headers' => [
418
                'Content-Type' => 'application/json',
419
            ],
420
        ];
421
422
        $response = $this->makeRequest('POST', 'corp-tube-admin/user-info', $options);
423
424
        /** @var UserInfo $userInfo */
425
        $userInfo = $this->deserialize($response->getBody()->getContents(), UserInfo::class);
426
427
        $userInfo->validate();
428
429
        return $userInfo;
430
    }
431
432
    /**
433
     * {@inheritdoc}
434
     */
435
    public function getTranscodingStatus(int $videoManagerId, string $videoId): ArrayCollection
436
    {
437
        $options = [
438
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
439
        ];
440
441
        $response = $this->makeRequest(
442
            'GET',
443
            'videos/'.$videoId.'/transcoding-status',
444
            $options
445
        );
446
447
        $response = $response->getBody()->getContents();
448
449
        return $this->deserialize($response, 'ArrayCollection<'.Transcode::class.'>');
450
    }
451
452
    public function getPlayers(int $videoManagerId): ArrayCollection
453
    {
454
        $options = [self::OPT_VIDEO_MANAGER_ID => $videoManagerId];
455
456
        $response = $this->makeRequest(
457
            'GET',
458
            'players',
459
            $options
460
        );
461
462
        $response = $response->getBody()->getContents();
463
464
        return $this->deserialize($response, 'ArrayCollection<'.Player::class.'>');
465
    }
466
}
467