Passed
Push — dev6 ( 1f4a51...d7b093 )
by Ron
16:11
created

FileTrait::deleteFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 10
c 1
b 0
f 0
dl 0
loc 21
rs 9.9332
ccs 3
cts 3
cp 1
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace App\Traits;
4
5
use Illuminate\Http\UploadedFile;
6
use Pion\Laravel\ChunkUpload\Handler\HandlerFactory;
7
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
8
9
use App\Models\FileUploads;
10
use Illuminate\Database\QueryException;
11
use Illuminate\Support\Facades\Log;
12
use Illuminate\Support\Facades\Auth;
13
use Illuminate\Support\Facades\Storage;
14
15
/**
16
 * File Trait assists with processing uploading and moving files
17
 */
18
trait FileTrait
19
{
20
    protected $disk;
21
    protected $folder;
22
23
    /**
24 2
     * Get an uploaded file chunk and process it
25
     */
26 2
    protected function getChunk($request)
27 2
    {
28
        $receiver = new FileReceiver('file', $request, HandlerFactory::classFromRequest($request));
29 2
        $save     = $receiver->receive();
30 2
31
        //  Save a completed upload
32 2
        if($save->isFinished())
33
        {
34 2
            $this->disk   = $request->disk;
35
            $this->folder = $request->folder;
36 2
            $filename     = $this->saveFile($save->getFile());
37
38 2
            $status   = [
39
                'percent'  => 100,
40 2
                'complete' => true,
41
                'filename' => $filename,
42 2
                'disk'     => $request->disk,
43
                'folder'   => $request->folder,
44
            ];
45
46
            Log::debug('File Upload Completed.  Details - ', $status);
47
            return $status;
48
        }
49
50
        $handler = $save->handler();
51
        $status  = [
52
            'percent'  => $handler->getPercentageDone(),
53
            'complete' => false,
54
        ];
55
56 2
        Log::debug('File upload in progress.  Details - ', $status);
57
        return $status;
58 2
    }
59 2
60
    /**
61 2
     * Save the file to the file system
62 2
     */
63 2
    protected function saveFile(UploadedFile $file)
64
    {
65
        $properName = $this->cleanFilename($file->getClientOriginalName());
66
        $fileName   = $this->checkForDuplicate($properName);
67
68
        $file->storeAs($this->folder, $fileName, $this->disk);
69
        return $fileName;
70
    }
71
72
    /**
73
     * Sanitize the filename to remove any spaces or illegal characters
74
     */
75
    protected function cleanFilename($name)
76
    {
77
        $newName =  str_replace(' ', '_', preg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $name));
78
79
        return $newName;
80
    }
81
82
    /**
83
     * Check if the filename already exists.  If it does, append the filename with (number)
84
     */
85
    protected function checkForDuplicate($name)
86 2
    {
87
88 2
        if(Storage::disk($this->disk)->exists($this->folder.DIRECTORY_SEPARATOR.$name))
89 2
        {
90
            $parts = pathinfo($name);
91 2
            $ext   = isset($parts['extension']) ? ('.'.$parts['extension']) : '';
92
            $base  = $parts['filename'];
93
            $number = 0;
94
95 2
96
            do
97 2
            {
98
                $name = $base.'('.++$number.')'.$ext;
99 2
            } while(Storage::disk($this->disk)->exists($this->folder.DIRECTORY_SEPARATOR.$name));
100
        }
101
102
        return $name;
103
    }
104
105
    /**
106
     * Make sure that there is some file data in the users current session - abort if it is missing
107
     */
108
    protected function checkForFile()
109
    {
110
        if(!session()->has('new-file-upload'))
111
        {
112
            Log::critical('File upload information missing', [
113
                'route' => \Request::route()->getName(),
114
                'user'  => Auth::check() ? Auth::user()->username : \Request::ip(),
1 ignored issue
show
Bug introduced by
Accessing username on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
115 2
            ]);
116 2
            abort(500, 'Uploaded File Data Missing');
117
        }
118
    }
119
120 1
    /**
121
     * Move a file from one location to another and store new location in database
122 1
     */
123 1
    // protected function moveStoredFile($fileData, $newDisk, $newFolder)
124
    // {
125
    //     $this->disk   = $newDisk;
126
    //     $this->folder = $newFolder;
127
128 1
129
    // }
130
131
    /**
132
     * Determine if a file is no longer in use, and then delete it from the filesystem
133
     */
134
    protected function deleteFile($fileID)
135
    {
136
        $fileData = FileUploads::find($fileID);
137 1
        $file     = $fileData->only(['disk', 'folder', 'file_name']);
138 1
139
        //  Try to delete the file from the database, if it fails, the file is in use elsewhere
140 1
        try
141
        {
142
            $fileData->delete();
143
        }
144
        catch(QueryException $e)
145
        {
146
            Log::debug('File ID '.$fileID.' is still in use and cannot be deleted');
147
            return false;
148
        }
149
150
        //  Delete the file from file storage
151
        Log::alert('File '.$file['folder'].DIRECTORY_SEPARATOR.$file['file_name'].' has been deleted');
152
        Storage::disk($file['disk'])->delete($file['folder'].DIRECTORY_SEPARATOR.$file['file_name']);
153
154
        return true;
155
    }
156
}
157