DiskClient::setProperty()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 15
cts 15
cp 1
rs 9.472
c 0
b 0
f 0
cc 4
nc 3
nop 4
crap 4
1
<?php
2
/**
3
 * Yandex PHP Library
4
 *
5
 * @copyright NIX Solutions Ltd.
6
 * @link https://github.com/nixsolutions/yandex-php-library
7
 */
8
9
/**
10
 * @namespace
11
 */
12
namespace Yandex\Disk;
13
14
use Psr\Http\Message\UriInterface;
15
use GuzzleHttp\Psr7\Response;
16
use GuzzleHttp\Exception\ClientException;
17
use Yandex\Common\AbstractServiceClient;
18
use Yandex\Disk\Exception\DiskRequestException;
19
20
/**
21
 * Class DiskClient
22
 *
23
 * @category Yandex
24
 * @package Disk
25
 *
26
 * @author   Alexander Mitsura <[email protected]>
27
 * @created  07.10.13 12:35
28
 *
29
 * @see https://tech.yandex.com/disk/doc/dg/concepts/api-methods-docpage/
30
 */
31
class DiskClient extends AbstractServiceClient
32
{
33
    const DECODE_TYPE_DEFAULT = self::DECODE_TYPE_XML;
34
35
    /**
36
     * @var string
37
     */
38
    private $version = 'v1';
39
40
    /**
41
     * @var string
42
     */
43
    protected $serviceDomain = 'webdav.yandex.ru';
44
45
    /**
46
     * @param string $version
47
     *
48
     * @return self
49
     */
50 1
    public function setVersion($version)
51
    {
52 1
        $this->version = $version;
53
54 1
        return $this;
55
    }
56
57
    /**
58
     * @return string
59
     */
60 2
    public function getVersion()
61
    {
62 2
        return $this->version;
63
    }
64
65
    /**
66
     * @inheritdoc
67
     */
68 2
    public function getServiceUrl($resource = '')
69
    {
70 2
        return parent::getServiceUrl($resource) . '/' . $this->version;
71
    }
72
73
    /**
74
     * @param $path
75
     * @return string
76
     */
77 1
    public function getRequestUrl($path)
78
    {
79 1
        return parent::getServiceUrl() . $path;
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getServiceUrl() instead of getRequestUrl()). Are you sure this is correct? If so, you might want to change this to $this->getServiceUrl().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
80
    }
81
82
    /**
83
     * @param string $token access token
84
     */
85 25
    public function __construct($token = '')
86
    {
87 25
        $this->setAccessToken($token);
88 25
    }
89
90
    /**
91
     * Sends a request
92
     *
93
     * @param string              $method  HTTP method
94
     * @param string|UriInterface $uri     URI object or string.
95
     * @param array               $options Request options to apply.
96
     *
97
     * @throws \Exception|\GuzzleHttp\Exception\ClientException
98
     * @return Response
99
     */
100 20
    protected function sendRequest($method, $uri, array $options = [])
101
    {
102
        try {
103 20
            $response = $this->getClient()->request($method, $uri, $options);
104 2
        } catch (ClientException $ex) {
105 2
            $result = $ex->getResponse();
106 2
            $code = $result->getStatusCode();
107 2
            $message = $result->getReasonPhrase();
108
109 2
            throw new DiskRequestException(
110 2
                'Service responded with error code: "' . $code . '" and message: "' . $message . '"',
111 2
                $code
112
            );
113
        }
114
115 18
        return $response;
116
    }
117
118
    /**
119
     * @param string $path
120
     * @return bool
121
     *
122
     * @see https://tech.yandex.com/disk/doc/dg/reference/mkcol-docpage/
123
     */
124 1
    public function createDirectory($path = '')
125
    {
126 1
        return (bool) $this->sendRequest('MKCOL', $path);
127
    }
128
129
    /**
130
     * @param string $path
131
     * @param null $offset
132
     * @param null $amount
133
     * @return array
134
     *
135
     * @see https://tech.yandex.com/disk/doc/dg/reference/propfind_contains-request-docpage/
136
     */
137 2
    public function directoryContents($path = '/', $offset = null, $amount = null, $depth = '1')
