Passed
Push — dev5 ( 1c1697...6a3ae7 )
by Ron
08:21
created

FileLinksController   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 278
Duplicated Lines 0 %

Test Coverage

Coverage 96.18%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 126
c 1
b 0
f 0
dl 0
loc 278
ccs 126
cts 131
cp 0.9618
rs 10
wmc 30

12 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 4 1
A saveFile() 0 25 2
A createLink() 0 25 4
B store() 0 71 7
A update() 0 21 4
A __construct() 0 8 1
A details() 0 19 2
A index() 0 4 1
A disableLink() 0 10 1
A find() 0 22 3
A show() 0 6 1
A destroy() 0 23 3
1
<?php
2
3
namespace App\Http\Controllers\FileLinks;
4
5
use App\Files;
6
use Carbon\Carbon;
7
use App\FileLinks;
8
use App\FileLinkFiles;
9
use App\CustomerFileTypes;
10
use Illuminate\Support\Str;
11
use Illuminate\Http\Request;
12
use Illuminate\Http\UploadedFile;
13
use Illuminate\Support\Facades\Log;
14
use Illuminate\Support\Facades\Auth;
15
use App\Http\Controllers\Controller;
16
use Illuminate\Support\Facades\Route;
17
use Illuminate\Support\Facades\Storage;
18
use App\Http\Resources\FileLinksCollection;
19
use App\Http\Resources\CustomerFileTypesCollection;
20
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
21
use Pion\Laravel\ChunkUpload\Handler\HandlerFactory;
22
use App\Http\Resources\FileLinks as FileLinksResource;
23
24
class FileLinksController extends Controller
25
{
26
    private $user;
27
28
    //  Only authorized users have access
29 76
    public function __construct()
30
    {
31
        //  Verify the user is logged in and has permissions for this page
32 76
        $this->middleware('auth');
33
        $this->middleware(function($request, $next) {
34 58
            $this->user = auth()->user();
35 58
            $this->authorize('hasAccess', 'Use File Links');
36 40
            return $next($request);
37 76
        });
38 76
    }
39
40
    //  Landing page shows all links that the user owns
41 2
    public function index()
42
    {
43 2
        Log::debug('Route '.Route::currentRouteName().' visited by '.Auth::user()->full_name);
44 2
        return view('links.index');
45
    }
46
47
    //  Ajax call to show the links for a specific user
48 8
    public function find($id)
49
    {
50 8
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
51
52
        //  Verify if the user is trying to pull their own links
53 8
        if($id == 0)
54
        {
55 2
            $id = Auth::user()->user_id;
56
        }
57
        //  If the user is trying to pull someone elses links, they must be able to manage users
58 6
        else if ($id != Auth::user()->user_id)
59
        {
60 4
            $this->authorize('hasAccess', 'manage_users');
61
        }
62
63 6
        $links = new FileLinksCollection(
64 6
            FileLinks::where('user_id', $id)
65 6
                ->withCount('FileLinkFiles')
66 6
                ->orderBy('expire', 'desc')->get()
67
        );
68
69 6
        return $links;
70
    }
71
72
    //  Create a new file link form
73 2
    public function create()
74
    {
75 2
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
76 2
        return view('links.newLink');
77
    }
78
79
    //  Submit the new file link form
80 12
    public function store(Request $request)
81
    {
82 12
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name.'. Submitted Data - ', $request->toArray());
83
84 12
        $request->validate([
85 12
            'name'       => 'required',
86
            'expire'     => 'required',
87
            'customerID' => 'exists:customers,cust_id|nullable'
88
        ]);
89
90 8
        if(!empty($request->file))
91
        {
92 2
            $receiver = new FileReceiver('file', $request, HandlerFactory::classFromRequest($request));
93
94
            //  Recieve and process the file
95 2
            $save = $receiver->receive();
96
97
            //  See if the uploade has finished
98 2
            if($save->isFinished())
99
            {
100 2
                $this->saveFile($save->getFile());
101 2
                return 'uploaded successfully';
102
            }
103
104
            //  Get the current progress
105
            $handler = $save->handler();
106
107
            Log::debug('File being uploaded.  Percentage done - '.$handler->getPercentageDone());
108
            return response()->json([
109
                'done'   => $handler->getPercentageDone(),
110
                'status' => true
111
            ]);
112
        }
113
114
        //  If there are no files being uploaded or the file uploade process is done
115 8
        if(isset($request->_completed) && $request->_completed)
116
        {
117 8
            $linkID = $this->createLink($request);
118 8
            if($request->session()->has('newLinkFile'))
119
            {
120
                //  If there were files uploaded to the link, process them
121 2
                $files = session('newLinkFile');
122 2
                $path = config('filesystems.paths.links').DIRECTORY_SEPARATOR.$linkID;
123
124 2
                foreach($files as $file)
125
                {
126 2
                    $data = Files::find($file);
127
                    //  Move the file to the proper folder
128 2
                    Storage::move($data->file_link.$data->file_name, $path.DIRECTORY_SEPARATOR.$data->file_name);
129
                    //  Update file link in DB
130 2
                    $data->update([
131 2
                        'file_link' => $path.DIRECTORY_SEPARATOR
132
                    ]);
133
                    //  Attach file to the link
134 2
                    FileLinkFiles::create([
135 2
                        'link_id' => $linkID,
136 2
                        'file_id' => $data->file_id,
137 2
                        'user_id' => Auth::user()->user_id,
138 2
                        'upload' => 0
139
                    ]);
140
141 2
                    Log::info('File Added for link ID - '.$linkID.' by '.Auth::user()->full_name.'.  File ID-'.$data->file_id);
142
                }
143
144 2
                $request->session()->forget('newLinkFile');
145
            }
146
147 8
            return response()->json(['link' => $linkID, 'name' => Str::slug($request->name)]);
148
        }
149
150
        return response()->json(['complete' => false]);
151
    }
