Test Failed
Push — master ( 92f289...57b076 )
by Raza
02:44
created

DropboxClient::getAccountInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 2
1
<?php
2
3
namespace Srmklive\Dropbox\Client;
4
5
use GuzzleHttp\Client as HttpClient;
6
use GuzzleHttp\Exception\ClientException as HttpClientException;
7
use GuzzleHttp\Psr7\StreamWrapper;
8
use Illuminate\Support\Collection;
9
use Srmklive\Dropbox\Exceptions\BadRequest;
10
11
class DropboxClient
12
{
13
    const THUMBNAIL_FORMAT_JPEG = 'jpeg';
14
    const THUMBNAIL_FORMAT_PNG = 'png';
15
16
    const THUMBNAIL_SIZE_XS = 'w32h32';
17
    const THUMBNAIL_SIZE_S = 'w64h64';
18
    const THUMBNAIL_SIZE_M = 'w128h128';
19
    const THUMBNAIL_SIZE_L = 'w640h480';
20
    const THUMBNAIL_SIZE_XL = 'w1024h768';
21
22
    /** @var \GuzzleHttp\Client */
23
    protected $client;
24
25
    /**
26
     * Dropbox OAuth access token.
27
     *
28
     * @var string
29
     */
30
    protected $accessToken;
31
32
    /**
33
     * Dropbox API v2 Url.
34
     *
35
     * @var string
36
     */
37
    protected $apiUrl;
38
39
    /**
40
     * Dropbox content API v2 url for uploading content.
41
     *
42
     * @var string
43
     */
44
    protected $apiContentUrl;
45
46
    /**
47
     * Dropbox API v2 endpoint.
48
     *
49
     * @var string
50
     */
51
    protected $apiEndpoint;
52
53
    /**
54
     * @var mixed
55
     */
56
    protected $content;
57
58
    /**
59
     * Collection containing Dropbox API request data.
60
     *
61
     * @var \Illuminate\Support\Collection
62
     */
63
    protected $request;
64
65
    /**
66
     * DropboxClient constructor.
67
     *
68
     * @param string             $token
69
     * @param \GuzzleHttp\Client $client
70
     */
71 12
    public function __construct($token, HttpClient $client = null)
72
    {
73 12
        $this->setAccessToken($token);
74
75 12
        $this->setClient($client);
76
77 12
        $this->apiUrl = 'https://api.dropboxapi.com/2/';
78 12
        $this->apiContentUrl = 'https://content.dropboxapi.com/2/';
79 12
    }
80
81
    /**
82
     * Set Http Client.
83
     *
84
     * @param \GuzzleHttp\Client $client
85
     */
86 12
    protected function setClient(HttpClient $client = null)
87
    {
88 12
        if ($client instanceof HttpClient) {
89 11
            $this->client = $client;
90 11
        } else {
91 1
            $this->client = new HttpClient([
92
                'headers' => [
93 1
                    'Authorization' => "Bearer {$this->accessToken}",
94 1
                ],
95 1
            ]);
96
        }
97 12
    }
98
99
    /**
100
     * Set Dropbox OAuth access token.
101
     *
102
     * @param string $token
103
     */
104 12
    protected function setAccessToken($token)
105
    {
106 12
        $this->accessToken = $token;
107 12
    }
108
109
    /**
110
     * Copy a file or folder to a different location in the user's Dropbox.
111
     *
112
     * If the source path is a folder all its contents will be copied.
113
     *
114
     * @param string $fromPath
115
     * @param string $toPath
116
     *
117
     * @return \Psr\Http\Message\ResponseInterface
118
     *
119
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-copy
120
     */
121 1 View Code Duplication
    public function copy($fromPath, $toPath)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
    {
123 1
        $this->setupRequest([
124 1
            'from_path' => $this->normalizePath($fromPath),
125 1
            'to_path'   => $this->normalizePath($toPath),
126 1
        ]);
127
128 1
        $this->apiEndpoint = 'files/copy';
129
130 1
        return $this->doDropboxApiRequest();
131
    }
132
133
    /**
134
     * Create a folder at a given path.
135
     *
136
     * @param string $path
137
     *
138
     * @return \Psr\Http\Message\ResponseInterface
139
     *
140
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-create_folder
141
     */
142 1
    public function createFolder($path)
143
    {
144 1
        $this->setupRequest([
145 1
            'path' => $this->normalizePath($path),
146 1
        ]);
147
148 1
        $this->apiEndpoint = 'files/create_folder';
149
150 1
        $response = $this->doDropboxApiRequest();
151 1
        $response['.tag'] = 'folder';
152
153 1
        return $response;
154
    }
155
156
    /**
157
     * Delete the file or folder at a given path.
158
     *
159
     * If the path is a folder, all its contents will be deleted too.
160
     * A successful response indicates that the file or folder was deleted.
161
     *
162
     * @param string $path
163
     *
164
     * @return \Psr\Http\Message\ResponseInterface
165
     *
166
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-delete
167
     */
168 1
    public function delete($path)
169
    {
170 1
        $this->setupRequest([
171 1
            'path' => $this->normalizePath($path),
172 1
        ]);
173
174 1
        $this->apiEndpoint = 'files/delete';
175
176 1
        return $this->doDropboxApiRequest();
177
    }
178
179
    /**
180
     * Download a file from a user's Dropbox.
181
     *
182
     * @param string $path
183
     *
184
     * @return resource
185
     *
186
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-download
187
     */
188 1
    public function download($path)
189
    {
190 1
        $this->setupRequest([
191 1
            'path' => $this->normalizePath($path),
192 1
        ]);
193
194 1
        $this->apiEndpoint = 'files/download';
195
196 1
        $response = $this->doDropboxApiContentRequest();
197
198 1
        return StreamWrapper::getResource($response->getBody());
199
    }
200
201
    /**
202
     * Returns the metadata for a file or folder.
203
     *
204
     * Note: Metadata for the root folder is unsupported.
205
     *
206
     * @param string $path
207
     *
208
     * @return \Psr\Http\Message\ResponseInterface
209
     *
210
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-get_metadata
211
     */
212 1
    public function getMetaData($path)
213
    {
214 1
        $this->setupRequest([
215 1
            'path' => $this->normalizePath($path),
216 1
        ]);
217
218 1
        $this->apiEndpoint = 'files/get_metadata';
219
220 1
        return $this->doDropboxApiRequest();
221
    }
222
223
    /**
224
     * Get a temporary link to stream content of a file.
225
     *
226
     * This link will expire in four hours and afterwards you will get 410 Gone.
227
     * Content-Type of the link is determined automatically by the file's mime type.
228
     *
229
     * @param string $path
230
     *
231
     * @return string
232
     *
233
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-get_temporary_link
234
     */
235 1 View Code Duplication
    public function getTemporaryLink($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
236
    {
237 1
        $this->setupRequest([
238 1
            'path' => $this->normalizePath($path),
239 1
        ]);
240
241 1
        $this->apiEndpoint = 'files/get_temporary_link';
242
243 1
        $response = $this->doDropboxApiRequest();
244
245 1
        return $response['link'];
246
    }
247
248
    /**
249
     * Get a thumbnail for an image.
250
     *
251
     * This method currently supports files with the following file extensions:
252
     * jpg, jpeg, png, tiff, tif, gif and bmp.
253
     *
254
     * Photos that are larger than 20MB in size won't be converted to a thumbnail.
255
     *
256
     * @param string $path
257
     * @param string $format
258
     * @param string $size
259
     *
260
     * @return string
261
     */
262 1
    public function getThumbnail($path, $format = 'jpeg', $size = 'w64h64')
263
    {
264 1
        $this->setupRequest([
265 1
            'path'   => $this->normalizePath($path),
266 1
            'format' => $format,
267 1
            'size'   => $size,
268 1
        ]);
269
270 1
        $this->apiEndpoint = 'files/get_thumbnail';
271
272 1
        $response = $this->doDropboxApiContentRequest();
273
274 1
        return (string) $response->getBody();
275
    }
276
277
    /**
278
     * Starts returning the contents of a folder.
279
     *
280
     * If the result's ListFolderResult.has_more field is true, call
281
     * list_folder/continue with the returned ListFolderResult.cursor to retrieve more entries.
282
     *
283
     * Note: auth.RateLimitError may be returned if multiple list_folder or list_folder/continue calls
284
     * with same parameters are made simultaneously by same API app for same user. If your app implements
285
     * retry logic, please hold off the retry until the previous request finishes.
286
     *
287
     * @param string $path
288
     * @param bool   $recursive
289
     *
290
     * @return \Psr\Http\Message\ResponseInterface
291
     *
292
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
293
     */
294 1 View Code Duplication
    public function listFolder($path = '', $recursive = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
295
    {
296 1
        $this->setupRequest([
297 1
            'path'      => $this->normalizePath($path),
298 1
            'recursive' => $recursive,
299 1
        ]);
300
301 1
        $this->apiEndpoint = 'files/list_folder';
302
303 1
        return $this->doDropboxApiRequest();
304
    }
305
306
    /**
307
     * Once a cursor has been retrieved from list_folder, use this to paginate through all files and
308
     * retrieve updates to the folder, following the same rules as documented for list_folder.
309
     *
310
     * @param string $cursor
311
     *
312
     * @return \Psr\Http\Message\ResponseInterface
313
     *
314
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder-continue
315
     */
316 1
    public function listFolderContinue($cursor = '')
317
    {
318 1
        $this->setupRequest([
319 1
            'cursor' => $cursor,
320 1
        ]);
321
322 1
        $this->apiEndpoint = 'files/list_folder/continue';
323
324 1
        return $this->doDropboxApiRequest();
325
    }
326
327
    /**
328
     * Move a file or folder to a different location in the user's Dropbox.
329
     *
330
     * If the source path is a folder all its contents will be moved.
331
     *
332
     * @param string $fromPath
333
     * @param string $toPath
334
     *
335
     * @return \Psr\Http\Message\ResponseInterface
336
     *
337
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-move
338
     */
339 1 View Code Duplication
    public function move($fromPath, $toPath)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
340
    {
341 1
        $this->setupRequest([
342 1
            'from_path' => $this->normalizePath($fromPath),
343 1
            'to_path'   => $this->normalizePath($toPath),
344 1
        ]);
345
346 1
        $this->apiEndpoint = 'files/move_v2';
347
348 1
        return $this->doDropboxApiRequest();
349
    }
350
351
    /**
352
     * Create a new file with the contents provided in the request.
353
     *
354
     * Do not use this to upload a file larger than 150 MB. Instead, create an upload session with upload_session/start.
355
     *
356
     * @link https://www.dropbox.com/developers/documentation/http/documentation#files-upload
357
     *
358
     * @param string          $path
359
     * @param string|resource $contents
360
     * @param string|array    $mode
361
     *
362
     * @return array
363
     */
364 1
    public function upload($path, $contents, $mode = 'add')
365
    {
366 1
        $this->setupRequest([
367 1
            'path' => $this->normalizePath($path),
368 1
            'mode' => $mode,
369 1
        ]);
370
371 1
        $this->content = $contents;
372
373 1
        $this->apiEndpoint = 'files/upload';
374
375 1
        $response = $this->doDropboxApiContentRequest();
376
377 1
        $metadata = \GuzzleHttp\json_decode($response->getBody(), true);
378 1
        $metadata['.tag'] = 'file';
379
380 1
        return $metadata;
381
    }
382
383
    /**
384
     * Get Account Info for current authenticated user.
385
     *
386
     * @link https://www.dropbox.com/developers/documentation/http/documentation#users-get_current_account
387
     *
388
     * @return \Psr\Http\Message\ResponseInterface
389
     */
390
    public function getAccountInfo()
391
    {
392
        $this->apiEndpoint = 'users/get_current_account';
393
394
        return $this->doDropboxApiRequest();
395
    }
396
397
    /**
398
     * Revoke current access token.
399
     *
400
     * @link https://www.dropbox.com/developers/documentation/http/documentation#auth-token-revoke
401
     *
402
     * @return \Psr\Http\Message\ResponseInterface
403
     */
404
    public function revokeToken()
405
    {
406
        $this->apiEndpoint = 'auth/token/revoke';
407
408
        return $this->doDropboxApiRequest();
409
    }
410
411
    /**
412
     * Set Dropbox API request data.
413
     *
414
     * @param array $request
415
     */
416 11
    protected function setupRequest($request)
417
    {
418 11
        $this->request = new Collection($request);
419 11
    }
420
421
    /**
422
     * Perform Dropbox API request.
423
     *
424
     * @throws \Exception
425
     *
426
     * @return \Psr\Http\Message\ResponseInterface
427
     */
428 8
    protected function doDropboxApiRequest()
429
    {
430
        try {
431 8
            $response = $this->client->post("{$this->apiUrl}{$this->apiEndpoint}", [
432 8
                'json' => $this->request->toArray(),
433 8
            ]);
434 8
        } catch (HttpClientException $exception) {
435
            throw $this->determineException($exception);
436
        }
437
438 7
        return json_decode($response->getBody(), true);
439
    }
440
441
    /**
442
     * Setup headers for Dropbox API request.
443
     *
444
     * @return array
445
     */
446 3
    protected function setupDropboxHeaders()
447
    {
448
        $headers = [
449 3
            'Dropbox-API-Arg' => json_encode(
450 3
                $this->request->toArray()
451 3
            ),
452 3
        ];
453
454 3
        if (!empty($this->content)) {
455 1
            $headers['Content-Type'] = 'application/octet-stream';
456 1
        }
457
458 3
        return $headers;
459
    }
460
461
    /**
462
     * Perform Dropbox API request.
463
     *
464
     * @throws \Exception
465
     *
466
     * @return \Psr\Http\Message\ResponseInterface
467
     */
468 3
    protected function doDropboxApiContentRequest()
469
    {
470
        try {
471 3
            $response = $this->client->post("{$this->apiContentUrl}{$this->apiEndpoint}", [
472 3
                'headers' => $this->setupDropboxHeaders(),
473 3
                'body'    => !empty($this->content) ? $this->content : '',
474 3
            ]);
475 3
        } catch (HttpClientException $exception) {
476
            throw $this->determineException($exception);
477
        }
478
479 3
        return $response;
480
    }
481
482
    /**
483
     * Normalize path.
484
     *
485
     * @param string $path
486
     *
487
     * @return string
488
     */
489 10
    protected function normalizePath($path)
490
    {
491 10
        $path = (trim($path, '/') === '') ? '' : '/'.$path;
492
493 10
        return str_replace('//', '/', $path);
494
    }
495
496
    /**
497
     * Catch Dropbox API request exception.
498
     *
499
     * @param HttpClientException $exception
500
     *
501
     * @return \Exception
502
     */
503
    protected function determineException(HttpClientException $exception)
504
    {
505
        if (!empty($exception->getResponse()) && in_array($exception->getResponse()->getStatusCode(), [400, 409])) {
506
            return new BadRequest($exception->getResponse());
507
        }
508
509
        return $exception;
510
    }
511
}
512