Image saving as tmp in database in Laravel 8 - laravel

Blade File
<form action="{{route('sproduct.store')}}" method="post" enctype="multipart/form-data"
class="w-75 mx-auto mt-5 mb-5">
#csrf
<div class="form-group mt-2 mb-2">
<label for="formgroupexampleinput">Select Product</label>
<select name="products" id="products">
<option>Select Product</option>
#foreach ($products as $product)
<option value="{{$product->id}}">{{$product->title}}</option>
#endforeach
</select>
</div>
<div class="form-group mt-3 mb-3">
<label for="formgroupexampleinput">Display Images</label>
<input type="file" name="file[]" multiple>
</div>
<input type="submit" class="form-control btn-primary w-25" value="Submit">
</form>
Fuction
public function store(Request $request)
{
if ($request->hasfile('file')) {
foreach ($request->file as $file) {
$fileExt = $file->getClientOriginalExtension();
$image_name = "img_".rand(123456,999999). "." .$fileExt;
$destination_path = public_path('/uploads/products_images/display_images');
$file->move($destination_path, $image_name);
$image = new Image();
$image->image = $file;
$image->product_id = $request->products;
$image->save();
}
return "done";
}
}
Question
hi, I am trying to add images to my images table but the image is saving as a tmp file in the database but saving as a jpg in the given folder. I don't know the solution to this. Please let me know why this is happening and how to fix it.
Thankyou in Advance.

mikenenter code here in comment told me I needed to save the name of the file.
public function store(Request $request)
{
if ($request->hasfile('file')){
foreach ($request->file as $file) {
$fileExt = $file->getClientOriginalExtension();
$image_name = "img_".rand(123456,999999). "." .$fileExt;
$destination_path = public_path('/uploads/products_images/display_images');
$file->move($destination_path, $image_name);
$image = new Image();
$image->image = $image_name;
$image->product_id = $request->products;
$image->save();
}
return "done";
}
}

Related

CRUD Laravel Update in database one to many relationship