138
    {
139 2
        $response = $this->sendRequest(
140 2
            'PROPFIND',
141 2
            $path,
142
            [
143
                'headers' => [
144 2
                    'Depth' => $depth
145
                ],
146
                'query' => [
147 2
                    'offset' => $offset,
148 2
                    'amount' => $amount
149
                ]
150
            ]
151
        );
152
153 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
154
155 1
        $contents = [];
156 1
        foreach ($decodedResponseBody->children('DAV:') as $element) {
157 1
            array_push(
158 1
                $contents,
159
                [
160 1
                    'href' => $element->href->__toString(),
161 1
                    'status' => $element->propstat->status->__toString(),
162 1
                    'creationDate' => $element->propstat->prop->creationdate->__toString(),
163 1
                    'lastModified' => $element->propstat->prop->getlastmodified->__toString(),
164 1
                    'displayName' => $element->propstat->prop->displayname->__toString(),
165 1
                    'contentLength' => $element->propstat->prop->getcontentlength->__toString(),
166 1
                    'resourceType' => $element->propstat->prop->resourcetype->collection ? 'dir' : 'file',
167 1
                    'contentType' => $element->propstat->prop->getcontenttype->__toString()
168
                ]
169
            );
170
        }
171 1
        return $contents;
172
    }
173
174
    /**
175
     * @return array
176
     *
177
     * @see https://tech.yandex.com/disk/doc/dg/reference/propfind_space-request-docpage/
178
     */
179 1
    public function diskSpaceInfo()
180
    {
181 1
        $body = '<?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:">
182
            <D:prop><D:quota-available-bytes/><D:quota-used-bytes/></D:prop></D:propfind>';
183
184 1
        $response = $this->sendRequest(
185 1
            'PROPFIND',
186 1
            '/',
187
            [
188 1
                'headers' => [
189
                    'Depth' => '0'
190
                ],
191 1
                'body' => $body
192
            ]
193
        );
194
195 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
196
197 1
        $info = (array) $decodedResponseBody->children('DAV:')->response->propstat->prop;
198
        return [
199 1
            'usedBytes' => $info['quota-used-bytes'],
200 1
            'availableBytes' => $info['quota-available-bytes']
201
        ];
202
    }
203
204
    /**
205
     * @param string $path
206
     * @param string $property
207
     * @param string $value
208
     * @param string $namespace
209
     * @return bool
210
     *
211
     * @see https://tech.yandex.com/disk/doc/dg/reference/proppatch-docpage/
212
     */
213 3
    public function setProperty($path = '', $property = '', $value = '', $namespace = 'default:namespace')
214
    {
215 3
        if (!empty($property) && !empty($value)) {
216
            $body = '<?xml version="1.0" encoding="utf-8" ?><propertyupdate xmlns="DAV:" xmlns:u="'
217 2
                . $namespace . '"><set><prop><u:' . $property . '>' . $value . '</u:'
218 2
                . $property . '></prop></set></propertyupdate>';
219
220 2
            $response = $this->sendRequest(
221 2
                'PROPPATCH',
222 2
                $path,
223
                [
224
                    'headers' => [
225 2
                        'Content-Length' => strlen($body),
226 2
                        'Content-Type' => 'application/x-www-form-urlencoded'
227
                    ],
228 2
                    'body' => $body
229
                ]
230
            );
231
232 2
            $decodedResponseBody = $this->getDecodedBody($response->getBody());
233
234 2
            $resultStatus = $decodedResponseBody->children('DAV:')->response->propstat->status;
235 2
            if (strpos($resultStatus, '200 OK')) {
236 1
                return true;
237
            }
238
        }
239 2
        return false;
240
    }
241
242
    /**
243
     * @param string $path
244
     * @param string $property
245
     * @param string $namespace
246
     * @return string|false
247
     *
248
     * @see https://tech.yandex.com/disk/doc/dg/reference/propfind_property-request-docpage/
249
     */
250 3
    public function getProperty($path = '', $property = '', $namespace = 'default:namespace')
251
    {
252 3
        if (!empty($property)) {
253 2
            $body = '<?xml version="1.0" encoding="utf-8" ?><propfind xmlns="DAV:"><prop><' . $property
254 2
                . ' xmlns="' . $namespace . '"/></prop></propfind>';
255
256 2
            $response = $this->sendRequest(
257 2
                'PROPFIND',
258 2
                $path,
259
                [
260
                    'headers' => [
261 2
                        'Depth' => '1',
262 2
                        'Content-Length' => strlen($body),
263 2
                        'Content-Type' => 'application/x-www-form-urlencoded'
264
                    ],
265 2
                    'body' => $body
266
                ]
267
            );
268
269 2
            $decodedResponseBody = $this->getDecodedBody($response->getBody());
270
271 2
            $resultStatus = $decodedResponseBody->children('DAV:')->response->propstat->status;
272 2
            if (strpos($resultStatus, '200 OK')) {
273 1
                return (string)$decodedResponseBody->children('DAV:')->response->propstat->prop->children();
274
            }
275
        }
276
277 2
        return false;
278
    }
