Passed
Pull Request — master (#86)
by Ron
29:18
created

FilesDomain   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Test Coverage

Coverage 77.59%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
dl 0
loc 134
ccs 45
cts 58
cp 0.7759
rs 10
c 1
b 0
f 0
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A isFileDup() 0 30 5
A cleanFilename() 0 7 1
A moveFile() 0 21 2
A saveFile() 0 16 2
A processFileChunk() 0 12 2
A deleteFile() 0 22 2
1
<?php
2
3
namespace App\Domains;
4
5
use Illuminate\Http\UploadedFile;
6
use Illuminate\Support\Facades\Log;
7
use Illuminate\Support\Facades\Auth;
8
use Illuminate\Support\Facades\Storage;
9
10
use App\Files;
11
12
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
13
use Pion\Laravel\ChunkUpload\Handler\HandlerFactory;
14
15
class FilesDomain
16
{
17
    protected $receiver, $path, $fileID;
18
19
    //  Constructor will set a default path location in the event one is not set through child class
20 44
    public function __construct()
21
    {
22 44
        $this->path = config('filesystems.paths.default');
23 44
    }
24
25
    //  Process a file chunk
26 6
    protected function processFileChunk($data, $public = false)
27
    {
28 6
        $this->receiver = new FileReceiver('file', $data, HandlerFactory::classFromRequest($data));
29
30 6
        $save = $this->receiver->receive();
31 6
        if($save->isFinished())
32
        {
33 6
            $fileID = $this->saveFile($save->getFile(), $public);
34 6
            return $fileID;
35
        }
36
37
        return false;
38
    }
39
40
    //  Save a file after it has been uploaded
41 18
    protected function saveFile(UploadedFile $file, $public = false)
42
    {
43 18
        $fileName = $this->cleanFilename($file->getClientOriginalName());
44 18
        $fileName = $this->isFileDup($fileName);
45 18
        $file->storeAs($this->path, $fileName);
46
47
        //  Place file in Files table of DB
48 18
        $newFile = Files::create([
49 18
            'file_name' => $fileName,
50 18
            'file_link' => $this->path.DIRECTORY_SEPARATOR,
51 18
            'public'    => $public,
52
        ]);
53
54 18
        $user = isset(Auth::user()->full_name) ? Auth::user()->full_name : \Request::ip();
55 18
        Log::info('New file stored in database by '.$user.'. File Data - ', array($newFile));
56 18
        return  $newFile->file_id;
57
    }
58
59
    //  Try to delete a file - note this will fail if it is still in use
60 4
    protected function deleteFile($fileID)
61
    {
62 4
        $fileData = Files::find($fileID);
63 4
        $fileLink = $fileData->file_link.$fileData->file_name;
64
65
        try
66
        {
67
            //  Try to delete file from database - will throw error if foreign key is in use
68 4
            $fileData->delete();
69
        }
70
        catch(\Illuminate\Database\QueryException $e)
71
        {
72
            //  Unable to remove file from the database
73
            Log::warning('Attempt to delete file failed.  Reason - '.$e.'. Additional File Data - ', ['file_id' => $fileID, 'file_name' => $fileLink, 'user_id' => Auth::user()->user_id]);
74
            return false;
75
        }
76
77
        //  Delete the file from the storage system
78 4
        Storage::delete($fileLink);
79
80 4
        Log::notice('File deleted by '.Auth::user()->full_name.'. File Information - ', ['file_id' => $fileID, 'file_name' => $fileLink, 'user_id' => Auth::user()->user_id]);
81 4
        return true;
82
    }
83
84
    //  Clean a file name to remove any spaces
85 18
    protected function cleanFilename($name)
86
    {
87
        //  Remove all spaces
88 18
        $fileName = str_replace(' ', '_', $name);
89 18
        Log::debug('Cleaning filename.  Old name - '.$name.'.  New Name - '.$fileName);
90
91 18
        return $fileName;
92
    }
93
94
    //  Determine if the already exists and should be appended
95 18
    protected function isFileDup($fileName)
96
    {
97
        //  Determine if the filename already exists
98 18
        if(Storage::exists($this->path.DIRECTORY_SEPARATOR.$fileName))
99
        {
100
            $fileParts = pathinfo($fileName);
101
            $extension = isset($fileParts['extension']) ? ('.'.$fileParts['extension']) : '';
102
103
            //  Look to see if a number is already appended to a file.  (example - file(1).pdf)
104
            if(preg_match('/(.*?)(\d+)$/', $fileParts['filename'], $match))
105
            {
106
                // Has a number, increment it
107
                $base = $match[1];
108
                $number = intVal($match[2]);
109
            }
110
            else
111
            {
112
                // No number, add one
113
                $base = $fileParts['filename'];
114
                $number = 0;
115
            }
116
117
            //  Increase the number until one that is not in use is found
118
            do
119
            {
120
                $fileName = $base.'('.++$number.')'.$extension;
121
            } while(Storage::exists($this->path.DIRECTORY_SEPARATOR.$fileName));
122
        }
123
124 18
        return $fileName;
125
    }
126
127
    //  When multiple files are uploaded at once, they are placed in a temporary location.  This moves them to the final folder
128 6
    protected function moveFile($newPath, $fileID)
129
    {
130 6
        $data = Files::find($fileID);
131
        //  Move the file to the proper folder
132
        try {
133 6
            Log::debug('Attempting to moving file '.$fileID.' to '.$newPath);
134 6
            Storage::move($data->file_link.$data->file_name, $newPath.DIRECTORY_SEPARATOR.$data->file_name);
135
        }
136 2
        catch(\Exception $e)
137
        {
138 2
            report($e);
139 2
            return false;
140
        }
141 4
        Log::info('Moved file '.$data->file_name.'from '.$data->file_link.' to new location - '.$newPath.'.  File Details - ', array($data));
142
143
        //  Update file link in DB
144 4
        $data->update([
145 4
            'file_link' => $newPath.DIRECTORY_SEPARATOR
146
        ]);
147
148 4
        return true;
149
    }
150
}
151