Passed
Push — dev5 ( 1fbf2b...8c60e2 )
by Ron
09:02
created

FileLinksController   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 302
Duplicated Lines 0 %

Test Coverage

Coverage 97.18%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 134
dl 0
loc 302
ccs 138
cts 142
cp 0.9718
rs 10
c 1
b 0
f 0
wmc 28

14 Methods

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