I have been reading up on file uploads in Laravel, reading through the documentation and looking at best practices. In my application, I have two instances: an upload area for single files, and an area for uploading multiple files.
The singular one allows users to enter their own file name whereas the multi file upload does not.
The method for uploading a single file
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// Get every extension that we allowed
$all_ext = implode(',', $this->allExtensions());
$this->validate($request, [
'name'=>'required|unique:file_meta_data|min:3|max:40',
'file' => 'required|file|mimes:' . $all_ext . '|max:2048'
]);
// Grab data from the request to fill the necessary fields
$name = $request->get('name');
$department = $request->get('department');
$category = $request->get('category');
$uploadedFile = $request->file('file');
// Get the extension and then use this to work out the file type
$file->size = $uploadedFile->getSize();
$extension = $uploadedFile->getClientOriginalExtension();
$type = $this->getType($extension);
// Create a new instancce of this model
$file = new FileMetaData();
$file->name = $name;
$file->department = $department;
$file->category = $category;
$file->type = $type;
$file->extension = $extension;
// Upload all the given files to Storage, within a specific directory
if ($department != '') {
$path = $file->storeAs('library/' . $department, $name);
$category = null;
} elseif ($category != '') {
$path = $file->storeAs('library/' . $category, $name);
$department = null;
}
// Grab the filepath so we can store it in the database
$file->filepath = $path;
// Finally, check that the file exists and save the model
if (Storage::exists($path)) {
$file->save();
return redirect('editable/templates-and-tools')->with('success', 'File has been added');
}
}
As you can see this takes various attributes and then places the file within storage, in the specified directory.
The multiple uploading method
/**
* Process uploading of multiple files
*
* @param Request $request
* @return void
*/
public function bulkUpload(Request $request)
{
// Get every extension that we allowed
$all_ext = implode(',', $this->allExtensions());
// Initialize a file upload counter
$fileCount = 0;
// Get the category and department from the form
$department = $request->get('department');
$category = $request->get('category');
// Loop through each file and add it to storage
foreach ($request->file('file') as $file) {
// Get the meta data for each file
$name = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$type = $this->getType($extension);
$size = $file->getSize();
// Upload all the given files to Storage, within a specific directory
if ($department != '') {
$path = $file->storeAs('library/' . $department, $name);
$category = null;
} elseif ($category != '') {
$path = $file->storeAs('library/' . $category, $name);
$department = null;
}
// Grab the filepath so we can store it in the database
$file->filepath = $path;
// Create the database entries for the newly uploaded files
FileMetaData::UpdateOrCreate([
'name' => $name,
'department' => $department,
'category' => $category,
'type' => $type,
'extension' => $extension,
'size' => $size,
'filepath' => $path
]);
$fileCount++;
}
return redirect('editable/templates-and-tools')->with('success', $fileCount . ' files have been added');
}
I'm trying to improve these two methods so that they're cleaner and have better overall security. Also, when using the multiple file upload, you can only rename the files by editing the database entry once they're uploaded, via a seperate form.
How could I improve these methods?
Perhaps I should also use a better UI element like a Jquery file uploader?