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