Laravel multiple file upload for a single item with validation - ajax

I'm trying to upload multiple files for a single row using Laravel and Ajax. For a single image, it works good, but when I try to upload multiple images, always getting error: "The file must be a file of type: jpeg, png, bmp, gif, svg, docx, xlsx, pdf."
I want to do something like that:
id | client_id | files
---|-----------|------
1 | 1 | image.png, test.pdf
---|-----------|------
2 | 2 | imag3.png, test.docx
tasks.blade.php
<form method="post" id="addTask_form" name="addtask" enctype="multipart/form-data">
..........
<div class="form-group">
<label>File</label>
<input type="file" name="file[]" id="file" multiple />
</div>
TasksController.php
$validation = Validator::make($request->all(), [
'employee_id' => 'required',
.......
'file' => 'nullable|mimes:jpeg,png,bmp,gif,svg,docx,xlsx,pdf',
]);
if($request->hasFile('file')){
$image = $request->file('file');
$data = [];
foreach ($image as $img) {
$new_name = rand() . '.' . $img->getClientOriginalExtension();
$img->move(public_path('uploads'), $new_name);
$data[] = $new_name;
$task = Task::find($request->get('task_id'));
$task->employee_id = $request->get('employee_id');
..............
$task->file = json_encode($data);
$task->save();
}
}
Than, I need to get each value of array as a separated string in my datatable in order that it can be clickable. For example:
id | client_id | files
---|-----------|------
1 | 1 | 287319667.jpg | 2074802246.jpg
---|-----------|------
2 | 2 | 2074802246.jpg | 2074802246.jpg
Here is my datatable column:
return Datatables::of($tasks)
->editColumn('link', function ($link) {
return '<a href="public/uploads/'.$link->file.' >'.$link->file.'</a>';
})
and it returns full array like: ["287319667.jpg","2074802246.jpg"]
So, I need to show like that: 287319667.jpg | 2074802246.jpg.
Thank you in advance

What you're doing will work for single file if you want to validate multiple file use this
'file.*' => 'required|file|mimes:xlsx,xls,csv,jpg,jpeg,****'

Related

LARAVEL Get file Content and split to save in another table

Hi everyone I need your help on how to split value from textarea and insert in a users table using laravel, I was able to get file content = "name | username | password", I need to split each value so I ca save it to a users table the file itself is save in a different table, should I put it in a different method or just specify my target table in the same as the file will be saved? Your help will be much appreciated.
UploadController:
public function store(Request $request){
$validator = Validator::make(
$request->all(),
['filename' => 'required|mimes:txt,jpeg,png,jpg,bmp|max:2048']
);
if ($validator->fails()) {
return back()->withErrors($validator->errors());
}
// if validation success
if ($file = $request->file('filename')) {
$filename = 'uploaded-here.' . $file->getClientOriginalExtension();
//stored in laravel local storage
$target_path = $file->storeAs('uploaded-here/', $filename);
if ($file->move($target_path, $filename)) {
// save file name in the database
$file = File::create(['filename' => $filename]);
return back()->with("success", "File uploaded successfully");
}
}
}
html code:
<div class="form-group" {{ $errors->has('filename') ? 'has-error' : '' }}>
<label for="filename"></label>
<input type="file" name="filename" id="filename" class="form-control">
<span class="text-danger"> {{ $errors->first('filename') }}</span>
<textarea id="editor" name="editor></textarea>
</div>
<button type="submit" class="btn btn-success btn-md"> Upload </button>
js
window.onload = function() {
var doc = document.getElementById('filename');
if (doc) {
doc.addEventListener('change', getFile);
}
}
function getFile(event) {
const input = event.target
if ('files' in input && input.files.length > 0) {
placeFileContent(
document.getElementById('editor'),
input.files[0])
}
}
function placeFileContent(target, file) {
readFileContent(file).then(content => {
target.value = content
}).catch(error => console.log(error))
}
function readFileContent(file) {
const reader = new FileReader()
return new Promise((resolve, reject) => {
reader.onload = event => resolve(event.target.result)
reader.onerror = error => reject(error)
reader.readAsText(file)
})
}
There is an error. Quotation closed sign is missing in name attribute of textarea.
<textarea id="editor" name="editor"></textarea>
You can split using JavaScipt's split() method. Like follwoing:
Say, you have the textarea value as your given format: name | email | password
as you have given example: example errol | errol.boneo13#gmail.com | password123.
Let's say, you have get the textarea value,
var textValue = document.getElementById('editor').value;
textValue = textValue .split(" | ");
var name = textValue [0];
var email = textValue [1];
var password = textValue [2];
Hope it helps....
EDIT::
As you wanted to do in laravel, you can do like following:
$textValue = $request->editor;
$textValue = explode(" | ", $textValue );
$name = $textValue [0];
$email = $textValue [1];
$password = $textValue [2];

Uploading files with infyom generator