152
153
    //  Create the new file link
154 8
    private function createLink($data)
155
    {
156 8
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name.'. Submitted Data - ', $data->toArray());
157
158
        //  Generate a random hash to use as the file link and make sure it is not already in use
159
        do
160
        {
161 8
            $hash = strtolower(Str::random(15));
162 8
            $dup  = FileLinks::where('link_hash', $hash)->get()->count();
163 8
        } while($dup != 0);
164
165
        //  Create the new file link
166 8
        $link = FileLinks::create([
167 8
            'user_id'      => Auth::user()->user_id,
168 8
            'cust_id'      => $data->customerID,
169 8
            'link_hash'    => $hash,
170 8
            'link_name'    => $data->name,
171 8
            'expire'       => $data->expire,
172 8
            'allow_upload' => isset($data->allowUp) && $data->allowUp ? true : false,
173 8
            'note'         => $data->note
174
        ]);
175
176 8
        Log::info('File Link Created for '.Auth::user()->full_name.'.  Link ID-'.$link->link_id);
177
178 8
        return $link->link_id;
179
    }
180
181
    //  Save a file attached to the link
182 2
    private function saveFile(UploadedFile $file)
183
    {
184 2
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
185
186 2
        $filePath = config('filesystems.paths.links').DIRECTORY_SEPARATOR.'_tmp';
187
188
        //  Clean the file and store it
189 2
        $fileName = Files::cleanFilename($filePath, $file->getClientOriginalName());
190 2
        $file->storeAs($filePath, $fileName);
191
192
        //  Place file in Files table of DB
193 2
        $newFile = Files::create([
194 2
            'file_name' => $fileName,
195 2
            'file_link' => $filePath.DIRECTORY_SEPARATOR
196
        ]);
197 2
        $fileID = $newFile->file_id;
198
199
        //  Save the file ID in the session array
200 2
        $fileArr = session('newLinkFile') != null ? session('newLinkFile') : [];
201 2
        $fileArr[] = $fileID;
202 2
        session(['newLinkFile' => $fileArr]);
203
204
        //  Log stored file
205 2
        Log::info('File Stored by '.Auth::user()->user_id, ['file_id' => $fileID, 'file_path' => $filePath.DIRECTORY_SEPARATOR.$fileName]);
206 2
        return $fileID;
207
    }
