Completed
Pull Request — master (#16)
by frey
06:34
created

Adapter::getVisibility()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 6
Ratio 42.86 %

Code Coverage

Tests 2
CRAP Score 14.1113

Importance

Changes 0
Metric Value
cc 5
eloc 7
nc 3
nop 1
dl 6
loc 14
ccs 2
cts 7
cp 0.2857
crap 14.1113
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Freyo\Flysystem\QcloudCOSv3;
4
5
use Freyo\Flysystem\QcloudCOSv3\Client\Conf;
6
use Freyo\Flysystem\QcloudCOSv3\Client\Cosapi;
7
use Freyo\Flysystem\QcloudCOSv3\Exceptions\RuntimeException;
8
use League\Flysystem\Adapter\AbstractAdapter;
9
use League\Flysystem\AdapterInterface;
10
use League\Flysystem\Config;
11
use League\Flysystem\Util;
12
13
/**
14
 * Class Adapter.
15
 */
16
class Adapter extends AbstractAdapter
17
{
18
    /**
19
     * @var
20
     */
21
    protected $bucket;
22
23
    /**
24
     * @var
25
     */
26
    protected $debug;
27
28
    /**
29
     * Adapter constructor.
30
     *
31
     * @param $config
32
     */
33
    public function __construct($config)
34
    {
35
        Conf::setAppId($config['app_id']);
36
        Conf::setSecretId($config['secret_id']);
37
        Conf::setSecretKey($config['secret_key']);
38
39
        $this->bucket = $config['bucket'];
40
        $this->debug  = $config['debug'];
41
42
        $this->setPathPrefix($config['protocol'].'://'.$config['domain'].'/');
43
44
        Cosapi::setTimeout($config['timeout']);
45
    }
46
47
    /**
48
     * @return string
49
     */
50 14
    public function getBucket()
51
    {
52 14
        return $this->bucket;
53
    }
54
55
    /**
56
     * @param string $path
57
     *
58
     * @return string
59
     */
60 1
    public function getUrl($path)
61
    {
62 1
        return $this->applyPathPrefix($path);
63
    }
64
65
    /**
66
     * @param string $path
67
     * @param string $contents
68
     * @param Config $config
69
     *
70
     * @throws RuntimeException
71
     *
72
     * @return array|bool
73
     */
74 View Code Duplication
    public function write($path, $contents, Config $config)
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...
75
    {
76
        $tmpfname = $this->writeTempFile($contents);
77
78
        if (false === $tmpfname) {
79
            return false;
80
        }
81
        
82
        try {
83
            $response = Cosapi::upload($this->getBucket(), $tmpfname, $path,
0 ignored issues
show
Bug introduced by
It seems like $tmpfname defined by $this->writeTempFile($contents) on line 76 can also be of type boolean; however, Freyo\Flysystem\QcloudCO...Client\Cosapi::upload() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
84
                                        null, null, $config->get('insertOnly', 1));
85
86
            $this->deleteTempFile($tmpfname);
0 ignored issues
show
Bug introduced by
It seems like $tmpfname defined by $this->writeTempFile($contents) on line 76 can also be of type boolean; however, Freyo\Flysystem\QcloudCO...apter::deleteTempFile() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
87
88
            $response = $this->normalizeResponse($response);
89
90
            if (false === $response) {
91
                return false;
92
            }
93
94
            $this->setContentType($path, $contents);
95
        } catch (RuntimeException $exception) {
96
            $this->deleteTempFile($tmpfname);
0 ignored issues
show
Bug introduced by
It seems like $tmpfname defined by $this->writeTempFile($contents) on line 76 can also be of type boolean; however, Freyo\Flysystem\QcloudCO...apter::deleteTempFile() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
97
98
            throw $exception;
99
        }
100
101
        return $response;
102
    }
103
104
    /**
105
     * @param string   $path
106
     * @param resource $resource
107
     * @param Config   $config
108
     *
109
     * @throws RuntimeException
110
     *
111
     * @return array|bool
112
     */
113 1 View Code Duplication
    public function writeStream($path, $resource, Config $config)
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...
114
    {
115 1
        $uri = stream_get_meta_data($resource)['uri'];
116
117 1
        $response = Cosapi::upload($this->getBucket(), $uri, $path,
118 1
                                    null, null, $config->get('insertOnly', 1));
119
120 1
        $response = $this->normalizeResponse($response);
121
122
        if (false === $response) {
123
            return false;
124
        }
125
126
        $this->setContentType($path, stream_get_contents($resource));
127
128
        return $response;
129
    }
130
131
    /**
132
     * @param string $path
133
     * @param string $contents
134
     * @param Config $config
135
     *
136
     * @throws RuntimeException
137
     *
138
     * @return array|bool
139
     */
140 View Code Duplication
    public function update($path, $contents, Config $config)
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...
141
    {
142
        $tmpfname = $this->writeTempFile($contents);
143
144
        if (false === $tmpfname) {
145
            return false;
146
        }
147
        
148
        try {
149
            $response = Cosapi::upload($this->getBucket(), $tmpfname, $path,
0 ignored issues
show
Bug introduced by
It seems like $tmpfname defined by $this->writeTempFile($contents) on line 142 can also be of type boolean; however, Freyo\Flysystem\QcloudCO...Client\Cosapi::upload() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
150
                                        null, null, $config->get('insertOnly', 0));
151
152
            $this->deleteTempFile($tmpfname);
0 ignored issues
show
Bug introduced by
It seems like $tmpfname defined by $this->writeTempFile($contents) on line 142 can also be of type boolean; however, Freyo\Flysystem\QcloudCO...apter::deleteTempFile() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
153
154
            $response = $this->normalizeResponse($response);
155
156
            if (false === $response) {
157
                return false;
158
            }
159
160
            $this->setContentType($path, $contents);
161
        } catch (RuntimeException $exception) {
162
            $this->deleteTempFile($tmpfname);
0 ignored issues
show
Bug introduced by
It seems like $tmpfname defined by $this->writeTempFile($contents) on line 142 can also be of type boolean; however, Freyo\Flysystem\QcloudCO...apter::deleteTempFile() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
163
164
            throw $exception;
165
        }
166
167
        return $response;
168
    }
169
170
    /**
171
     * @param string   $path
172
     * @param resource $resource
173
     * @param Config   $config
174
     *
175
     * @throws RuntimeException
176
     *
177
     * @return array|bool
178
     */
179 1 View Code Duplication
    public function updateStream($path, $resource, Config $config)
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...
180
    {
181 1
        $uri = stream_get_meta_data($resource)['uri'];
182
183 1
        $response = Cosapi::upload($this->getBucket(), $uri, $path,
184 1
                                    null, null, $config->get('insertOnly', 0));
185
186 1
        $response = $this->normalizeResponse($response);
187
188
        if (false === $response) {
189
            return false;
190
        }
191
192
        $this->setContentType($path, stream_get_contents($resource));
193
194
        return $response;
195
    }
196
197
    /**
198
     * @param string $path
199
     * @param string $newpath
200
     *
201
     * @return bool
202
     */
203 1
    public function rename($path, $newpath)
204
    {
205 1
        return $this->normalizeResponse(
206 1
            Cosapi::move($this->getBucket(), $path, $newpath, 1)
207 1
        );
208
    }
209
210
    /**
211
     * @param string $path
212
     * @param string $newpath
213
     *
214
     * @return array|bool
215
     */
216
    public function copy($path, $newpath)
217
    {
218
        $resource = $this->read($path);
219
220
        if (false === $resource) {
221
            return false;
222
        }
223
224
        return $this->update($newpath, $resource['contents'], new Config());
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->update($newpath, ...ue\Flysystem\Config()); of type array|boolean adds the type array to the return on line 224 which is incompatible with the return type declared by the interface League\Flysystem\AdapterInterface::copy of type boolean.
Loading history...
225
    }
226
227
    /**
228
     * @param string $path
229
     *
230
     * @return bool
231
     */
232 1
    public function delete($path)
233
    {
234 1
        return $this->normalizeResponse(
235 1
            Cosapi::delFile($this->getBucket(), $path)
236 1
        );
237
    }
238
239
    /**
240
     * @param string $dirname
241
     *
242
     * @return bool
243
     */
244 1
    public function deleteDir($dirname)
245
    {
246 1
        return $this->normalizeResponse(
247 1
            Cosapi::delFolder($this->getBucket(), $dirname)
248 1
        );
249
    }
250
251
    /**
252
     * @param string $dirname
253
     * @param Config $config
254
     *
255
     * @return bool
256
     */
257 1
    public function createDir($dirname, Config $config)
258
    {
259 1
        return $this->normalizeResponse(
260 1
            Cosapi::createFolder($this->getBucket(), $dirname)
261 1
        );
262
    }
263
264
    /**
265
     * @param string $path
266
     * @param string $visibility
267
     *
268
     * @return bool
269
     */
270 1
    public function setVisibility($path, $visibility)
271
    {
272 1
        $visibility = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? 'eWPrivateRPublic' : 'eWRPrivate';
273
274 1
        return $this->normalizeResponse(
275 1
            Cosapi::update($this->getBucket(), $path, null, $visibility)
276 1
        );
277
    }
278
279
    /**
280
     * @param string $path
281
     *
282
     * @return bool
283
     */
284 1
    public function has($path)
285
    {
286
        try {
287 1
            return (bool) $this->getMetadata($path);
288 1
        } catch (RuntimeException $exception) {
289 1
            return false;
290
        }
291
    }
292
293
    /**
294
     * @param string $path
295
     *
296
     * @return string
297
     */
298
    public function read($path)
299
    {
300
        return ['contents' => file_get_contents($this->getUrl($path))];
301
    }
302
303
    /**
304
     * @param string $path
305
     *
306
     * @return array
307
     */
308
    public function readStream($path)
309
    {
310
        return ['stream' => fopen($this->getUrl($path), 'r')];
311
    }
312
313
    /**
314
     * @param string $directory
315
     * @param bool   $recursive
316
     *
317
     * @return bool
318
     */
319 1
    public function listContents($directory = '', $recursive = false)
320
    {
321 1
        return $this->normalizeResponse(
322 1
            Cosapi::listFolder($this->getBucket(), $directory)
323 1
        );
324
    }
325
326
    /**
327
     * @param string $path
328
     *
329
     * @return bool
330
     */
331 6
    public function getMetadata($path)
332
    {
333 6
        return $this->normalizeResponse(
334 6
            Cosapi::stat($this->getBucket(), $path)
335 6
        );
336
    }
337
338
    /**
339
     * @param string $path
340
     *
341
     * @return array|bool
342
     */
343 1
    public function getSize($path)
344
    {
345 1
        $stat = $this->getMetadata($path);
346
347
        if (isset($stat['filesize'])) {
348
            return ['size' => $stat['filesize']];
349
        }
350
351
        return false;
352
    }
353
354
    /**
355
     * @param string $path
356
     *
357
     * @return array|bool
358
     */
359 1
    public function getMimetype($path)
360
    {
361 1
        $stat = $this->getMetadata($path);
362
363
        if (isset($stat['custom_headers']['Content-Type'])) {
364
            return ['mimetype' => $stat['custom_headers']['Content-Type']];
365
        }
366
367
        return false;
368
    }
369
370
    /**
371
     * @param string $path
372
     *
373
     * @return array|bool
374
     */
375 1
    public function getTimestamp($path)
376
    {
377 1
        $stat = $this->getMetadata($path);
378
379
        if (isset($stat['ctime'])) {
380
            return ['timestamp' => $stat['ctime']];
381
        }
382
383
        return false;
384
    }
385
386
    /**
387
     * @param string $path
388
     *
389
     * @return array|bool
390
     */
391 1
    public function getVisibility($path)
392
    {
393 1
        $stat = $this->getMetadata($path);
394
395 View Code Duplication
        if (isset($stat['authority']) && $stat['authority'] === 'eWPrivateRPublic') {
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...
396
            return ['visibility' => AdapterInterface::VISIBILITY_PUBLIC];
397
        }
398
399 View Code Duplication
        if (isset($stat['authority']) && $stat['authority'] === 'eWRPrivate') {
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
            return ['visibility' => AdapterInterface::VISIBILITY_PRIVATE];
401
        }
402
403
        return false;
404
    }
405
406
    /**
407
     * @param string $content
408
     *
409
     * @return bool|string
410
     */
411
    private function writeTempFile($content)
412
    {
413
        $tmpfname = tempnam('/tmp', 'dir');
414
415
        chmod($tmpfname, 0777);
416
417
        file_put_contents($tmpfname, $content);
418
419
        return $tmpfname;
420
    }
421
422
    /**
423
     * @param string $tmpfname
424
     *
425
     * @return bool
426
     */
427
    private function deleteTempFile($tmpfname)
428
    {
429
        return unlink($tmpfname);
430
    }
431
432
    /**
433
     * @param string $path
434
     * @param string $content
435
     *
436
     * @return bool
437
     */
438
    protected function setContentType($path, $content)
439
    {
440
        $custom_headers = [
441
            'Content-Type' => Util::guessMimeType($path, $content),
442
        ];
443
444
        return $this->normalizeResponse(
445
            Cosapi::update($this->getBucket(), $path, null, null, $custom_headers)
446
        );
447
    }
448
449
    /**
450
     * @param $response
451
     *
452
     * @throws RuntimeException
453
     *
454
     * @return mixed
455
     */
456 14
    protected function normalizeResponse($response)
457
    {
458 14
        if ($response['code'] == 0) {
459
            return isset($response['data']) ? $response['data'] : true;
460
        }
461
462 14
        if ($this->debug) {
463 14
            throw new RuntimeException($response['message'], $response['code']);
464
        }
465
466
        return false;
467
    }
468
}
469