Passed
Push — master ( fabd45...a8694e )
by Ron
03:26 queued 11s
created

FileLinksController   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Test Coverage

Coverage 93.57%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 135
c 1
b 0
f 0
dl 0
loc 290
ccs 131
cts 140
cp 0.9357
rs 9.92
wmc 31

12 Methods

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