208
209
    //  Show details about a file link
210 4
    public function details($id, /** @scrutinizer ignore-unused */ $name)
211
    {
212 4
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
213
214
        //  Verify that the link is a valid link
215 4
        $linkData = FileLinks::find($id);
216 4
        $fileTypes = new CustomerFileTypesCollection(CustomerFileTypes::all());
217
218
        //  If the link is invalid, return an error page
219 4
        if(empty($linkData))
220
        {
221 2
            Log::warning('User '.Auth::user()->full_name.' tried to view bad file link', ['user_id' => Auth::user()->user_id, 'link_id' => $id]);
222 2
            return view('links.badLink');
223
        }
224
225 2
        return view('links.details', [
226 2
            'link_id'    => $linkData->link_id,
227 2
            'cust_id'    => $linkData->cust_id,
228 2
            'file_types' => $fileTypes
229
        ]);
230
    }
231
232
    //  Ajax call te get JSON details of the link
233 2
    public function show($id)
234
    {
235 2
        $linkData = new FileLinksResource(FileLinks::find($id));
236
237 2
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
238 2
        return $linkData;
239
    }
240
241
    //  Update the link's details
242 6
    public function update(Request $request, $id)
243
    {
244 6
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name.'. Submitted Data - ', $request->toArray());
245
246 6
        $request->validate([
247 6
            'name'       => 'required',
248
            'expire'     => 'required',
249
            'customerTag' => 'exists:customers,cust_id|nullable'
250
        ]);
251
252 2
        FileLinks::find($id)->update([
253 2
            'link_name'    => $request->name,
254 2
            'expire'       => $request->expire,
255 2
            'allow_upload' => isset($request->allowUpload) && $request->allowUpload ? true : false,
256 2
            'cust_id'      => $request->customerTag,
257 2
            'note'         => $request->hasInstructions ? $request->instructions : null
258
        ]);
259
260 2
        Log::info('File Link Updated by '.Auth::user()->full_name, ['link_id' => $id]);
261
262 2
        return response()->json(['success' => true]);
263
    }
264
265
    //  Disable a file linke, but do not remove it (set the expire date to a previous date)
266 2
    public function disableLink($id)
267
    {
268
        //  update the expire date for the link
269 2
        FileLinks::find($id)->update([
270 2
            'expire' => Carbon::yesterday()
271
        ]);
272
273 2
        Log::info('User '.Auth::user()->full_name.' disabled link ID - '.$id);
274 2
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
275 2
        return response()->json(['success' => true]);
276
    }
277
278
    //  Delete a file link
279 2
    public function destroy($id)
280
    {
281
        //  Remove the file from database
282 2
        $data = FileLinkFiles::where('link_id', $id)->get();
283 2
        if(!$data->isEmpty())
284
        {
285 2
            foreach($data as $file)
286
            {
287 2
                $fileID = $file->file_id;
288 2
                $file->delete();
289
290
                //  Delete the file if it is no longer in use
291 2
                Files::deleteFile($fileID);
292
            }
293
        }
294
295 2
        FileLinks::find($id)->delete();
296
297 2
        Log::debug('Route ' . Route::currentRouteName() . ' visited by ' . Auth::user()->full_name);
298 2
        Log::info('File link deleted by '.Auth::user()->full_name, ['link_id' => $id, 'user_id' => Auth::user()->user_id]);
299
300 2
        return response()->json([
301 2
            'success' => true
302
        ]);
303
    }
304
}
305