I have a CRUD app with cars and for every car I have fields to create a car and images to upload. Everithing is ok, I have one to many relationship and for a car I can have multiple images . When I create a car and I upload photos these photos are stored correctly in database and in my public/images director. The problem is when I want to make the UPDATE par, I don't know how to update the photos in database.
Here is my code, I have update function where I don't know exactly how to make the update .
My cars table:
Schema::create('cars', function (Blueprint $table) {
$table->id();
$table->string('model');
$table->integer('seats');
$table->string('fuel');
$table->integer('year');
$table->string('color');
$table->string('gearbox');
$table->integer('price');
$table->string('coinType');
$table->timestamps();
});
My images table
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->integer('car_id');
$table->string('file_name');
$table->timestamps();
});
My Car model:
class Car extends Model
{
protected $fillable = [
'model',
'seats',
'fuel',
'year',
'color',
'gearbox',
'price',
'coinType',
];
public function images()
{
return $this->hasMany(Image::class);
}
use HasFactory;
}
My Image model:
class Image extends Model
{
protected $fillable = [
'car_id',
'file_name'
];
public function car()
{
return $this->belongsTo(Car::class);
}
use HasFactory;
}
My edit.blade:
#extends('layouts.app')
#section('content')
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h2 class="display-3">Edit a car</h2>
<div>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div><br />
#endif
<form method="post" action="{{ url('cars/'. $res->id) }}" enctype="multipart/form-data">
#csrf
#method('PUT')
<div class="form-group">
<legend>
<label for="model" class="col-form-label">Model :</label>
<input type="text" class="form-control" id="model" name="model" value="{{ $res->model }}">
</legend>
</div>
<div class="form-group ">
<legend>
<label for="seats" class="col-form-label">Seats :</label>
</legend>
<select name="seats" id="seats" value="{{ $res->seats }}">
<option value="2">2</option>
<option value="4" selected="selected">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="fuel" class="col-form-label">Fuel :</label>
</legend>
<select name="fuel" id="fuel" value="{{ $res->fuel }}">
<option value="benzine+gpl">benzine+gpl</option>
<option value="gpl" selected="selected">diesel</option>
<option value="diesel">gpl</option>
<option value="diesel+gpl">diesel+gpl</option>
<option value="benzine">benzine</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="year" class="col-form-label">Year :</label>
</legend>
<input type="text" name="year" id="year" value="{{ $res->year }}">
</div>
<div class="form-group">
<legend>
<label for="color" class="col-form-label">Color :</label>
</legend>
<input type="text" class="form-control" id="color" name="color" value="{{ $res->color }}">
</div>
<div class="form-group ">
<legend>
<label for="gearbox" class="col-form-label">Gearbox :</label>
</legend>
<select name="gearbox" id="gearbox" value="{{ $res->gearbox }}">
<option value="manual">manual</option>
<option value="automatic" selected="selected">automatic</option>
<option value="semiautomatic">semiautomatic</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="price" class="col-form-label">Price :</label>
</legend>
<input type="text" class="form-control" id="price" name="price" value="{{ $res->price }}">
</div>
<div class="form-group ">
<legend>
<label for="coinType" class="col-form-label">CoinType :</label>
</legend>
<select name="coinType" id="coinType" value="{{ $res->coinType }}">
<option value="EUR">EUR</option>
<option value="LEI" selected="selected">LEI</option>
<option value="USD">USD</option>
</select>
</div>
<div class="form-group ">
<legend>
<label for="image" class="col-form-label">Upload images :</label>
</legend>
<input type="file" class="form-control" name="images[]" multiple />
</div>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="col-xs-12 col-sm-12 col-md-12 ">
<button type="submit" class="btn btn-primary">Add car</button>
<a class="btn btn-primary" href="{{ route('cars.index') }}"> Back</a>
</div>
</div>
</form>
#endsection
My Controller:
public function store(Request $request)
{
$request->validate([
'model' => 'required',
'year' => 'required',
'color' => 'required',
'price'=> 'required',
'file_name.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
$destionationPath = public_path('/images');
$images = [];
$car = new Car();
$car->model = $request->model;
$car->seats = $request->seats;
$car->fuel = $request->fuel;
$car->year = $request->year;
$car->color = $request->color;
$car->gearbox = $request->gearbox;
$car->price = $request->price;
$car->coinType = $request->coinType;
$car->save();
if ($files = $request->file('images')) {
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
}
foreach ($images as $imag) {
$image = new Image();
$image->car_id = $car->id;
$image->file_name = $imag;
$image->save();
}
return redirect()->route('cars.index')->with('success', 'Car saved !');
}
public function update(Request $request, $id)
{
$request->validate([
'model' => 'required',
'year' => 'required',
'color' => 'required',
'price'=> 'required',
'file_name.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
$destionationPath = public_path('/images');
$images = [];
$car = Car::find($id);
$car->model = $request->model;
$car->seats = $request->seats;
$car->fuel = $request->fuel;
$car->year = $request->year;
$car->color = $request->color;
$car->gearbox = $request->gearbox;
$car->price = $request->price;
$car->coinType = $request->coinType;
$car->update();
if ($files = $request->file('images')) {
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
}
foreach ($images as $imag) {
//here I don't know what to do
}
return redirect()->route('cars.index')->with('success', 'Car updated !');
}
Thank you.
Looking at your blade file, you don't really show the original images, so the user can't update the images, he can insert new images and the old ones should be deleted, right?
If you want to update the image, you have to show the original images on the blade file with it's ID, so in the backend you can find the image based on the ID
But this should work for you now:
you can just check if the user uploaded any file
if ($files = $request->files('images')) {
...
delete all the old images
$car->images->each(function($image) {
// You probabily should be using Storage facade for this
// this should be the full path, I didn't test it, but if you need add extra methods so it returns the full path to the file
if (file_exists($destionationPath . '/' . $image->file_name) {
unset($destionationPath . '/' . $image->file_name);
}
$image->delete();
});
And then recreate the images like you do on store
foreach ($files as $file) {
$fileName = $file->getClientOriginalName();
$file->move($destionationPath, $fileName);
$images[] = $fileName;
}
foreach ($images as $imag) {
$image = new Image();
$image->car_id = $car->id;
$image->file_name = $imag;
$image->save();
}

Call to a member function getClientOriginalName() on array

I have a multiple image. When I upload multiple image. I get this error.
Call to a member function getClientOriginalName() on array
my blade
<form action="{{ route('design-studios.store') }}" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" value="{{ old('title') }}">
</div>
//......
<div class="form-group">
<fieldset class="border p-3">
<legend>Slideshow</legend>
<div class="form-group">
<label for="sliders">Image</label>
<input id="sliders" name="sliders[]" type="file" multiple class="form-control">
</div>
</fieldset>
</div>
</form>
My Controller.
public function store(Request $request)
{
$design_studio = new DesignStudio;
$design_studio->user_id = 1;
$design_studio->title = $request->title;
$design_studio->lang = $request->lang;
$design_studio->body = $request->body;
if($request->has('image')) {
$image = $request->file('image');
$filename = $image->getClientOriginalName();
$image->move(public_path('images/design-studio'), $filename);
$design_studio->image = $request->file('image')->getClientOriginalName();
}
if ($sliders = $request->file('sliders')) {
foreach ($sliders as $slider) {
$filename = $slider->getClientOriginalName();
$slider->move(public_path('images/design-studio'), $filename);
$design_studio->sliders = $request->file('sliders')->getClientOriginalName();
}
}
$design_studio->save();
$design_studio->categories()->attach($request->category);
return redirect()->route('design-studios.index');
}
My Model
protected $casts = [
'sliders' => array()
];
I get this error.
Call to a member function getClientOriginalName() on array
Here you need to call that method on the file you are looping through instead of trying to call it on the array of files.
$design_studio->sliders = $slider->getClientOriginalName();

Laravel Image Upload not saving to public folder

I am struggling with this image upload system.
It is supposed to upload an image that will be attached to a post (each post has 1 image).
Everything seems to be working fine, the problem is that when I check the database for the image path, I see a path to a random temporary file and the image doesn't even get uploaded to the right folder inside the app public folder.
Check the logic below:
PostController.php
public function store(Request $request)
{
$post = new Post;
$request->validate([
'title' => 'required',
'description' => 'required',
'slug' => 'required',
'message' => 'required',
'user' => 'required',
'post_image' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
]);
if ($request->has('post_image')) {
$image = $request->file('post_image');
$name = Str::slug($request->input('title')).'_'.time();
$folder = '/uploads/images/';
$filePath = $folder . $name. '.' . $image->getClientOriginalExtension();
$this->uploadOne($image, $folder, 'public', $name);
$post->post_image = Storage::url($filePath);;
}
Post::create($request->all());
return \Redirect::to('admin')->with('success','Great! Post created successfully.');
}
UploadTrait.php
trait UploadTrait
{
public function uploadOne(UploadedFile $uploadedFile, $folder = null, $disk = 'public', $filename = null)
{
$name = !is_null($filename) ? $filename : Str::random(25);
$file = $uploadedFile->storeAs($folder, $name.'.'.$uploadedFile->getClientOriginalExtension(), $disk);
return $file;
}
}
Post.php (model)
class Post extends Model
{
protected $fillable = [
'title',
'description',
'slug',
'message',
'user',
'post_image'
];
public function getImageAttribute(){
return $this->post_image;
}
}
Create.blade.php
<form action="{{ route('blog.store') }}" method="POST" name="add_post" role="form" enctype="multipart/form-data">
{{ csrf_field() }}
<h1>New Post</h1>
<div role="separator" class="dropdown-divider"></div>
<div class="form-row">
<div class="form-group col-12 col-md-6">
<label for="title">Post Title</label>
<input type="text" autocomplete="off" class="form-control" id="title" name="title" placeholder="Your post title" required>
<span class="text-danger">{{ $errors->first('title') }}</span>
</div>
<div class="form-group col-12 col-md-6">
<label for="slug">Slug</label>
<input type="text" autocomplete="off" class="form-control" id="slug" name="slug" placeholder="Write post slug" required>
<span class="text-danger">{{ $errors->first('slug') }}</span>
</div>
</div>
<div class="form-row">
<div class="form-group col-12 col-md-12">
<label for="description">Post Description</label>
<textarea class="form-control" id="description" name="description" placeholder="Enter a small description for your post" required></textarea>
<span class="text-danger">{{ $errors->first('description') }}</span>
</div>
</div>
<div class="badge badge-warning badge-pill">Message</div>
<div role="separator" class="dropdown-divider"></div>
<div class="form-row">
<div class="form-group col-md-12">
<textarea class="form-control" col="4" id="message" name="message"></textarea>
<span class="text-danger">{{ $errors->first('message') }}</span>
</div>
</div>
<input type="hidden" value="{{ Auth::user()->name }}" name="user">
<input id="post_image" type="file" class="form-control" name="post_image">
<button type="submit" class="btn btn-warning btn-block">Create Post</button>
</form>
Thank you for your help!
Regards,
Tiago
You can use directly the functions provided by Laravel itself
$image_path = Storage::disk('public')->putFile('folders/inside/public', $request->file('post_image'));
Notice Storage::disk('public') that specifies the public folder.
Then you can update your request array with $request['image_path'] = $image_path and save it like you're currently doing or you cant still use your $post = new Post; and set every input data like $post->title = $request->title; then save like $post->save();
You did not save the image path in the database on the created post
$post = new Post; //here you have created an empty Post object
...
$post->post_image = Storage::url($filePath); //here you assigned the post_image to the empty object.
Post::create($request->all());// here you create a new POST object with the request data, which does not contain the post_image
Thank you David! I managed to correct the path that gets saved to the database, but the files are not getting uploaded (even though the path in database says /uploads/images/something.png, when i check the folder, the image is not there.. there is not even an uploads folder. This is the method I have now with your suggestions:
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'description' => 'required',
'slug' => 'required',
'message' => 'required',
'user' => 'required',
'post_image' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
]);
if ($request->has('post_image')) {
$image = $request->file('post_image');
$name = Str::slug($request->input('title')).'_'.time();
$folder = '/uploads/images';
$filePath = $folder . $name. '.' . $image->getClientOriginalExtension();
$this->uploadOne($image, $folder, 'public', $name);
$image_path = Storage::disk('public')->putFile('uploads/images', $request->file('post_image'));
$request['image_path'] = $image_path;
}
$post = new Post;
$post->title = $request->title;
$post->description = $request->description;
$post->slug = $request->slug;
$post->message = $request->message;
$post->user = $request->user;
$post->post_image = $request->image_path;
$post->save();
return \Redirect::to('admin')->with('success','Great! Post created successfully.');
}
Input in form
<form method="POST" enctype="multipart/form-data" action="/url">
<input id="category_logo" type="file" class="form-control" name="category_logo">...
Code in controller
$category = Category::find($id);
if($request->has('category_logo')) {
$image = $request->file('category_logo');
$category->category_logo = $image->getClientOriginalName();
$image->move(public_path('img/logo'), $image->getClientOriginalName());
}
$category->save();
Works for me!

Summernote WYSIWYG editor not rendering data correctly with Laravel 5.8

I have a problem when I want to rendering data and Images from database, I'm using Summernote and Laravel, I will paste my Code of the controller and views, thanks in advance.
I get summer note show correctly with all his options, but when I try to add some things in my text like make it bold or something like that he did not work.
Controller:
public function createPost(Request $request){
$this->validate($request, [
'title' => 'required',
'description' => 'required',
]);
$title = $request->input('title');
$description = $request->input('description');
$writer = Auth::user()->id;
$dom = new \DomDocument();
$dom->loadHtml($description, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$images = $dom->getElementsByTagName('img');
foreach($images as $k => $img){
$data = $img->getAttribute('src');
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
$image_name= "/upload/" . time().$k.'.png';
$path = public_path() . $image_name;
file_put_contents($path, $data);
$img->removeAttribute('src');
$img->setAttribute('src', $image_name);
}
$description = $dom->saveHTML();
$post = new Post;
$post->title= $title;
$post->description = $description;
$post->writer = $writer;
$post->save();
return redirect()->route('home')->with('success', 'Post has been successfully added!');
}
Add view:
#if(Auth::check())
<div class="col-md-12">
<form method="post" action="{{ route('post.form') }}">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Title</label>
<input type="text" class="form-control" id="id_title" name="title"
aria-describedby="title" placeholder="Enter title">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" id="content" rows="3" name="description" placeholder="Description"></textarea>
</div>
<button type="submit" class="btn btn-primary">Publish <i class="fas fa-paper-plane"></i></button>
</form>
</div>
#endif
Call of the summernote:
<script>
$(document).ready(function() {
$('#content').summernote({
height:300,
});
});
</script>
Example of the result, title plus content :
You should use {!! $description !!} to print as html.
Inspect the output in the browser, maybe the summernote plugin is not called properly,
In head tag, check the javascript plugin, and the css as well. Put them is proper order.

Laravel 5.4 Multiple upload and Inserting data

Hello everyone and thank you in advance, first of all sorry if my code is so confused I am still learning ^^.
I am trying to make a product with different attribute plus 3 different images(making the product gallery) and a feature image,
I have succeed to create the attributes and feature image.
The problem is with the 3 image for the gallery I cant store (neither in DB or image folder)
I have Two tables (product and productgallery) the relation between them is hasMany (I am using Laravel 5.4)
This the error I got after run the code
SQLSTATE[HY000]: General error: 1364 Field 'product_id' doesn't have a default value (SQL: insert into `product_galleries` (`updated_at`, `created_at`) values (2017-05-13 20:58:20, 2017-05-13 20:58:20))
(sorry for my English which for sure will make it harder to understand my question)
ProductController
public function store(UploadRequest $request)
{
$product = new Product();
$product->product_name = $request->product_name;
$product->product_description = $request->product_description;
if($request->hasFile('product_preview')) {
$file = Input::file('product_preview');
$filename = time(). '-' .$file->getClientOriginalName();
$product->product_preview = $filename;
$file->move(public_path().'/images/product-feature', $filename);
}
$product->category_id = $request->category_id;
$product->color_id = $request->color_id;
$product->size_id = $request->size_id;
$product->material_id = $request->material_id;
// $product->fantasia_id = $request->fantasia_id;
$productgallery = new ProductGallery();
if($request->hasFile('fileToUpload[]')) {
$files = Input::file('fileToUpload[]');
foreach ($request->$files as $photo) {
$filename = time(). '-' .$photo->getClientOriginalName();
$productgallery->product_images = $filename;
$photo->move(public_path().'/images/product-gallery', $filename);
$productgallery->product_id = 1;
}
}
$product->save();
$productgallery->save();
return $this->create()->with('success', 'Uploaded Successfully');
}
Upload request (FormRequest)
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UploadRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
$rules = [
'product_name' => 'required|max:120',
'category_id' => 'required|integer',
'product_preview' => 'required|image|mimes:jpeg,png,jpg,gif,svg',
];
$fileToUpload = count($this->input('fileToUpload'));
foreach(range(0, $fileToUpload) as $index) {
$rules['fileToUpload.' . $index] = 'image|mimes:jpeg,bmp,png|max:2000';
}
return $rules;
}
}
the view for the form
#extends('layouts.backend-master')
#section('styles')
<link rel="stylesheet" href="">
#endsection
#section('content')
#if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong> There were some problems with your input.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<h1>Add a new product</h1>
<form action="{{route('products.store')}}" method="post" enctype="multipart/form-data">
<div class="input-group">
<label for="product_name">Name of the product</label>
<input type="text" name="product_name" id="product_name"/>
</div>
<div class="input-group">
<label for="product_description">Product Description</label>
<textarea type="text" name="product_description" id="product_description" rows="8"></textarea>
</div>
<div class="input-group">
<label for="product_preview">Feature Image:</label>
<input type="file" name="product_preview" id="file">
</div>
<div class="input-group">
<label for="category_id">Category</label>
<select name="category_id" id="category_id">
#foreach($categories as $category)
<option value="{{ $category->id }}">{{ $category->category_name }}</option>
#endforeach
</select>
</div>
<div class="input-group">
<label for="color_id">Color</label>
<select name="color_id" id="color_id">
#foreach($colors as $color)
<option value="{{ $color->id }}">{{ $color->color_name }}</option>
#endforeach
</select>
</div>
<div class="input-group">
<label for="size_id">Size</label>
<select name="size_id" id="size_id">
#foreach($sizes as $size)
<option value="{{ $size->id }}">{{ $size->size_name }}</option>
#endforeach
</select>
</div>
<div class="input-group">
<label for="material_id">Material</label>
<select name="material_id" id="material_id">
#foreach($materials as $material)
<option value="{{ $material->id }}">{{ $material->material_type }}</option>
#endforeach
</select>
</div>
<div class="input-group">
<label for="fileToUpload">Product Gallery:</label>
<input type="file" name="fileToUpload[]" id="fileToUpload" multiple >
</div>
<button type="submit" class="btn">Add</button>
<input type="hidden" name="_token" value="{{Session::token()}}">
</form>
#endsection
#section('scripts')
#endsection
thank you
You'll need to look at Laravel relationships API documentation. Here's a link to read more about it Laravel 5.4 Eloquent Relationships
Quick tip to fix that
You should add a foreign key in your database/migration file
For a migration you can simply add
$table->foreign('product_id')->references('id')->on('products');
And add this method to your Product model
public function productgallery(){
return $this->hasMany(Productgallery::class);
}
and this to your Productgallery model
public function product(){
return $this->belongsTo(Product::class);
}
Note: You'll still need to populate the product_id field within your request
Package solution
I'd recommend you use a 3rd party package for that matter, as it will be less work, cleaner and more solid to use.
You can look more into spatie's medialibrary for Laravel
I think this is what you want.
This will create a new Product and create a new ProductGallery for each image passed in $request->file('fileToUpload[]'):
$product = new Product();
$product->product_name = $request->product_name;
$product->product_description = $request->product_description;
if($request->hasFile('product_preview')) {
$file = Input::file('product_preview');
$filename = time(). '-' .$file->getClientOriginalName();
$product->product_preview = $filename;
$file->move(public_path().'/images/product-feature', $filename);
}
$product->category_id = $request->category_id;
$product->color_id = $request->color_id;
$product->size_id = $request->size_id;
$product->material_id = $request->material_id;
// $product->fantasia_id = $request->fantasia_id;
// First save the product (so that you have it's ID)
$product->save();
// Then create galleries
if($request->hasFile('fileToUpload[]')) {
$files = Input::file('fileToUpload[]');
foreach ($files as $photo) {
$productgallery = new ProductGallery();
$filename = time(). '-' .$photo->getClientOriginalName();
$productgallery->product_images = $filename;
$photo->move(public_path().'/images/product-gallery', $filename);
$productgallery->product_id = $product->id; // Save it to the newly created product
$productgallery->save();
}
}
return $this->create()->with('success', 'Uploaded Successfully');

Resources