InMemoryFilesystem   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 35
eloc 76
dl 0
loc 272
rs 9.6
c 0
b 0
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A updateStream() 0 4 1
A exists() 0 4 1
A getMetadataInternal() 0 3 1
A read() 0 5 1
A visibility() 0 4 1
A timestamp() 0 4 1
A metadata() 0 4 1
A rename() 0 12 3
A setVisibilityPublic() 0 4 1
A writeStream() 0 12 2
A listContents() 0 17 3
A put() 0 4 1
A createDir() 0 6 1
A delete() 0 6 1
A mimetype() 0 4 1
A setVisibility() 0 10 2
A update() 0 4 1
A putStream() 0 4 1
A size() 0 4 1
A setVisibilityPrivate() 0 4 1
A deleteDir() 0 10 3
A copy() 0 10 3
A __construct() 0 5 2
A write() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Filesystem;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\Exception\RuntimeException;
18
use Valkyrja\Filesystem\Contract\Filesystem as Contract;
19
use Valkyrja\Filesystem\Data\InMemoryFile;
20
use Valkyrja\Filesystem\Data\InMemoryMetadata;
21
use Valkyrja\Filesystem\Enum\Visibility;
22
use Valkyrja\Filesystem\Exception\UnableToReadContentsException;
23
24
use function fread;
25
use function str_starts_with;
26
use function time;
27
28
/**
29
 * Class InMemoryFilesystem.
30
 *
31
 * @author Melech Mizrachi
32
 */
