Passed
Push — master ( 10f591...07b5ce )
by
unknown
22:43
created

AbstractApiClient::createVideo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 9.424
c 0
b 0
f 0
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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