Passed
Pull Request — master (#72)
by Omid
22:21
created

AbstractApiClient::getVideoUploadUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
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 MovingImage\Client\VMPro\Collection\ChannelCollection;
8
use MovingImage\Client\VMPro\Collection\TranscodeCollection;
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\Thumbnail;
16
use MovingImage\Client\VMPro\Entity\UserInfo;
17
use MovingImage\Client\VMPro\Entity\Video;
18
use MovingImage\Client\VMPro\Entity\VideoDownloadUrl;
19
use MovingImage\Client\VMPro\Entity\VideoManager;
20
use MovingImage\Client\VMPro\Entity\VideoRequestParameters;
21
use MovingImage\Client\VMPro\Entity\VideosRequestParameters;
22
use MovingImage\Client\VMPro\Interfaces\ApiClientInterface;
23
use MovingImage\Client\VMPro\Util\ChannelTrait;
24
use MovingImage\Client\VMPro\Util\Logging\Traits\LoggerAwareTrait;
25
use MovingImage\Client\VMPro\Util\SearchEndpointTrait;
26
use MovingImage\Meta\Interfaces\ThumbnailInterface;
27
28
abstract class AbstractApiClient extends AbstractCoreApiClient implements ApiClientInterface
29
{
30
    use LoggerAwareTrait;
31
    use SearchEndpointTrait;
32
    use ChannelTrait;
33
34
    /**
35
     * @throws \Exception
36
     */
37
    public function getChannels(int $videoManagerId): Channel
38
    {
39
        $response = $this->makeRequest('GET', 'channels', [
40
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
41
        ]);
42
43
        $rootChannel = $this->deserialize($response->getBody()->getContents(), Channel::class);
44
        $rootChannel->setChildren($this->sortChannels($rootChannel->getChildren()));
45
46
        return $rootChannel;
47
    }
48
49
    /**
50
     * Since the VMPro API doesn't sort any more the returned channels, we have to do it on our side.
51
     *
52
     * @throws \Exception
53
     */
54
    protected function sortChannels(array $channels)
55
    {
56
        array_map(function ($channel) {
57
            $channel->setChildren($this->sortChannels($channel->getChildren()));
58
        }, $channels);
59
60
        uasort($channels, function ($a, $b) {
61
            return $a->getName() > $b->getName();
62
        });
63
64
        return $channels;
65
    }
66
67
    public function createVideo(
68
        int $videoManagerId,
69
        string $fileName,
70
        ?string $title = '',
71
        ?string $description = '',
72
        ?array $channels = [],
73
        ?string $group = null,
74
        ?array $keywords = [],
75
        ?bool $autoPublish = null
76
    ): string {
77
        $channel = implode(',', $channels);
78
        $response = $this->makeRequest('POST', 'videos', [
79
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
80
            'json' => $this->buildJsonParameters(
81
                compact('fileName'), // Required parameters
82
                compact('title', 'description', 'channel', 'group', 'keywords', 'autoPublish') // Optional parameters
83
            ),
84
        ]);
85
86
        $videoLocation = $response->getHeader('location')[0];
87
88
        $pieces = explode('/', $videoLocation);
89
90
        return end($pieces);
91
    }
92
93
    public function getVideos(int $videoManagerId, ?VideosRequestParameters $parameters = null): array
94
    {
95
        $options = [
96
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
97
        ];
98
99
        if ($parameters) {
100
            $query = http_build_query($parameters->getContainer(), null, '&', PHP_QUERY_RFC3986);
101
            $options['query'] = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
102
        }
103
104
        $response = $this->makeRequest('GET', 'videos', $options);
105
        $response = json_encode(json_decode($response->getBody()->getContents(), true)['videos']);
106
107
        return $this->deserialize($response, 'array<'.Video::class.'>');
108
    }
109
110
    public function getCount(int $videoManagerId, ?VideosRequestParameters $parameters = null): int
111
    {
112
        $options = [
113
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
114
        ];
115
116
        if ($parameters) {
117
            $query = http_build_query($parameters->getContainer(), null, '&', PHP_QUERY_RFC3986);
118
            $options['query'] = preg_replace('/%5B[0-9]+%5D/simU', '%5B%5D', $query);
119
        }
120
121
        $response = $this->makeRequest('GET', 'videos', $options);
122
123
        return json_decode($response->getBody()->getContents(), true)['total'];
124
    }
125
126
    public function getVideoUploadUrl(int $videoManagerId, string $videoId): string
127
    {
128
        $response = $this->makeRequest('GET', sprintf('videos/%s/url', $videoId), [
129
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
130
        ]);
131
132
        return $response->getHeader('location')[0];
133
    }
134
135
    public function updateVideo(
136
        int $videoManagerId,
137
        string $videoId,
138
        string $title,
139
        string $description,
140
        ?bool $autoPublish = null
141
    ): void {
142
        $this->makeRequest('PATCH', sprintf('videos/%s', $videoId), [
143
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
144
            'json' => $this->buildJsonParameters([], compact('title', 'description', 'autoPublish')),
145
        ]);
146
    }
147
148
    public function addVideoToChannel(int $videoManagerId, string $videoId, string $channelId): void
149
    {
150
        $this->makeRequest('POST', sprintf('channels/%s/videos/%s', $channelId, $videoId), [
151
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
152
        ]);
153
    }
154
155
    public function removeVideoFromChannel(int $videoManagerId, string $videoId, string $channelId): void
156
    {
157
        $this->makeRequest('DELETE', sprintf('channels/%s/videos/%s', $channelId, $videoId), [
158
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
159
        ]);
160
    }
161
162
    public function setCustomMetaData(int $videoManagerId, string $videoId, array $metadata): void
163
    {
164
        $this->makeRequest('PATCH', sprintf('videos/%s/metadata', $videoId), [
165
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
166
            'json' => $metadata,
167
        ]);
168
    }
169
170
    public function getEmbedCode(
171
        int $videoManagerId,
172
        string $videoId,
173
        string $playerDefinitionId,
174
        ?string $embedType = 'html'
175
    ): EmbedCode {
176
        $url = sprintf(
177
            'videos/%s/embed-codes?player_definition_id=%s&embed_type=%s',
178
            $videoId,
179
            $playerDefinitionId,
180
            $embedType
181
        );
182
183
        if ($this->cacheTtl) {
184
            $url = sprintf('%s&token_lifetime_in_seconds=%s', $url, $this->cacheTtl);
185
        }
186
187
        $response = $this->makeRequest('GET', $url, [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]);
188
189
        $data = \json_decode($response->getBody(), true);
190
        $embedCode = new EmbedCode();
191
        $embedCode->setCode($data['embedCode']);
192
193
        return $embedCode;
194
    }
195
196
    public function deleteVideo(int $videoManagerId, string $videoId): void
197
    {
198
        $this->makeRequest('DELETE', sprintf('videos/%s', $videoId), [
199
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
200
        ]);
201
    }
202
203
    public function getVideo(int $videoManagerId, string $videoId, ?VideoRequestParameters $parameters = null): Video
204
    {
205
        $options = [
206
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
207
        ];
208
209
        if ($parameters) {
210
            $options['query'] = $parameters->getContainer();
211
        }
212
213
        $response = $this->makeRequest(
214
            'GET',
215
            sprintf('videos/%s', $videoId),
216
            $options
217
        );
218
219
        return $this->deserialize($response->getBody()->getContents(), Video::class);
220
    }
221
222
    public function getAttachments(int $videoManagerId, string $videoId): array
223
    {
224
        $response = $this->makeRequest(
225
            'GET',
226
            sprintf('videos/%s/attachments', $videoId),
227
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
228
        );
229
230
        return $this->deserialize($response->getBody()->getContents(), 'array<'.Attachment::class.'>');
231
    }
232
233
    public function getChannelAttachments(int $videoManagerId, int $channelId): array
234
    {
235
        $response = $this->makeRequest(
236
            'GET',
237
            sprintf('channels/%s/attachments', $channelId),
238
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
239
        );
240
241
        return $this->deserialize($response->getBody()->getContents(), 'array<'.Attachment::class.'>');
242
    }
243
244
    public function getKeywords(int $videoManagerId, ?string $videoId): array
245
    {
246
        $uri = is_null($videoId)
247
            ? 'keyword/find'
248
            : sprintf('videos/%s/keywords', $videoId);
249
250
        $response = $this->makeRequest(
251
            'GET',
252
            $uri,
253
            [self::OPT_VIDEO_MANAGER_ID => $videoManagerId]
254
        );
255
256
        return $this->deserialize($response->getBody()->getContents(), 'array<'.Keyword::class.'>');
257
    }
258
259
    public function updateKeywords(int $videoManagerId, string $videoId, array $keywords): void
260
    {
261
        //remove all keywords
262
        foreach ($this->getKeywords($videoManagerId, $videoId) as $keyword) {
263
            $this->deleteKeyword($videoManagerId, $videoId, $keyword->getId());
264
        }
265
266
        //add new
267
        foreach ($keywords as $keyword) {
268
            $this->makeRequest('POST', sprintf('videos/%s/keywords', $videoId), [
269
                self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
270
                'json' => ['text' => $keyword],
271
            ]);
272
        }
273
    }
274
275
    public function deleteKeyword(int $videoManagerId, string $videoId, int $keywordId): void
276
    {
277
        $this->makeRequest('DELETE', sprintf('videos/%s/keywords/%s', $videoId, $keywordId), [
278
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
279
        ]);
280
    }
281
282
    public function searchVideos(
283
        int $videoManagerId,
284
        ?VideosRequestParameters $parameters = null,
285
        ?string $searchQuery = null
286
    ): VideoCollection {
287
        $options = $this->getRequestOptionsForSearchVideosEndpoint($videoManagerId, $parameters);
288
        if ($searchQuery) {
289
            $options['query'] = sprintf('(%s) AND (%s)', $options['query'], $searchQuery);
290
        }
291
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
292
        $response = $this->normalizeSearchVideosResponse($response->getBody()->getContents());
293
294
        return $this->deserialize($response, VideoCollection::class);
295
    }
296
297
    public function searchChannels(
298
        int $videoManagerId,
299
        ?ChannelsRequestParameters $parameters = null
300
    ): ChannelCollection {
301
        $options = $this->getRequestOptionsForSearchChannelsEndpoint($videoManagerId, $parameters);
302
        $response = $this->makeRequest('POST', 'search', ['json' => $options]);
303
        $response = $this->normalizeSearchChannelsResponse($response->getBody()->getContents());
304
        /** @var ChannelCollection $collection */
305
        $collection = $this->deserialize($response, ChannelCollection::class);
306
307
        //builds parent/children relations on all channels
308
        $channels = $this->setChannelRelations($collection->getChannels());
0 ignored issues
show
Documentation introduced by
$collection->getChannels() is of type array<integer,object<Mov...aces\ChannelInterface>>, but the function expects a array<integer,object<Mov...\VMPro\Entity\Channel>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
309
        $collection->setChannels($channels);
310
311
        return $collection;
312
    }
313
314
    public function getVideoManagers(): array
315
    {
316
        $response = $this->makeRequest('GET', '', []);
317
318
        return $this->deserialize($response->getBody()->getContents(), 'array<'.VideoManager::class.'>');
319
    }
320
321
    public function getVideoDownloadUrls(int $videoManagerId, string $videoId): array
322
    {
323
        $options = [
324
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
325
        ];
326
327
        $response = $this->makeRequest(
328
            'GET',
329
            sprintf('videos/%s/download-urls', $videoId),
330
            $options
331
        );
332
333
        return $this->deserialize($response->getBody()->getContents(), 'array<'.VideoDownloadUrl::class.'>');
334
    }
335
336
    public function createThumbnailByTimestamp(int $videoManagerId, string $videoId, int $timestamp): ?ThumbnailInterface
337
    {
338
        $options = [
339
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
340
        ];
341
342
        $response = $this->makeRequest(
343
            'POST',
344
            'videos/'.$videoId.'/thumbnails?timestamp='.$timestamp,
345
            $options
346
        );
347
348
        if (preg_match('/\/thumbnails\/([0-9]*)/', $response->getHeader('Location')[0], $match)) {
349
            return (new Thumbnail())->setId($match[1]);
350
        }
351
352
        return null;
353
    }
354
355
    public function getThumbnail(int $videoManagerId, string $videoId, int $thumbnailId): ?ThumbnailInterface
356
    {
357
        $options = [
358
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
359
        ];
360
361
        $response = $this->makeRequest(
362
            'GET',
363
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId.'/url',
364
            $options
365
        );
366
367
        $result = \json_decode($response->getBody()->getContents(), true);
368
369
        if (isset($result['downloadUrl'])) {
370
            return (new Thumbnail())
371
                ->setId($thumbnailId)
372
                ->setUrl($result['downloadUrl']);
373
        }
374
375
        return null;
376
    }
377
378
    public function updateThumbnail(int $videoManagerId, string $videoId, int $thumbnailId, bool $active): void
379
    {
380
        $options = [
381
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
382
            'json' => ['active' => $active],
383
        ];
384
385
        $this->makeRequest(
386
            'PATCH',
387
            'videos/'.$videoId.'/thumbnails/'.$thumbnailId,
388
            $options
389
        );
390
    }
391
392
    public function getUserInfo(string $token): UserInfo
393
    {
394
        $options = [
395
            'body' => json_encode(['jwt_id_token' => $token]),
396
            'headers' => [
397
                'Content-Type' => 'application/json',
398
            ],
399
        ];
400
401
        $response = $this->makeRequest('POST', 'corp-tube-admin/user-info', $options);
402
403
        /** @var UserInfo $userInfo */
404
        $userInfo = $this->deserialize($response->getBody()->getContents(), UserInfo::class);
405
406
        $userInfo->validate();
407
408
        return $userInfo;
409
    }
410
411
    public function getTranscodingStatus(int $videoManagerId, string $videoId): TranscodeCollection
412
    {
413
        $options = [
414
            self::OPT_VIDEO_MANAGER_ID => $videoManagerId,
415
        ];
416
417
        $response = $this->makeRequest(
418
            'GET',
419
            'videos/'.$videoId.'/transcoding-status',
420
            $options
421
        );
422
423
        $response = $this->normalizeSearchTranscodingStatusResponse($response->getBody()->getContents());
424
425
        return $this->deserialize($response, TranscodeCollection::class);
426
    }
427
}
428