279
280
    /**
281
     * @return string
282
     * @see https://tech.yandex.com/disk/doc/dg/reference/userinfo-docpage/
283
     */
284 1
    public function getLogin()
285
    {
286 1
        $response = $this->sendRequest(
287 1
            'GET',
288 1
            '/?userinfo'
289
        );
290 1
        $result = explode(":", $response->getBody());
291 1
        array_shift($result);
292 1
        return implode(':', $result);
293
    }
294
295
    /**
296
     * @param string $path
297
     * @return array
298
     *
299
     * @see https://tech.yandex.com/disk/doc/dg/reference/get-docpage/
300
     */
301 1
    public function getFile($path = '')
302
    {
303 1
        $response = $this->sendRequest('GET', $path);
304
305 1
        $result = [];
306 1 View Code Duplication
        foreach ($response->getHeaders() as $key => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
307 1
            $result['headers'][strtolower($key)] = $value[0];
308
        }
309 1
        $result['body'] = $response->getBody();
310 1
        return $result;
311
    }
312
313
    /**
314
     * @param string $path
315
     * @param string $destination
316
     * @param string $name
317
     * @return string|false
318
     *
319
     * @see https://tech.yandex.com/disk/doc/dg/reference/get-docpage/
320
     */
321 2
    public function downloadFile($path = '', $destination = '', $name = '')
322
    {
323 2
        $response = $this->sendRequest('GET', $path);
324 2
        if ($name === '' && $response->getHeader('Content-Disposition')
325 2
            && is_array($response->getHeader('Content-Disposition'))
326 2
            && count($response->getHeader('Content-Disposition')) > 0
327
        ) {
328 1
            $matchResults = [];
329 1
            preg_match(
330 1
                "/.*?filename=\"(.*?)\".*?/",
331 1
                $response->getHeader('Content-Disposition')[0],
332 1
                $matchResults
333
            );
334 1
            $name = urldecode($matchResults[1]);
335
        }
336
337 2
        $file = $destination . $name;
338
339 2
        $result = file_put_contents($file, $response->getBody()) ? $file : false;
340
341 2
        return $result;
342
    }
343
344
    /**
345
     * @param string $path
346
     * @param array $file
347
     * @param array $extraHeaders
348
     * @return Response
349
     *
350
     * @see https://tech.yandex.com/disk/doc/dg/reference/put-docpage/
351
     */
352 1
    public function uploadFile($path = '', $file = null, $extraHeaders = null)
353
    {
354 1
        if (file_exists($file['path'])) {
355
            $headers = [
356 1
                'Content-Length' => (string)$file['size']
357
            ];
358 1
            $finfo = finfo_open(FILEINFO_MIME);
359 1
            $mime = finfo_file($finfo, $file['path']);
360 1
            $parts = explode(";", $mime);
361 1
            $headers['Content-Type'] = $parts[0];
362 1
            $headers['Etag'] = md5_file($file['path']);
363 1
            $headers['Sha256'] = hash_file('sha256', $file['path']);
364 1
            $headers = isset($extraHeaders) ? array_merge($headers, $extraHeaders) : $headers;
365
366 1
            return $this->sendRequest(
367 1
                'PUT',
368 1
                $path . $file['name'],
369
                [
370 1
                    'headers' => $headers,
371 1
                    'body' => fopen($file['path'], 'rb'),
372
                    'expect' => true
373
                ]
374
            );
375
        }
376
    }
377
378
    /**
379
     * @param $path
380
     * @param $size
381
     * @return array
382
     *
383
     * @see https://tech.yandex.com/disk/doc/dg/reference/preview-docpage/
384
     */
385 1
    public function getImagePreview($path, $size)
