laravel 7 - add new images on existing tables - php

I was successful uploading multiple images while inserting a new record. I used two models Car and caralbum and made a join. However, I was trying to create an option to add more images on current list but failed to do so. my codes are-
controller to add new record with multiple images
$car = new Car;
.......
.......
$car->save();
if (count($request->car_image) > 0) {
foreach ($request->car_image as $image) {
........
........
Image::make($image)->save($location);
$caralbum = new caralbum;
$caralbum->car_id = $car->id;
$caralbum->image_name = $image_name;
$caralbum->image_location = $location;
$caralbum->save();
}
}
controller to add additional images
$car = Car::find($id);
if (count($request->car_image) > 0) {
foreach ($request->car_image as $image) {
....
....
Image::make($image)->save($location);
$caralbum = new caralbum;
$caralbum->car_id = $car->id;
$caralbum->image_name = $image_name;
$caralbum->image_location = $location;
$caralbum->save();
blade to add new record with multiple images
<input type="file" name="car_image[]" multiple>
blade to add additional images
<input type="file" name="car_image[]" multiple>
<a class="btn btn-success" href="{{ url('car_store_images/'.$cars->id) }}">
Add Images
</a>

I have found one problem. on the index blade where I am displaying the images the image class was not named as array. After adding [] after it, it is working now.
#foreach ($cars->join_caralbum as $image)
<div class="card" >
<img class="card-img-top" name="car_image[]" src="{{asset($image->image_location)}}" style ="height:90px; width:120px;" >
<a class="btn btn-danger" href="{{ url('car_destroy_image/'.$image->id) }}"
onclick="return confirm('Are you sure you want to delete all images for this car?')"><i class="fas fa-trash fa-xs"></i></a>
</div>
#endforeach

Related

Handle a list of files over laravel CRUD

I'm working on a form where you have to enter all information you need and at the end, on save all information will be saved at the same times. The form have a list of images where you can add, change and delete pictures.
The way it was made is that all inputs refer to the name carousels[]. Adding the file is alright, the problem is that this way I have no way to identify in backend which file I have to delete or change.
I'm wondering if any Laravel master know a better way to handle a list of files over a form the way a need it to work. So I would be able to add new images, replace an old image by a new one and/or delete a specific image.
There are the pieces of code I'm working with.
Frontend:
#php
$carrousel = $Ids = [];
foreach ($offerImages as $index => $image) {
$carrousel[] = $image['image'];
$ids[] = $index;
}
#endphp
#for($i = 0; $i < 4; $i++)
<div class="col-sm-4 error-block">
<div class="{{ (!empty($carrousel[$i])) ? 'fileinput fileinput-exists':'fileinput fileinput-new' }}" data-provides="fileinput">
<div class="fileinput-preview thumbnail" id="banner{{$i}}" data-trigger="fileinput">
<img src="{{ !empty($carrousel[$i]) ? asset($carrousel[$i]) : (url('/') . "/images/default-thumbnail.png") }}"></div>
<div>
<span class="btn btn-secondary btn-sm btn-file">
<span class="fileinput-new ">Select image</span>
<span class="fileinput-exists">Change</span>
<input type="file" name="carrousels[]" id="carrousel{{$i}}">
</span>
Remove
</div>
</div>
</div>
#endfor
Backend
public function update(UpdateRequest $request)
{
try {
$id = $request->id;
$carrouselFolder = config('constants.DEFAULT.UPLOAD_FOLDERS.CARROUSEL');
$carrousels = [];
Log::debug($request->carrousels);
if ($request->carrousels) {
foreach ($request->carrousels as $image) {
if (!empty($image)) {
//upload image
$imageName = generateRandomString(30) . '.' . $image->getClientOriginalExtension();
if ($image->move(public_path($carrouselFolder), $imageName)) {
$image = $carrouselFolder . $imageName;
}
$carrousels[] = $image;
}
}
}
return redirect()->to(route('...'))
->with('toastSuccess', '...');
} catch (\Exception $e) {
return redirect()->back()->with('toastError', $e->getMessage());
}
}
send another parameter with old carousel, retrive it in controller then if both not empty, delete the old image . you can try this
View code
#php
$carrousel = $Ids = [];
foreach ($offerImages as $index => $image) {
$carrousel[] = $image['image'];
$ids[] = $index;
}
#endphp
#for($i = 0; $i < 4; $i++)
<div class="col-sm-4 error-block">
<div class="{{ (!empty($carrousel[$i])) ? 'fileinput fileinput-exists':'fileinput fileinput-new' }}" data-provides="fileinput">
<div class="fileinput-preview thumbnail" id="banner{{$i}}" data-trigger="fileinput">
<img src="{{ !empty($carrousel[$i]) ? asset($carrousel[$i]) : (url('/') . "/images/default-thumbnail.png") }}"></div>
<div>
<span class="btn btn-secondary btn-sm btn-file">
<span class="fileinput-new ">Select image</span>
<span class="fileinput-exists">Change</span>
<input type="text" name="oldcarrousels[{{$i}}]" value="{{ !empty($carrousel[$i]) ?$carrousel[$i] :'' }}">
<input type="file" name="carrousels[{{$i}}]" id="carrousel{{$i}}">
</span>
Remove
</div>
</div>
</div>
#endfor
Controller code
foreach ($request->carrousels as $in=>$image) {
if (!empty($image)) {
if (!empty($request->oldcarrousels[$in]) || $request->oldcarrousels[$in]!='') {
//image deleting code here
}
//upload image
$imageName = generateRandomString(30) . '.' . $image->getClientOriginalExtension();
if ($image->move(public_path($carrouselFolder), $imageName)) {
$image = $carrouselFolder . $imageName;
}
$carrousels[] = $image;
}
}

How to edit image in Laravel 5.7?

I inserted the image in my database, now I am trying to edit the images and the edited image should be deleted from my folder and a new image should be updated there. Could you please help me where I am mistaking?
Here is my Controller.php file
public function edit($slider)
{
$property=Property::all();
$slider = Slider::find($slider);
$data = ['property'=>$property, 'slider'=>$slider];
return view('admin.slider.edit', $data);
}
public function update(Request $r, $id)
{
$slider=Slider::find($id);
if( $r->hasFile('slider_thumb')){
$thums = $r->slider_thumb;
$slider_thumb = uniqid($chr).'.'.$thums->getClientOriginalExtension();
$img = Image::make($thums->getRealPath());
$img->resize(204, 107, function ($constraint) {
$constraint->aspectRatio();
});
$thumbPath = public_path().'/slider_img/'.$slider_thumb;
if (file_exists($thumbPath)) {
$this->removeImage($thumbPath);
}
$img->save($thumbPath);
$optimizerChain = OptimizerChainFactory::create();
$optimizerChain->optimize($thumbPath);
$slider_thumbimg = $slider_thumb;
}else{
$slider_thumb = NULL;
}
$slider->property_id = $r->property_id;
$slider->slider_image=$slider_imageimg;
$slider->save();
return redirect('/admin/slider');
}
}
here is my HTML file
<form class="form-horizontal" method="POST" action="{{ route('slider.update',['id'=>$slider->id]) }}" enctype="multipart/form-data">
#csrf
#method('PUT')
#if($slider->slider_image == NULL or $slider->slider_image == '')
<img src="{{asset('images/no-image-found.jpg')}}" style="width: 100px; height: 100px;">
#else
<img src="{{ asset('slider_img/'.$slider->slider_image) }}" style="width: 100px; height: 80px;">
#endif
<input type="file" name="slider_image" value="{{ $slider->slider_image }}">
<div class="form-group">
<div class="col-sm-12 text-right">
<button type="submit" class="btn btn-info">
<i class="fa fa-check"></i> Save
</button>
</div>
</div>
</form>
You did not use Laravel standards. you need to refer to laravel filesystem document to upload file. then you need to check request file exist. if request has new file; you should remove old file and upload new file. in else you should not remove old file.
follow below code:
public function store(PostRequest $request,string $slug = null)
{
$postData = $request->all();
//upload and set thumbnail of post, if exist
if($request->file("thumbnail")){
$image = new Images();
$thumbnailName = $image->uploadFile($request,"thumbnail",config("upload_image_path.post-thumbnail"));
$postData["thumbnail"] = $thumbnailName;
}
$post = $this->postService->save($postData,$slug);

Display image from the url save in database

Greeting developers,
I was trying to create one database to store images. It stores the URL of that image and the insertion is working fine.
Now I want to display the image stored in the database but it just shows image icon and not display the image. The image is stored in the image folder inside the public folder. I really need a favor. Thanks in advance. Below I attach my code:
Form Controller:
public function store(Request $request)
{
$this->validate($request, [
'filename' => 'required',
'filename.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
if($request->hasfile('filename'))
{
foreach($request->file('filename') as $image)
{
$name=$image->getClientOriginalName();
$image->move(public_path().'/images/', $name);
$data[] = $name;
}
}
$form= new Form();
$form->filename=json_encode($data);
$form->save();
return back()->with('success', 'Your images has been successfully');
}
public function show()
{
$users = DB::select('select * from forms');
return view('display',['users'=>$users]);
}
Insert page
<form method="post" action="{{url('form')}}" enctype="multipart/form-data">
{{csrf_field()}}
<div class="input-group control-group increment" >
<input type="file" name="filename[]" class="form-control">
<div class="input-group-btn">
<button class="btn btn-success" type="button"><i class="glyphicon glyphicon-plus"></i>Add</button>
</div>
</div>
<div class="clone hide">
<div class="control-group input-group" style="margin-top:10px">
<input type="file" name="filename[]" class="form-control">
<div class="input-group-btn">
<button class="btn btn-danger" type="button"><i class="glyphicon glyphicon-remove"></i> Remove</button>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" style="margin-top:10px">Submit</button>
</form>
</div>
<script type="text/javascript">
$(document).ready(function() {
$(".btn-success").click(function(){
var html = $(".clone").html();
$(".increment").after(html);
});
$("body").on("click",".btn-danger",function(){
$(this).parents(".control-group").remove();
});
});
</script>
Display Page:
#foreach ($users as $user)
<img src= url({{url('images/$user->filename')}});}/>
#endforeach
Your are storing multiple filenames as json in filename column in forms table. In blade template you're inserting json in img src instead of single filename. As filenames are stored as json so you need to decode json and run foreach for each filename.
#foreach ($users as $user)
#php $filenames = json_decode($user->filename); #endphp
#foreach ($filenames as $filename)
<img src="{{ url('images/' . $filename) }}"/>
#endforeach
#endforeach
if its json do like this
#foreach ($users as $user)
#php $images = json_decode($user->filename,true); #endphp
#foreach ($images as $image)
<img src="{{ url('images/'.$image) }}"/>
#endforeach
#endforeach
you are encoding the filenames in your controller which is an array so in your blade template you would must decode it first and then loop through it through foreach loop and show it in the img tag. Hope it will help you.

Laravel edit dropzone

I saved files(images) by DropzoneJS and I can get them everywhere I like, but my problem is how to edit them. I go to my products edit page I can see my image but have no idea how to edit them such as (delete some of them or add to them)
here is my code to get them:
public function edit($id)
{
$product = Product::findOrFail($id);
$images = DB::table('images')->where('imageable_id', '=', $product->id)->get();
// rest of codes
}
and I show my images in edit page like:
#foreach($images as $test)
<img src="{{url('/')}}/images/{{$test->name}}" alt="test" width="100" height="100">
#endforeach
screenshot
UPDATE
#linktoahref way works for me if I want to delete each of images, and he suggested to make new uploader for adding images into my product on edit page, not bad idea totally but it's not what I'm exactly looking for.
What I try to achieve is to use DropZone itself to return my exist
images of each product and be able to remove or add to it.
I read many questions,articles, etc. And I get that I have to use mockFile which i have no idea about it. Would be appreciate if someone can help me to get this done.
Thanks.
For DELETE, you could add a button next to the image that would fire the destroy method of the respective controller
#foreach($images as $test)
<img src="{{ url('/') }}/images/{{ $test->name }}" alt="test" width="100" height="100">
<a href="#" class="btn btn-danger"
onclick="event.preventDefault();
document.getElementById('image-{{ $test->id }}').submit();">
DELETE
</a>
<form id="image-{{ $test->id }}"
action="{{ route('images.destroy', ['id' => $test->id]) }}"
method="POST" style="display: none;">
{{ csrf_field() }}
{{ method_field('DELETE') }}
</form>
#endforeach
and handle the deletion of image in your ImageController's destroy method (or your custom controller's method, make sure the method types are same)
public function destroy(Image $image)
{
// Destroy the Image
Storage::delete($image->name);
// Redirect Back
return redirect()->back();
}

Trouble getting the image out from public folder with a one-to-one relationship

I am having some trouble getting the image from the public folder where in the database, I have UserImage table and personal_info table and they are connected together in a one to one relationship. I have tried using this but it just return me blank results.
Here are the codes:
HomeController:
public function getInfo($id) {
$data = personal_info::where('id', $id)->get();
$data3 = UserImage::where('user_id', $id)->get();
return view('test',compact('data', 'data3'));
test.blade.php (where I show the image)
#foreach ($data as $object)
<b>Name: </b>{{ $object->Name }}<br><br>
#foreach ($data3 as $currentUser)
<img src="{{ asset('public/images/' . $currentUser->name ) }}">
#endforeach
#if ($data3->count())
#foreach ($data3 as $currentUser)
<a href="{!! route('user.upload.image', ['id' => $currentUser->user_id]) !!}">
<button class="btn btn-primary">
<i class ="fa fa-plus"></i>Upload Images
</button>
</a>
#endforeach
#else
<a href="{!! route('user.upload.image', ['id' => $object->id]) !!}">
<button class="btn btn-primary">
<i class ="fa fa-plus"></i>Upload Images
</button>
#endif
#endforeach
Create1Controller:
public function store1(Request $request)
{
$this->validate($request, [
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($request->hasFile('file')) {
$image = $request->file('file');
$name = $image->getClientOriginalName();
$size = $image->getClientSize();
$id = $request->user_id;
$destinationPath = public_path('/images');
$image->move($destinationPath, $name);
$userImage = new UserImage;
$personal_info = new personal_info;
$userImage->name = $name;
$userImage->size = $size;
$user = personal_info::find($id);
$user->UserImages()->save($userImage);
}
return redirect('/home');
}
Since you are not saving your assets into storage and saving into your public directory you could use the url() method instead. If you need to stick with asset() you need to create a symlink from the storage directory to the public directory which is explained here, and use the storage directory to save your assets.
As I see, there is no relation between saved image name and the $currentUser->name
Can you show your code you use to save the image? There you have to save the image with current user name.
The error here: $image->move($destinationPath, $name);

Categories