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