GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Videos::cast()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 16
c 2
b 0
f 0
dl 0
loc 20
rs 9.7333
cc 2
nc 2
nop 1
1
<?php
2
3
namespace ApiVideo\Client\Api;
4
5
use ApiVideo\Client\Buzz\FormByteRangeUpload;
6
use ApiVideo\Client\Buzz\OAuthBrowser;
7
use ApiVideo\Client\Model\Video;
8
use ApiVideo\Client\Model\VideoStatus;
9
use Buzz\Exception\RequestException;
10
use Buzz\Message\Form\FormUpload;
11
use Buzz\Message\RequestInterface;
12
use DateTimeImmutable;
13
use Exception;
14
use InvalidArgumentException;
15
16
class Videos extends BaseApi
17
{
18
    /** @var int Upload chunk size in bytes */
19
    public $chunkSize; // 64 MiB;
20
21
    /** @var Captions */
22
    public $captions;
23
24
    public function __construct(OAuthBrowser $browser)
25
    {
26
        parent::__construct($browser);
27
28
        $this->chunkSize = 120 * 1024 * 1024;
29
    }
30
31
    /**
32
     * @param string $videoId
33
     * @return Video|null
34
     */
35
    public function get($videoId)
36
    {
37
        $response = $this->browser->get("/videos/$videoId");
38
        if (!$response->isSuccessful()) {
39
            $this->registerLastError($response);
40
41
            return null;
42
        }
43
44
        return $this->unmarshal($response);
45
    }
46
47
    /**
48
     * @param string $videoId
49
     * @return VideoStatus|null
50
     */
51
    public function getStatus($videoId)
52
    {
53
        $response = $this->browser->get("/videos/$videoId/status");
54
        if (!$response->isSuccessful()) {
55
            $this->registerLastError($response);
56
57
            return null;
58
        }
59
60
        return VideoStatus::fromArray(json_decode($response->getContent(), true));
61
    }
62
63
    /**
64
     * Incrementally iterate over a collection of elements.
65
     * By default the elements are returned in an array, unless you pass a
66
     * $callback which will be called for each instance of Video.
67
     * Available parameters:
68
     *   - currentPage (int)   current pagination page
69
     *   - pageSize    (int)   number of elements per page
70
     *   - videoIds    (array) videoIds to limit the search to
71
     *   - tags        (array)
72
     *   - metadata    (array)
73
     * If currentPage and pageSize are not given, the method iterates over all
74
     * pages of results and return an array containing all the results.
75
     *
76
     * @param array    $parameters
77
     * @param callable $callback
78
     * @return Video[]|null
79
     */
80
    public function search(array $parameters = array(), $callback = null)
81
    {
82
        $params                = $parameters;
83
        $currentPage           = isset($parameters['currentPage']) ? $parameters['currentPage'] : 1;
84
        $params['pageSize']    = isset($parameters['pageSize']) ? $parameters['pageSize'] : 100;
85
        $params['currentPage'] = $currentPage;
86
        $allVideos             = array();
87
88
        do {
89
            $response = $this->browser->get('/videos?'.http_build_query($params));
90
91
            if (!$response->isSuccessful()) {
92
                $this->registerLastError($response);
93
94
                return null;
95
            }
96
97
            $json   = json_decode($response->getContent(), true);
98
            $videos = $json['data'];
99
100
            $allVideos[] = $this->castAll($videos);
101
            if (null !== $callback) {
102
                foreach (current($allVideos) as $video) {
103
                    call_user_func($callback, $video);
104
                }
105
            }
106
107
            if (isset($parameters['currentPage'])) {
108
                break;
109
            }
110
111
            $pagination = $json['pagination'];
112
            $pagination['currentPage']++;
113
            $params['currentPage'] = $pagination['currentPage'];
114
        } while ($pagination['pagesTotal'] >= $pagination['currentPage']);
115
        $allVideos = call_user_func_array('array_merge', $allVideos);
116
117
        if (null === $callback) {
118
            return $allVideos;
119
        }
120
121
        return null;
122
    }
123
124
    /**
125
     * @param string $title
126
     * @param array  $properties
127
     * @return Video|null
128
     */
129
    public function create($title, array $properties = array())
130
    {
131
        $response = $this->browser->post(
132
            '/videos',
133
            array(),
134
            json_encode(
135
                array_merge(
136
                    $properties,
137
                    array('title' => $title)
138
                )
139
            )
140
        );
141
        if (!$response->isSuccessful()) {
142
            $this->registerLastError($response);
143
144
            return null;
145
        }
146
147
        return $this->unmarshal($response);
148
    }
149
150
    public function download($source, $title, array $properties = array())
151
    {
152
        $properties['source'] = $source;
153
154
        return $this->create($title, $properties);
155
    }
156
157
    /**
158
     * @param string $source Path to the file to upload
159
     * @param array  $properties
160
     * @param string $videoId
161
     * @return Video|null
162
     * @throws RequestException
163
     * @throws InvalidArgumentException
164
     */
165
    public function upload($source, array $properties = array(), $videoId = null)
166
    {
167
        $timeout = $this->browser->getClient()->getTimeout();
0 ignored issues
show
Bug introduced by
The method getTimeout() does not exist on Buzz\Client\ClientInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Buzz\Client\BatchClientInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

167
        $timeout = $this->browser->getClient()->/** @scrutinizer ignore-call */ getTimeout();
Loading history...
168
        // Set unlimited timeout for video uploads
169
        $this->browser->getClient()->setTimeout(0);
0 ignored issues
show
Bug introduced by
The method setTimeout() does not exist on Buzz\Client\ClientInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Buzz\Client\BatchClientInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

169
        $this->browser->getClient()->/** @scrutinizer ignore-call */ setTimeout(0);
Loading history...
170
171
        if (!is_readable($source)) {
172
            throw new InvalidArgumentException('The source file must be readable.');
173
        }
174
175
        if ($videoId === null) {
176
            if (!isset($properties['title'])) {
177
                $properties['title'] = basename($source);
178
            }
179
180
            $videoId = $this->create($properties['title'], $properties)->videoId;
181
        }
182
183
        $resource = fopen($source, 'rb');
184
185
        $stats  = fstat($resource);
186
        $length = $stats['size'];
187
        if (0 >= $length) {
188
            throw new InvalidArgumentException("'$source' is an empty file.");
189
        }
190
        // Complete upload in a single request when file is small enough
191
        if ($this->chunkSize > $length) {
192
            $response = $this->browser->submit(
193
                "/videos/$videoId/source",
194
                array('file' => new FormUpload($source))
195
            );
196
197
            if (!$response->isSuccessful()) {
198
                $this->registerLastError($response);
199
200
                return null;
201
            }
202
203
            return $this->unmarshal($response);
204
        }
205
206
        // Split content to upload big files in multiple requests
207
        $copiedBytes = 0;
208
        stream_set_chunk_size($resource, $this->chunkSize);
209
        $lastResponse = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $lastResponse is dead and can be removed.
Loading history...
210
        do {
211
            $chunkPath   = tempnam(sys_get_temp_dir(), 'upload-chunk-');
212
            $chunk       = fopen($chunkPath, 'w+b');
213
            $from        = $copiedBytes;
214
            $copiedBytes += stream_copy_to_stream($resource, $chunk, $this->chunkSize, $copiedBytes);
215
216
            $response = $this->browser->submit(
217
                "/videos/$videoId/source",
218
                array('file' => new FormByteRangeUpload($chunkPath, $from, $copiedBytes, $length)),
219
                RequestInterface::METHOD_POST,
220
                array(
221
                    'Content-Range' => 'bytes '.$from.'-'.($copiedBytes - 1).'/'.$length,
222
                )
223
            );
224
225
            if ($response->getStatusCode() >= 400) {
226
                $this->registerLastError($response);
227
228
                return null;
229
            }
230
231
            $lastResponse = $response;
232
233
            fclose($chunk);
234
            unlink($chunkPath);
235
236
        } while ($copiedBytes < $length);
237
238
        fclose($resource);
239
240
        if (null !== $lastResponse) {
241
            $lastResponse = $this->unmarshal($lastResponse);
242
        }
243
244
        $this->browser->getClient()->setTimeout($timeout);
245
246
        return $lastResponse;
247
    }
248
249
    /**
250
     * @param string $source Path to the file to upload
251
     * @param string $videoId
252
     * @return Video|null
253
     * @throws RequestException
254
     * @throws InvalidArgumentException
255
     */
256
    public function uploadThumbnail($source, $videoId)
257
    {
258
        if (!is_readable($source)) {
259
            throw new InvalidArgumentException('The source file must be readable.');
260
        }
261
262
        $resource = fopen($source, 'rb');
263
264
        $stats  = fstat($resource);
265
        $length = $stats['size'];
266
        if (0 >= $length) {
267
            throw new InvalidArgumentException("'$source' is an empty file.");
268
        }
269
270
        $response = $this->browser->submit(
271
            "/videos/$videoId/thumbnail",
272
            array('file' => new FormUpload($source))
273
        );
274
275
        if (!$response->isSuccessful()) {
276
            $this->registerLastError($response);
277
278
            return null;
279
        }
280
281
        return $this->unmarshal($response);
282
    }
283
284
    /**
285
     * @param string $videoId
286
     * @param array  $properties
287
     * @return Video|null
288
     */
289
    public function update($videoId, array $properties)
290
    {
291
        $response = $this->browser->patch(
292
            "/videos/$videoId",
293
            array(),
294
            json_encode($properties)
295
        );
296
297
        if (!$response->isSuccessful()) {
298
            $this->registerLastError($response);
299
300
            return null;
301
        }
302
303
        return $this->unmarshal($response);
304
    }
305
306
    /**
307
     * @param string $videoId
308
     * @return Video|null
309
     */
310
    public function setPublic($videoId)
311
    {
312
        $response = $this->browser->patch(
313
            "/videos/$videoId",
314
            array(),
315
            json_encode(array('public' => true))
316
        );
317
318
        if (!$response->isSuccessful()) {
319
            $this->registerLastError($response);
320
321
            return null;
322
        }
323
324
        return $this->unmarshal($response);
325
    }
326
327
    /**
328
     * @param string $videoId
329
     * @return Video|null
330
     */
331
    public function setPrivate($videoId)
332
    {
333
        $response = $this->browser->patch(
334
            "/videos/$videoId",
335
            array(),
336
            json_encode(array('public' => false))
337
        );
338
339
        if (!$response->isSuccessful()) {
340
            $this->registerLastError($response);
341
342
            return null;
343
        }
344
345
        return $this->unmarshal($response);
346
    }
347
348
    /**
349
     * @param string $videoId
350
     * @param string $timecode
351
     * @return Video|null
352
     */
353
    public function updateThumbnailWithTimeCode($videoId, $timecode)
354
    {
355
        if (empty($timecode)) {
356
            throw new InvalidArgumentException('Timecode is an empty file.');
357
        }
358
359
        $response = $this->browser->patch(
360
            "/videos/$videoId/thumbnail",
361
            array(),
362
            json_encode(array('timecode' => $timecode))
363
        );
364
365
        if (!$response->isSuccessful()) {
366
            $this->registerLastError($response);
367
368
            return null;
369
        }
370
371
        return $this->unmarshal($response);
372
    }
373
374
    /**
375
     * @param string $videoId
376
     * @return int|null
377
     */
378
    public function delete($videoId)
379
    {
380
        $response = $this->browser->delete("/videos/$videoId");
381
382
        if (!$response->isSuccessful()) {
383
            $this->registerLastError($response);
384
385
            return null;
386
        }
387
388
        return $response->getStatusCode();
389
    }
390
391
    /**
392
     * @param array $data
393
     * @return Video
394
     * @throws Exception
395
     */
396
    protected function cast(array $data)
397
    {
398
        $video              = new Video;
399
        $video->videoId     = $data['videoId'];
400
        $video->title       = $data['title'];
401
        $video->description = $data['description'];
402
        $video->public      = $data['public'];
403
        $video->tags        = $data['tags'];
404
        $video->metadata    = $data['metadata'];
405
        $video->source      = $data['source'];
406
        $video->assets      = $data['assets'];
407
        $video->publishedAt = new DateTimeImmutable($data['publishedAt']);
408
        $video->updatedAt   = new DateTimeImmutable($data['updatedAt']);
409
        if (array_key_exists('playerId', $data)) {
410
            $video->playerId = $data['playerId'];
411
        }
412
        $video->panoramic    = $data['panoramic'];
413
        $video->mp4Support    = $data['mp4Support'];
414
415
        return $video;
416
    }
417
}
418