Test Failed
Push — master ( 2cefea...d08b1d )
by Filippo
06:04 queued 01:17
created

ChunksFilesystem::addTemporaryContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Jobtech\LaravelChunky\Support;
4
5
use Illuminate\Support\Str;
6
use Jobtech\LaravelChunky\Chunk;
7
use Jobtech\LaravelChunky\Events\ChunkAdded;
8
use Jobtech\LaravelChunky\Events\ChunkDeleted;
9
use Jobtech\LaravelChunky\Exceptions\ChunkyException;
10
use Keven\Flysystem\Concatenate\Concatenate;
11
use Symfony\Component\HttpFoundation\File\File;
12
13
class ChunksFilesystem extends FileSystem
14
{
15
    /** {@inheritdoc} */
16
    public function disk($disk = null): ?string
17
    {
18
        if (! empty($disk) && is_string($disk)) {
19
            $this->disk = $disk;
20
        }
21
22
        return $this->disk;
23
    }
24
25
    /** {@inheritdoc} */
26
    public function folder($folder = null): ?string
27
    {
28
        if (! empty($folder) && is_string($folder)) {
29
            $this->folder = $folder;
30
        }
31
32
        return $this->folder;
33
    }
34
35
    /**
36
     * @param string $folder
37
     *
38
     * @return string
39
     */
40
    public function fullPath(string $folder): string
41
    {
42
        $suffix = Str::endsWith($folder, DIRECTORY_SEPARATOR) ? '' : DIRECTORY_SEPARATOR;
43
44
        if (Str::startsWith($folder, $this->folder)) {
45
            return $folder.$suffix;
46
        } elseif (! Str::endsWith($this->folder, $folder.$suffix)) {
47
            return $this->folder.$folder.$suffix;
48
        }
49
50
        return $this->folder;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->folder could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
51
    }
52
53
    /**
54
     * Retrieve every chunks' folder.
55
     *
56
     * @return array
57
     */
58
    public function folders(): array
59
    {
60
        return $this->filesystem()
61
            ->disk($this->disk)
62
            ->directories($this->folder);
63
    }
64
65
    /**
66
     * @param string|null $folder
67
     *
68
     * @return array
69
     */
70
    public function list($folder = null): array
71
    {
72
        $folder = $this->fullPath($folder);
0 ignored issues
show
Bug introduced by
It seems like $folder can also be of type null; however, parameter $folder of Jobtech\LaravelChunky\Su...sFilesystem::fullPath() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

72
        $folder = $this->fullPath(/** @scrutinizer ignore-type */ $folder);
Loading history...
73
74
        return $this->filesystem()
75
            ->disk($this->disk)
76
            ->files($folder);
77
    }
78
79
    /**
80
     * @param \Jobtech\LaravelChunky\Chunk $chunk
81
     * @param string $folder
82
     * @param array $options
83
     *
84
     * @return Chunk
85
     */
86
    public function store(Chunk $chunk, string $folder, $options = []): Chunk
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

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

86
    public function store(Chunk $chunk, string $folder, /** @scrutinizer ignore-unused */ $options = []): Chunk

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
87
    {
88
        if (! $chunk->getOriginalPath() instanceof File) {
89
            throw new ChunkyException('Path must be a file');
90
        }
91
92
        $file = fopen($chunk->getPath(), 'r');
93
        $destination = $this->fullPath($folder).$chunk->getSlug();
94
        $this->filesystem()->disk($this->disk)->put(
95
            $destination, $file
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type false; however, parameter $contents of Illuminate\Filesystem\FilesystemAdapter::put() does only seem to accept resource|string, maybe add an additional type check? ( Ignorable by Annotation )

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

95
            $destination, /** @scrutinizer ignore-type */ $file
Loading history...
96
        );
97
98
        fclose($file);
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

98
        fclose(/** @scrutinizer ignore-type */ $file);
Loading history...
99
100
        $chunk->setPath($destination);
101
102
        event(new ChunkAdded($chunk));
103
104
        return $chunk;
105
    }
106
107
    /**
108
     * Delete all chunks and, once empty, delete the folder.
109
     *
110
     * @param string $folder
111
     *
112
     * @return bool
113
     */
114
    public function delete(string $folder): bool
115
    {
116
        $folder = $this->fullPath($folder);
117
118
        if (! $this->filesystem()->disk($this->disk)->exists($folder)) {
119
            return true;
120
        }
121
122
        foreach ($this->listChunks($folder) as $chunk) {
123
            $this->deleteChunk($chunk);
124
        }
125
126
        $result = $this->filesystem()->disk($this->disk)
127
            ->deleteDirectory($folder);
128
129
        return $result;
130
    }
131
132
    /**
133
     * Delete all chunks and, once empty, delete the folder.
134
     *
135
     * @param string $folder
136
     *
137
     * @return bool
138
     */
139
    public function deleteChunk(Chunk $chunk): bool
140
    {
141
        if (! $this->filesystem()->disk($this->disk)->exists($chunk->getPath())) {
142
            return true;
143
        }
144
145
        $deleted = $this->filesystem()
146
            ->disk($this->disk)
147
            ->delete($chunk->getPath());
148
149
        if ($deleted) {
150
            event(new ChunkDeleted($chunk));
151
        }
152
153
        return $deleted;
154
    }
155
156
    /**
157
     * @param string $folder
158
     * @return \Illuminate\Support\Collection
159
     */
160
    public function listChunks(string $folder)
161
    {
162
        $folder = $this->fullPath($folder);
163
        $files = $this->list($folder);
164
165
        return collect($files)
166
            ->map(function ($path, $key) use ($folder, $files) {
167
                $filename = str_replace($folder, '', $path);
168
                $exploded_name = explode('_', $filename);
169
                $index = array_shift($exploded_name);
170
                $last = count($files) - 1 == $key;
171
172
                return new Chunk(intval($index), $path, $this->disk, $last);
173
            })->sortBy(function (Chunk $chunk) {
174
                return $chunk->getIndex();
175
            });
176
    }
177
178
    /**
179
     * @param string $path
180
     * @return bool
181
     */
182
    public function exists(string $path): bool
183
    {
184
        return $this->filesystem()->disk($this->disk)->exists($path);
185
    }
186
187
    /**
188
     * @param string $folder
189
     * @return int
190
     */
191
    public function chunksCount(string $folder): int
192
    {
193
        $folder = $this->fullPath($folder);
194
195
        return count($this->list($folder));
196
    }
197
198
    /**
199
     * @param string $path
200
     * @return int
201
     */
202
    public function chunkSize(string $path): int
203
    {
204
        return $this->filesystem()->disk($this->disk)->size($path);
205
    }
206
207
    /**
208
     * @param $path
209
     * @return resource|null
210
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
211
     */
212
    public function readChunk($path)
213
    {
214
        return $this->filesystem()->disk($this->disk)->readStream($path);
215
    }
216
217
    /**
218
     * Concatenate all chunks into final merge.
219
     *
220
     * @param string $chunk
221
     * @param array $chunks
222
     * @return bool
223
     */
224
    public function concatenate(string $chunk, array $chunks): bool
225
    {
226
        $this->filesystem()->disk($this->disk)->addPlugin(new Concatenate);
0 ignored issues
show
Bug introduced by
The method addPlugin() does not exist on Illuminate\Contracts\Filesystem\Filesystem. It seems like you code against a sub-type of Illuminate\Contracts\Filesystem\Filesystem such as Illuminate\Filesystem\FilesystemAdapter. ( Ignorable by Annotation )

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

226
        $this->filesystem()->disk($this->disk)->/** @scrutinizer ignore-call */ addPlugin(new Concatenate);
Loading history...
227
228
        return $this->filesystem()->disk($this->disk)->concatenate($chunk, ...$chunks);
0 ignored issues
show
Bug introduced by
The method concatenate() does not exist on Illuminate\Contracts\Filesystem\Filesystem. It seems like you code against a sub-type of Illuminate\Contracts\Filesystem\Filesystem such as Illuminate\Filesystem\FilesystemAdapter. ( Ignorable by Annotation )

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

228
        return $this->filesystem()->disk($this->disk)->/** @scrutinizer ignore-call */ concatenate($chunk, ...$chunks);
Loading history...
229
    }
230
}
231