BackblazeAdapter   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 266
Duplicated Lines 0 %

Test Coverage

Coverage 79.27%

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 97
dl 0
loc 266
ccs 88
cts 111
cp 0.7927
rs 10
c 4
b 0
f 1
wmc 30

20 Methods

Rating   Name   Duplication   Size   Complexity  
A copy() 0 7 1
A getClient() 0 3 1
A update() 0 10 1
A deleteDir() 0 3 1
A writeStream() 0 10 1
B listContents() 0 25 9
A getTimestamp() 0 5 1
A readStream() 0 18 3
A write() 0 10 1
A rename() 0 3 1
A __construct() 0 5 1
A read() 0 12 1
A getMimetype() 0 3 1
A getFileInfo() 0 10 1
A updateStream() 0 10 1
A createDir() 0 7 1
A getMetadata() 0 3 1
A has() 0 3 1
A delete() 0 3 1
A getSize() 0 5 1
1
<?php
2
3
namespace Mhetreramesh\Flysystem;
4
5
use BackblazeB2\Client;
6
use GuzzleHttp\Psr7;
7
use League\Flysystem\Adapter\AbstractAdapter;
8
use League\Flysystem\Adapter\Polyfill\NotSupportingVisibilityTrait;
9
use League\Flysystem\Config;
10
11
class BackblazeAdapter extends AbstractAdapter
12
{
13
    use NotSupportingVisibilityTrait;
14
15
    protected $client;
16
17
    protected $bucketName;
18
19
    protected $bucketId;
20
21
    public function __construct(Client $client, $bucketName, $bucketId = null)
22
    {
23
        $this->client = $client;
24
        $this->bucketName = $bucketName;
25
        $this->bucketId = $bucketId;
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31 1
    public function has($path)
32
    {
33 1
        return $this->getClient()->fileExists(['FileName' => $path, 'BucketId' => $this->bucketId, 'BucketName' => $this->bucketName]);
34
    }
35
36
    /**
37
     * {@inheritdoc}
38
     */
39 1
    public function write($path, $contents, Config $config)
40
    {
41 1
        $file = $this->getClient()->upload([
42 1
            'BucketId'   => $this->bucketId,
43 1
            'BucketName' => $this->bucketName,
44 1
            'FileName'   => $path,
45 1
            'Body'       => $contents,
46
        ]);
47
48 1
        return $this->getFileInfo($file);
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 1
    public function writeStream($path, $resource, Config $config)
55
    {
56 1
        $file = $this->getClient()->upload([
57 1
            'BucketId'   => $this->bucketId,
58 1
            'BucketName' => $this->bucketName,
59 1
            'FileName'   => $path,
60 1
            'Body'       => $resource,
61
        ]);
62
63 1
        return $this->getFileInfo($file);
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69 1
    public function update($path, $contents, Config $config)
70
    {
71 1
        $file = $this->getClient()->upload([
72 1
            'BucketId'   => $this->bucketId,
73 1
            'BucketName' => $this->bucketName,
74 1
            'FileName'   => $path,
75 1
            'Body'       => $contents,
76
        ]);
77
78 1
        return $this->getFileInfo($file);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84 1
    public function updateStream($path, $resource, Config $config)
85
    {
86 1
        $file = $this->getClient()->upload([
87 1
            'BucketId'   => $this->bucketId,
88 1
            'BucketName' => $this->bucketName,
89 1
            'FileName'   => $path,
90 1
            'Body'       => $resource,
91
        ]);
92
93 1
        return $this->getFileInfo($file);
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 1
    public function read($path)
100
    {
101 1
        $file = $this->getClient()->getFile([
102 1
            'BucketId'   => $this->bucketId,
103 1
            'BucketName' => $this->bucketName,
104 1
            'FileName'   => $path,
105
        ]);
106 1
        $fileContent = $this->getClient()->download([
107 1
            'FileId' => $file->getId(),
108
        ]);
109
110 1
        return ['contents' => $fileContent];
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 1
    public function readStream($path)
117
    {
118 1
        $stream = Psr7\stream_for();
0 ignored issues
show
Bug introduced by
The function stream_for was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

118
        $stream = /** @scrutinizer ignore-call */ Psr7\stream_for();
Loading history...
119 1
        $download = $this->getClient()->download([
120 1
            'BucketId'   => $this->bucketId,
121 1
            'BucketName' => $this->bucketName,
122 1
            'FileName'   => $path,
123 1
            'SaveAs'     => $stream,
124
        ]);
125 1
        $stream->seek(0);
126
127
        try {
128 1
            $resource = Psr7\StreamWrapper::getResource($stream);
129
        } catch (InvalidArgumentException $e) {
0 ignored issues
show
Bug introduced by
The type Mhetreramesh\Flysystem\InvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
130
            return false;
131
        }
132
133 1
        return $download === true ? ['stream' => $resource] : false;
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 1
    public function rename($path, $newpath)
140
    {
141 1
        return false;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147 1
    public function copy($path, $newPath)
148
    {
149 1
        return $this->getClient()->upload([
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getClient(...e_get_contents($path))) returns the type BackblazeB2\File which is incompatible with the return type mandated by League\Flysystem\AdapterInterface::copy() of boolean.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
150 1
            'BucketId'   => $this->bucketId,
151 1
            'BucketName' => $this->bucketName,
152 1
            'FileName'   => $newPath,
153 1
            'Body'       => @file_get_contents($path),
154
        ]);
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160
    public function delete($path)
161
    {
162
        return $this->getClient()->deleteFile(['FileName' => $path, 'BucketId' => $this->bucketId, 'BucketName' => $this->bucketName]);
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168
    public function deleteDir($path)
169
    {
170
        return $this->getClient()->deleteFile(['FileName' => $path, 'BucketId' => $this->bucketId, 'BucketName' => $this->bucketName]);
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176
    public function createDir($path, Config $config)
177
    {
178
        return $this->getClient()->upload([
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getClient(...> $path, 'Body' => '')) returns the type BackblazeB2\File which is incompatible with the return type mandated by League\Flysystem\AdapterInterface::createDir() of array|false.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
179
            'BucketId'   => $this->bucketId,
180
            'BucketName' => $this->bucketName,
181
            'FileName'   => $path,
182
            'Body'       => '',
183
        ]);
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189 1
    public function getMetadata($path)
190
    {
191 1
        return false;
192
    }
193
194
    /**
195
     * {@inheritdoc}
196
     */
197 1
    public function getMimetype($path)
198
    {
199 1
        return false;
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     */
205
    public function getSize($path)
206
    {
207
        $file = $this->getClient()->getFile(['FileName' => $path, 'BucketId' => $this->bucketId, 'BucketName' => $this->bucketName]);
208
209
        return $this->getFileInfo($file);
210
    }
211
212
    /**
213
     * {@inheritdoc}
214
     */
215
    public function getTimestamp($path)
216
    {
217
        $file = $this->getClient()->getFile(['FileName' => $path, 'BucketId' => $this->bucketId, 'BucketName' => $this->bucketName]);
218
219
        return $this->getFileInfo($file);
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225 9
    public function getClient()
226
    {
227 9
        return $this->client;
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233 1
    public function listContents($directory = '', $recursive = false)
234
    {
235 1
        $fileObjects = $this->getClient()->listFiles([
236 1
            'BucketId'   => $this->bucketId,
237 1
            'BucketName' => $this->bucketName,
238
        ]);
239 1
        if ($recursive === true && $directory === '') {
240 1
            $regex = '/^.*$/';
241 1
        } elseif ($recursive === true && $directory !== '') {
242 1
            $regex = '/^'.preg_quote($directory).'\/.*$/';
243 1
        } elseif ($recursive === false && $directory === '') {
244 1
            $regex = '/^(?!.*\\/).*$/';
245 1
        } elseif ($recursive === false && $directory !== '') {
246 1
            $regex = '/^'.preg_quote($directory).'\/(?!.*\\/).*$/';
247
        } else {
248 1
            throw new \InvalidArgumentException();
249
        }
250 1
        $fileObjects = array_filter($fileObjects, function ($fileObject) use ($regex) {
251 1
            return 1 === preg_match($regex, $fileObject->getName());
252 1
        });
253 1
        $normalized = array_map(function ($fileObject) {
254 1
            return $this->getFileInfo($fileObject);
255 1
        }, $fileObjects);
256
257 1
        return array_values($normalized);
258
    }
259
260
    /**
261
     * Get file info.
262
     *
263
     * @param $file
264
     *
265
     * @return array
266
     */
267 5
    protected function getFileInfo($file)
268
    {
269
        $normalized = [
270 5
            'type'      => 'file',
271 5
            'path'      => $file->getName(),
272 5
            'timestamp' => substr($file->getUploadTimestamp(), 0, -3),
273 5
            'size'      => $file->getSize(),
274
        ];
275
276 5
        return $normalized;
277
    }
278
}
279