Passed
Pull Request — master (#89)
by
unknown
22:08
created

AbstractApiClient::createVideo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 9.392
c 0
b 0
f 0
cc 1
nc 1
nop 9

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