Passed
Push — master ( 1d6d9a...2a90e7 )
by Ron
02:47 queued 12s
created

FilesDomain   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Test Coverage

Coverage 77.19%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
dl 0
loc 133
ccs 44
cts 57
cp 0.7719
rs 10
c 1
b 0
f 0
wmc 15

7 Methods

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