I am trying to upload a file with laravel using the code generated by the infyom generator. The file seems to be uploaded but this is what is shown on the application when I view the report (C:\xampp\tmp\php7925.tmp). Provided below is the code for my application.
Thank you so much and really appreciate the help in this project.
rgds,
Form
<!-- Inf File Field -->
<div class="form-group col-sm-6">
{!! Form::label('inf_file', 'Attachments:') !!}
{!! Form::file('inf_file') !!}
</div>
Controller
{
$input = $request->all();
$infrastructure = $this->infrastructureRepository->create($input);
$file = $request->file('inf_file');
$file = $request->inf_file;
if ($request->hasFile('inf_file')){
//
if ($request->file('inf_file')->isValid()){
}
}
Flash::success('Infrastructure saved successfully.');
return redirect(route('infrastructures.index'));
}
This is how you display when you view your records,
<!-- Inf File Field -->
<div class="form-group">
{!! Form::label('inf_file', 'Attachements:') !!}
<a download href="{{ asset($infrastructure->inf_file) }}">Download</a>
</div>
Managed to solve it.
public function store(CreateinfrastructureRequest $request)
{
$input = $request->all();
if ($request->hasFile('inf_file')){
//Validate the uploaded file
$Validation = $request->validate([
'inf_file' => 'required|file|mimes:pdf|max:30000'
]);
// cache the file
$file = $Validation['inf_file'];
// generate a new filename. getClientOriginalExtension() for the file extension
$filename = 'Infras-' . time() . '.' . $file->getClientOriginalExtension();
// save to storage/app/infrastructure as the new $filename
$InfrasFileName = $file->storeAs('infrastructure', $filename);
$path = "/storage/app/public/".$InfrasFileName;
}
$input['inf_file'] = $path;
$infrastructure = $this->infrastructureRepository->create($input);
Flash::success('Infrastructure saved successfully. ' . $path);
return redirect(route('infrastructures.index'));
}

How to create a two steps form in Laravel Nova?

First step - create a new a Gallery (Name and Type).
Click 'Next' button.
Second step - upload multiple images to that gallery.
What can I do in order to achieve that in Laravel Nova admin panel? I can't follow documentation and just add HasMany::make('Images') to a Gallery resource, I need a two steps form.
If I understand right first step you need to make from view input <input type="file" multiple>
than send request and in your controller you need something like this:
$date = Carbon::now()->format('Y-m-d-hh-mm-ss');
$files = request('images');
$pluss = 1;
foreach ($files as $file) {
$imageName = $date . '.' . $pluss . $file->getClientOriginalExtension();
$file->move(public_path('/images/products'), $imageName);
$pluss++;
$data = [
'image' => $imageName,
'product_id' => $product->id
];
Image::create($data);
}

Download files in zip using ZipArchive

I want to download files in zip. How can I do this? I tried, but error occurred.
I have a table name is articles:
id | volume_id | image
5 | 9 | file1.pdf
6 | 9 | file2.pdf
I want to download file1.pdf and file2.pdf in zip based on volume_id
viewarticles.blade.php is:
Download ZIP
web.php is:
Route::get('create-zip/{volume_id}', 'foruserview#createzip')->name('create-zip');
controller is:
use App\article;
use ZipArchive;
public function createzip($volume_id)
{
$articles = article::where('volume_id',$volume_id)->get();
$file= public_path(). "/storage/upload_pic/";
$zipFileName = 'AllDocuments.zip';
$zip = new ZipArchive;
if ($zip->open($file . '/' . $zipFileName, ZipArchive::CREATE) === TRUE) {
foreach($articles as $article) {
$images = $article->image;
$zip->addFile($file, $images);
}
$zip->close();
}
// Set Header
$headers = array(
'Content-Type' => 'application/octet-stream',
);
$filetopath=$file.'/'.$zipFileName;
// Create Download Response
if(file_exists($filetopath)){
return response()->download($file,$zipFileName,$headers);
}
}
After click on download button. Zip file of both images related with volume_id should be download.
But error occurs:
ErrorException (E_WARNING)
ZipArchive::close(): Read error: No such file or directory

How to store multiple images paths into database in laravel?

I am working on multiple image upload in laravel. Uploading is successful but, i got an issue. For later use i should store in database. For single column it easy but for different column for different images i couldnot do it.
Here is my image upload code
$images = [];
$destDir = "public/uploads/";
if($request->file('image1')) $images[]=$request->file('image1');
if($request->file('image2')) $images[]=$request->file('image2');
if($request->file('image3')) $images[]=$request->file('image3');
foreach($images as $image)
{
if(!empty($image))
{
$imageName = $image->getClientOriginalName();
$extension = $image->getClientOriginalExtension();
$temPath = $image->getRealPath();
$enImg = mt_rand(1111,9999).".".$extension;
$newPath = $destDir.$enImg.".".$extension;
move_uploaded_file($temPath, $newPath);
}
}
I have a feeling you are approaching this in a way that is making it more difficult for you. Instead of creating multiple separate file inputs in your form you can only set a multiple file input and set the name of the input to an array like so:
<form action="demo_form.asp">
Images: <input type="file" name="images[]" multiple>
<input type="submit">
</form>
Then in your php you can do something like this:
if (isset($request->all()['images'])) {
$this->persistUserImages($request->all()['images'], $userId);
}
/**
* Persists user images to storage and DB
*
* #param array $userImages
* #param int $userId
* #return array
*/
private function persistUserImages(array $userImages, $userId = 1)
{
if (empty($userImages)) {
return [];
}
$uploadedUserImagesFilenames = $this->uploadUserImagesToCloud($userImages, $userId);
foreach ($uploadedUserImagesFilenames as $filename) {
$userImage = new UserImage([
'user_id' => $userId,
'filename' => $filename,
'visible' => 1
]);
$userImage->save();
}
}
You can do like this this. In your blade,
<form action="{{url('path')}}" methos="post" enctype="multipart/form-data">
Images: <input type="file" name="images[]" multiple>
<input type="submit">
</form>
In you method,
public function store(Request $request){
foreach ( $request->images as $image) {
Model::create([
'image_url' => $image,
]);
}
}
Or
follow below link. It's very easy way to solve this problem.
Multiple Image Upload In Laravel
Hope you can solved your problem.
create a pivot table and store images in separate rows..
Table schema:- `images` table
columns `id`,`user_id`(foreign key),`image_path`
store your $newPath in this table every time..

Resources