386
    {
387 1
        $response = $this->sendRequest(
388 1
            'GET',
389 1
            $path,
390
            [
391
                'query' => [
392 1
                    'preview' => '',
393 1
                    'size' => $size
394
                ]
395
            ]
396
        );
397
398 1
        $result = [];
399 1 View Code Duplication
        foreach ($response->getHeaders() as $key => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
400 1
            $result['headers'][strtolower($key)] = $value[0];
401
        }
402
403 1
        $result['body'] = $response->getBody();
404 1
        return $result;
405
    }
406
407
    /**
408
     * @param string $target
409
     * @param string $destination
410
     * @return bool
411
     *
412
     * @see https://tech.yandex.com/disk/doc/dg/reference/copy-docpage/
413
     */
414 1
    public function copy($target = '', $destination = '')
415
    {
416 1
        return (bool) $this->sendRequest(
417 1
            'COPY',
418 1
            $target,
419
            [
420
                'headers' => [
421 1
                    'Destination' => $destination
422
                ]
423
            ]
424
        );
425
    }
426
427
    /**
428
     * @param string $path
429
     * @param string $destination
430
     * @return bool
431
     *
432
     * @see https://tech.yandex.com/disk/doc/dg/reference/move-docpage/
433
     */
434 1
    public function move($path = '', $destination = '')
435
    {
436 1
        return (bool) $this->sendRequest(
437 1
            'MOVE',
438 1
            $path,
439
            [
440
                'headers' => [
441 1
                    'Destination' => $destination
442
                ]
443
            ]
444
        );
445
    }
446
447
    /**
448
     * @param string $path
449
     * @return bool
450
     *
451
     * @see https://tech.yandex.com/disk/doc/dg/reference/delete-docpage/
452
     */
453 1
    public function delete($path = '')
454
    {
455 1
        return (bool) $this->sendRequest('DELETE', $path);
456
    }
457
458
    /**
459
     * @param string $path
460
     * @return string
461
     *
462
     * @see https://tech.yandex.com/disk/doc/dg/reference/publish-docpage/#publish-s_1
463
     * @see https://tech.yandex.com/disk/doc/dg/reference/publish-docpage/#publish-s
464
     */
465 1
    public function startPublishing($path = '')
466
    {
467 1
        $body = '<propertyupdate xmlns="DAV:"><set><prop>
468
            <public_url xmlns="urn:yandex:disk:meta">true</public_url>
469
            </prop></set></propertyupdate>';
470
471 1
        $response = $this->sendRequest(
472 1
            'PROPPATCH',
473 1
            $path,
474
            [
475
                'headers' => [
476 1
                    'Content-Length' => strlen($body)
477
                ],
478 1
                'body' => $body
479
            ]
480
        );
481
482 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
483
484 1
        $publicUrl = $decodedResponseBody->children('DAV:')->response->propstat->prop->children()->public_url;
485 1
        return (string)$publicUrl;
486
    }
487
488
    /**
489
     * @param string $path
490
     * @return void
491
     *
492
     * @see @https://tech.yandex.com/disk/doc/dg/reference/publish-docpage/#unpublish
493
     */
494 1
    public function stopPublishing($path = '')
495
    {
496 1
        $body = '<propertyupdate xmlns="DAV:"><remove><prop>
497
            <public_url xmlns="urn:yandex:disk:meta" />
498
            </prop></remove></propertyupdate>';
499
500 1
        $this->sendRequest(
501 1
            'PROPPATCH',
502 1
            $path,
503
            [
504
                'headers' => [
505 1
                    'Content-Length' => strlen($body)
506
                ],
507 1
                'body' => $body
508
            ]
509
        );
510 1
    }
511
512
    /**
513
     * @param string $path
514
     * @return string|bool
515
     *
516
     * @see https://tech.yandex.com/disk/doc/dg/reference/publish-docpage/#unpublish_1
517
     */
518 1
    public function checkPublishing($path = '')
519
    {
520 1
        $body = '<propfind xmlns="DAV:"><prop><public_url xmlns="urn:yandex:disk:meta"/></prop></propfind>';
521
522 1
        $response = $this->sendRequest(
523 1
            'PROPFIND',
524 1
            $path,
525
            [
526
                'headers' => [
527 1
                    'Content-Length' => strlen($body),
528 1
                    'Depth' => '0'
529
                ],
530 1
                'body' => $body
531
            ]
532
        );
533
534 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
535
536 1
        $propArray = (array) $decodedResponseBody->children('DAV:')->response->propstat->prop->children();
537 1
        return empty($propArray['public_url']) ? (bool)false : (string)$propArray['public_url'];
538
    }
539
}
540