33
class InMemoryFilesystem implements Contract
34
{
35
    /**
36
     * @var array<string, InMemoryFile>
37
     */
38
    protected array $files = [];
39
40
    public function __construct(
41
        InMemoryFile ...$files
42
    ) {
43
        foreach ($files as $file) {
44
            $this->files[$file->name] = $file;
45
        }
46
    }
47
48
    /**
49
     * @inheritDoc
50
     */
51
    #[Override]
52
    public function exists(string $path): bool
53
    {
54
        return isset($this->files[$path]);
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60
    #[Override]
61
    public function read(string $path): string
62
    {
63
        return $this->files[$path]->contents
64
            ?? throw new UnableToReadContentsException("Error reading file contents for $path");
65
    }
66
67
    /**
68
     * @inheritDoc
69
     */
70
    #[Override]
71
    public function write(string $path, string $contents): bool
72
    {
73
        $this->files[$path] = new InMemoryFile($path, $contents, timestamp: time());
74
75
        return true;
76
    }
77
78
    /**
79
     * @inheritDoc
80
     *
81
     * @param resource $resource The resource
82
     */
83
    #[Override]
84
    public function writeStream(string $path, $resource): bool
85
    {
86
        $pathContents = fread($resource, 4096);
87
88
        if ($pathContents === false) {
89
            throw new RuntimeException('Failed to read provided resource');
90
        }
91
92
        $this->files[$path] = new InMemoryFile($path, $pathContents, timestamp: time());
93
94
        return true;
95
    }
96
97
    /**
98
     * @inheritDoc
99
     */
100
    #[Override]
101
    public function update(string $path, string $contents): bool
102
    {
103
        return $this->write($path, $contents);
104
    }
105
106
    /**
107
     * @inheritDoc
108
     */
109
    #[Override]
110
    public function updateStream(string $path, $resource): bool
111
    {
112
        return $this->writeStream($path, $resource);
113
    }
114
115
    /**
116
     * @inheritDoc
117
     */
118
    #[Override]
119
    public function put(string $path, string $contents): bool
120
    {
121
        return $this->write($path, $contents);
122
    }
123
124
    /**
125
     * @inheritDoc
126
     */
127
    #[Override]
128
    public function putStream(string $path, $resource): bool
129
    {
130
        return $this->writeStream($path, $resource);
131
    }
132
133
    /**
134
     * @inheritDoc
135
     */
136
    #[Override]
137
    public function rename(string $path, string $newPath): bool
138
    {
139
        if ($this->exists($newPath) || ! $this->exists($path)) {
140
            return false;
141
        }
142
143
        $this->files[$newPath] = $this->files[$path];
144
145
        $this->delete($path);
146
147
        return true;
148
    }
149
150
    /**
151
     * @inheritDoc
152
     */
153
    #[Override]
154
    public function copy(string $path, string $newPath): bool
155
    {
156
        if ($this->exists($newPath) || ! $this->exists($path)) {
157
            return false;
158
        }
159
160
        $this->files[$newPath] = $this->files[$path];
161
162
        return true;
163
    }
164
165
    /**
166
     * @inheritDoc
167
     */
168
    #[Override]
169
    public function delete(string $path): bool
170
    {
171
        unset($this->files[$path]);
172
173
        return true;
174
    }
175
176
    /**
177
     * @inheritDoc
178
     */
179
    #[Override]
180
    public function metadata(string $path): array|null
181
    {
182
        return $this->getMetadataInternal($path)?->toArray();
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    #[Override]
189
    public function mimetype(string $path): string|null
190
    {
191
        return $this->getMetadataInternal($path)->mimetype ?? null;
192
    }
193
194
    /**
195
     * @inheritDoc
196
     */
197
    #[Override]
198
    public function size(string $path): int|null
199
    {
200
        return $this->getMetadataInternal($path)->size ?? null;
201
    }
202
203
    /**
204
     * @inheritDoc
205
     */
206
    #[Override]
207
    public function timestamp(string $path): int|null
208
    {
209
        return $this->files[$path]->timestamp ?? null;
210
    }
211
212
    /**
213
     * @inheritDoc
214
     */
215
    #[Override]
216
    public function visibility(string $path): string|null
217
    {
218
        return $this->getMetadataInternal($path)->visibility ?? null;
219
    }
220
221
    /**
222
     * @inheritDoc
223
     */
224
    #[Override]
225
    public function setVisibility(string $path, Visibility $visibility): bool
226
    {
227
        if (! $this->exists($path)) {
228
            return false;
229
        }
230
231
        $this->files[$path]->metadata->visibility = $visibility->value;
232
233
        return true;
234
    }
235
236
    /**
237
     * @inheritDoc
238
     */
239
    #[Override]
240
    public function setVisibilityPublic(string $path): bool
241
    {
242
        return $this->setVisibility($path, Visibility::PUBLIC);
243
    }
244
245
    /**
246
     * @inheritDoc
247
     */
248
    #[Override]
249
    public function setVisibilityPrivate(string $path): bool
250
    {
251
        return $this->setVisibility($path, Visibility::PRIVATE);
252
    }
253
254
    /**
255
     * @inheritDoc
256
     */
257
    #[Override]
258
    public function createDir(string $path): bool
259
    {
260
        $this->files[$path] = new InMemoryFile($path, timestamp: time());
261
262
        return true;
263
    }
264
265
    /**
266
     * @inheritDoc
267
     */
268
    #[Override]
269
    public function deleteDir(string $path): bool
270
    {
271
        foreach ($this->files as $filePath => $file) {
272
            if (str_starts_with($filePath, $path)) {
273
                unset($this->files[$filePath]);
274
            }
275
        }
276
277
        return true;
278
    }
279
280
    /**
281
     * @inheritDoc
282
     */
283
    #[Override]
284
    public function listContents(string|null $directory = null, bool $recursive = false): array
285
    {
286
        $directory ??= '';
287
288
        $contents = [];
289
290
        foreach ($this->files as $filePath => $file) {
291
            if (str_starts_with($filePath, $directory)) {
292
                $contents[] = [
293
                    'path'     => $filePath,
294
                    'contents' => $file->contents,
295
                ];
296
            }
297
        }
298
299
        return $contents;
300
    }
301
302
    protected function getMetadataInternal(string $path): InMemoryMetadata|null
303
    {
304
        return $this->files[$path]->metadata ?? null;
305
    }
306
}
307