Test Failed
Push — main ( 680892...12263f )
by ikechukwu
12:25
created

FileUpload::saveURLInDB()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Ikechukwukalu\Clamavfileupload\Foundation;
4
5
use Ikechukwukalu\Clamavfileupload\Models\FileUpload as FileUploadModel;
6
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
7
use Illuminate\Contracts\Filesystem\Filesystem;
8
use Illuminate\Http\Request;
9
use Illuminate\Support\Str;
10
use Illuminate\Support\Facades\Crypt;
11
use Illuminate\Support\Facades\Log;
12
use Illuminate\Support\Facades\Storage;
13
14
class FileUpload
15
{
16
    public static Request $request;
17
    public static ?string $name;
18
    public static string $fileName;
19
    public static string $input;
20
    public static string $ref;
21
    public static ?string $folder;
22
    public static string $uploadPath;
23
    public static array $scanData;
24
25
    /**
26
     * Log scan data.
27
     *
28
     * @param  string  $message
29
     * @return  bool
30
     */
31
    public static function logScanData(string $message): void
32
    {
33
        if (config('clamavfileupload.log_scan_data')) {
34
            Log::alert($message);
35
        }
36
    }
37
38
    /**
39
     * Provide \Illuminate\Support\Facades\Storage::build.
40
     *
41
     * @return  \Illuminate\Contracts\Filesystem\Filesystem
42
     */
43
    protected static function provideDisk(): Filesystem
44
    {
45
        return Storage::build([
46
            'driver' => self::getDisk(),
47
            'root' => self::storageDisk()->path(self::$uploadPath),
48
        ]);
49
    }
50
51
    /**
52
     * Save single or multiple files.
53
     *
54
     * @return  bool
55
     * @return  array
56
     */
57
    protected static function storeFiles(): bool|array
58
    {
59
        self::$fileName = self::setFileName();
60
61
        if (is_array(self::$request->file(self::$input))) {
62
            return self::saveMultipleFiles();
63
        }
64
65
        return self::saveSingleFile();
66
    }
67
68
    /**
69
     * Save multiple files.
70
     *
71
     * @param ?string $fileName
72
     * @return  bool
73
     * @return  array
74
     */
75
    protected static function saveMultipleFiles(?string $fileName = null): bool|array
76
    {
77
        $disk = self::provideDisk();
78
79
        $i = 1;
80
        foreach (self::$request->file(self::$input) as $file) {
81
            $disk->putFileAs("", $file, self::$fileName . "_{$i}" .
82
                    self::getExtension($file));
83
            $i ++;
84
        }
85
86
        return true;
87
    }
88
89
    /**
90
     * Save single file.
91
     *
92
     * @param ?string $fileName
93
     * @return  bool
94
     * @return  array
95
     */
96
    protected static function saveSingleFile(?string $fileName = null): bool|array
97
    {
98
        self::provideDisk()->putFileAs("",
99
                self::$request->file(self::$input),
0 ignored issues
show
Bug introduced by
It seems like self::request->file(self::input) can also be of type Illuminate\Http\UploadedFile[] and array; however, parameter $file of Illuminate\Filesystem\Fi...temAdapter::putFileAs() does only seem to accept Illuminate\Http\File|Ill...ttp\UploadedFile|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

99
                /** @scrutinizer ignore-type */ self::$request->file(self::$input),
Loading history...
100
                self::$fileName . self::getExtension());
101
102
        return true;
103
    }
104
105
    /**
106
     * Remove single or multiple files.
107
     *
108
     * @param array $files
109
     * @return  ?bool
110
     */
111
    protected static function removeFiles(array $files = []): ?bool
0 ignored issues
show
Unused Code introduced by
The parameter $files 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

111
    protected static function removeFiles(/** @scrutinizer ignore-unused */ array $files = []): ?bool

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...
112
    {
113
        if (is_array(self::$request->file(self::$input))) {
114
            return self::deleteMultipleFiles();
115
        }
116
117
        return self::deleteSingleFile();
118
    }
119
120
    /**
121
     * Delete multiple files.
122
     *
123
     * @return  bool
124
     */
125
    protected static function deleteMultipleFiles(): bool
126
    {
127
        $i = 1;
128
        foreach (self::$request->file(self::$input) as $file) {
129
            [$fileName, $relativeFilePath] = self::fileNameAndPath($file, $i);
0 ignored issues
show
Comprehensibility Best Practice introduced by
This list assign is not used and could be removed.
Loading history...
130
131
            $file = str_replace(self::storageDisk()
132
                        ->path(self::$uploadPath), '', $file);
133
            self::storageDisk()->delete(self::$uploadPath . $file);
134
135
            $i ++;
136
        }
137
138
        return true;
139
    }
140
141
    /**
142
     * Delete single file.
143
     *
144
     * @return  bool
145
     */
146
    protected static function deleteSingleFile(): bool
147
    {
148
        [$fileName, $relativeFilePath] = self::fileNameAndPath();
0 ignored issues
show
Comprehensibility Best Practice introduced by
This list assign is not used and could be removed.
Loading history...
149
150
        $file = str_replace(self::storageDisk()
151
                ->path(self::$uploadPath), '', self::$request->file(self::$input));
152
        self::storageDisk()->delete(self::$uploadPath . $file);
153
154
        return true;
155
    }
156
157
    /**
158
     * Set UUID ref.
159
     *
160
     * @return  string
161
     */
162
    protected static function setRef(): string
163
    {
164
        return (string) Str::uuid();
165
    }
166
167
    /**
168
     * Get UUID ref.
169
     *
170
     * @param $file
171
     * @param $i
172
     * @return  string
173
     */
174
    protected static function getName($file = null, $i = null): string
175
    {
176
        if ($file && $i) {
177
            return self::$name ? self::$name . "_{$i}"
178
                : $file->getClientOriginalName();
179
        }
180
181
        return self::$name ?? self::$request->file(self::$input)
182
                ->getClientOriginalName();
183
    }
184
185
    /**
186
     * Set file name.
187
     *
188
     * @return  string
189
     */
190
    protected static function setFileName(): string
191
    {
192
        return time() . Str::random(40);
193
    }
194
195
    /**
196
     * Save file name in database.
197
     *
198
     * @param $file
199
     * @return  string
200
     */
201
    protected static function saveFileNameInDB($fileName): string
202
    {
203
        if (config('clamavfileupload.hashed', false)) {
204
            return Crypt::encryptString($fileName);
205
        }
206
207
        return $fileName;
208
    }
209
210
    /**
211
     * Save file name in database.
212
     *
213
     * @param $file
214
     * @return  string
215
     */
216
    protected static function saveURLInDB($relativeFilePath): string
217
    {
218
        if (config('clamavfileupload.hashed', false)) {
219
            return Crypt::encryptString(asset(self::storageDisk()
220
                    ->url($relativeFilePath)));
221
        }
222
223
        return $relativeFilePath;
224
    }
225
226
    /**
227
     * Get extension.
228
     *
229
     * @param $file
230
     * @return  string
231
     */
232
    protected static function getExtension($file = null): string
233
    {
234
        if ($file) {
235
            return '.' . $file->getClientOriginalExtension();
236
        }
237
238
        return '.' . self::$request->file(self::$input)
239
                ->getClientOriginalExtension();
240
    }
241
242
    /**
243
     * Get relative path.
244
     *
245
     * @param $fileName
246
     * @return  string
247
     */
248
    protected static function getRelativeFilePath($fileName): string
249
    {
250
        return self::$uploadPath . "/" . $fileName;
251
    }
252
253
    /**
254
     * Get disk.
255
     *
256
     * @return  string
257
     */
258
    protected static function getDisk(): string
259
    {
260
        return config('clamavfileupload.disk');
261
    }
262
263
    /**
264
     * Get \Illuminate\Support\Facades\Storage::disk.
265
     *
266
     * @return  \Illuminate\Contracts\Filesystem\Filesystem
267
     */
268
    protected static function storageDisk(): Filesystem
269
    {
270
        return Storage::disk(self::getDisk());
271
    }
272
273
    /**
274
     * Get file name and path.
275
     *
276
     * @param $file
277
     * @param $i
278
     * @return  array
279
     */
280
    protected static function fileNameAndPath($file = null, $i = null): array
281
    {
282
        if ($file && $i) {
283
            $fileName = self::$fileName . "_{$i}" . self::getExtension($file);
284
            return [$fileName, self::getRelativeFilePath($fileName)];
285
        }
286
287
        $fileName = self::$fileName . self::getExtension();
288
        return [$fileName, self::getRelativeFilePath($fileName)];
289
    }
290
291
    /**
292
     * Get file model data.
293
     *
294
     * @param $file
295
     * @param $i
296
     * @return  array
297
     */
298
    protected static function getFileModelData($file = null, $i = null): array
299
    {
300
        [$fileName, $relativeFilePath] = self::fileNameAndPath($file, $i);
301
        return [
302
            'ref' => self::$ref,
303
            'name' => self::getName($file, $i),
304
            'file_name' => self::saveFileNameInDB($fileName),
305
            'url' => self::saveURLInDB($relativeFilePath),
306
            'size' => self::storageDisk()->size($relativeFilePath),
307
            'extension' => self::getExtension($file),
308
            'disk' => self::getDisk(),
309
            'mime_type' => self::storageDisk()->mimeType($relativeFilePath),
310
            'path' => self::storageDisk()->path($relativeFilePath),
311
            'folder' => self::$folder,
312
            'hashed' => config('clamavfileupload.hashed', false)
313
        ];
314
    }
315
316
    /**
317
     * Insert multiple files.
318
     *
319
     * @return  \Illuminate\Database\Eloquent\Collection
320
     */
321
    protected static function insertMultipleFiles(): ?EloquentCollection
322
    {
323
        $data = [];
324
        $i = 1;
325
326
        foreach (self::$request->file(self::$input) as $file) {
327
            $data[] = self::getFileModelData($file, $i);
328
            $i ++;
329
        }
330
331
        if (FileUploadModel::insert($data)) {
332
            return FileUploadModel::where('ref', self::$ref)->get();
0 ignored issues
show
Bug Best Practice introduced by
The expression return Ikechukwukalu\Cla...ref', self::ref)->get() could return the type Illuminate\Database\Eloq...Relations\HasOneThrough which is incompatible with the type-hinted return Illuminate\Database\Eloquent\Collection|null. Consider adding an additional type-check to rule them out.
Loading history...
333
        }
334
335
        return null;
336
    }
337
338
    /**
339
     * Insert single file.
340
     *
341
     * @return  \Ikechukwukalu\Clamavfileupload\Models\FileUpload
342
     */
343
    protected static function insertSingleFile(): ?FileUploadModel
344
    {
345
        return FileUploadModel::create(self::getFileModelData());
346
    }
347
}
348