I'm trying to save image using Laravel
Image is saved as tmp file in database, why so?
the image saved as C:\xampp\tmp\phpA3EB.tmp in the database
how can I fix this?
in the controller:
public function update(Request $request, Bank $bank)
{
if ( isset($request->photo) && $request->photo ) {
$request['image'] = UploadImage($request->file('photo'), 'bank', '/banks');
#unlink(public_path('/uploads/banks/') . $bank->image);
}
$updated = $bank->update($request->all());
$bank->updateTranslations([
'name' => $request->get('name_en'),
]);
return $updated ?
redirect()->route('banks.index')->with('success', trans('messages.updateTrue')) :
redirect()->back()->with('warning', trans('messages.updateFalse'));
}
function UploadImage($inputRequest, $prefix, $folderNam)
{
$imageName = $prefix.'_'.time().'.'.$inputRequest->getClientOriginalExtension();
$destinationPath = public_path('/uploads/'.$folderNam);
$inputRequest->move($destinationPath, $imageName);
return $imageName ? $imageName : false;
}
please try this :
public function UploadImage($image, $path)
{
$type = $image->getMimeType();
$ext = substr($type, 6, strlen($type) -1 );
$picName = uniqid() . '.' .$ext;
$image->move(public_path($path), $picName);
return $path . '/' . $picName;
}
}
Please try this :
public function UploadImage($image, $prefix, $path)
{
$ext = $image->extension();
$filename = $prefix.'_'.uniqid() . '.' .$ext;
$image->move(public_path('/uploads/'.$path), $filename);
return $filename;
}
I too struggled with mine for quite a while. However, I realized that I was doing everything okay but how I saved/created it on my database was the problem.
Here is what worked.
public function store(Request $request)
{
$request->validate([
'title'=>'required',
'features'=>'required',
'website'=>'required',
'img'=>'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$input=$request->all();
$imagePath=$request->file('img');
$imageName=time().'.'.$imagePath->getClientOriginalExtension();
$imagePath->move('uploads',$imageName);
$input['img']=$imageName;
Portfolio::create($input);
return Redirect::to('portfolio')->with('success','Great! Portfolio item created successfully.');
}
Related
I tried to update a form including a file(image) and to have the old image deleted. The update works fine but the old image is unable to delete. I tried this code but the image is not deleted. Please, help me. Thanks in advance.
public function update(Request $request, $id)
{
$slug = SlugService::createSlug(Category::class, 'slug', $request->title);
$request->validate([
'title'=>'required',
'category_image'=>'image'
]);
if ($request->hasFile('category_image')) {
$image = $request->file('category_image');
$newImageName = uniqid().'-'.$request->title.'.'.$image->getClientOriginalExtension();
$location = public_path('/categoryImage');
$OldImage = public_path('categoryImage/'.$request->category_image);
$image->move($location, $newImageName);
Storage::delete($OldImage);
}else {
$newImageName = $request->category_image;
}
Category::where('id', $id)->update([
'slug'=>$slug,
'title'=>$request->input('title'),
'details'=>$request->input('details'),
'category_image'=>$newImageName
]);
return redirect('category')->with('success', 'Category Successfully Updated');
}
public function update(Request $request, $id)
{
...
$category = Category::find($id); #new
if ($request->hasFile('category_image')) {
$image = $request->file('category_image');
$newImageName = uniqid().'-'.$request->title.'.'.$image->getClientOriginalExtension();
$location = public_path('/categoryImage');
$OldImage = public_path('categoryImage/'.$category->category_image); #new
$image->move($location, $newImageName);
unlink($OldImage); #new
}else {
$newImageName = $request->category_image;
}
#you can simplify this as
$category->slug = $slug;
$category->title = $request->title;
$category->details = $request->details;
$category->category_image = $newImageName;
$category->save()
return redirect('category')->with('success', 'Category Successfully Updated');
}
You can delete old image like this , if image is not in root of your storage insert your file location inside storage before image name.
unlink(storage_path('/location_inside_storage/'.$OldImage));
I am working with Laravel 7 trying to delete multiple images from my app. When I hit the delete button, the images are removed successfully from the show.blade.php as well as from the database. However, they are still in my storage on my local disk. I am storing my images in storage/app/public/upload as well as the symlink pointing to storage/upload in the public directory under app. I have tried a variety of ways to get it to delete but nothing has been fruitful. I have my one to many relationships set up in my models which I will show below. I need this to work under three circumstances such as if there is no image, one image or many images. I am using Laravel Resources for my routing and so my TaskController.php only has one destroy method.
Here is the code I have so far:
Models -
Image.php (relevant functions only - Storage and Task classes imported at top)
public function task()
{
return $this->belongsTo('App\Task', 'task_id');
// return $this->belongsTo(Task::class);
}
public static function boot()
{
parent::boot();
self::deleting(function ($images) {
Storage::delete(Storage::path($images['name']));
});
}
Task.php (relevant code only - Storage, File and Image classes imported at top)
public function images()
{
// return $this->hasMany('App\Image');
return $this->hasMany(Image::class);
}
public static function boot()
{
parent::boot();
self::deleting(function ($task) {
foreach ($task->images ?: [] as $image) {
$image->delete();
}
});
}
Controller
TasksController.php (store, show, update and destroy)
public function store(Request $request)
{
$this->validate($request, [
'task_name' => 'required',
'task_description' => 'required',
]);
// Create Task
$user = Auth::user();
$task = new Task();
$data = $request->all();
$task->user_id = $user->id;
$task = $user->task()->create($data);
if ($request->hasFile('images')) {
$files = $request->file('images');
foreach ($files ?: [] as $file) {
$name = time() . '-' . $file->getClientOriginalName();
$name = str_replace(' ', '-', $name);
$file->storeAs('public/upload', $name);
$task->images()->create(['name' => $name]);
$images = new Image;
$images->name = $name;
}
}
$task->task_name = $request->input('task_name');
$task->task_description = $request->input('task_description');
$task->task_priority = $request->input('task_priority');
$task->task_assigned_by = $request->input('task_assigned_by');
$task->task_assigned_to = $request->input('task_assigned_to');
$task->task_to_be_completed_date = $request->input('task_to_be_completed_date');
$task->task_notes = $request->input('task_notes');
$task->task_status = $request->task_status;
$task->save();
return redirect('/home')->with('success', 'Task Created');
}
public function update(Request $request, $id)
{
$this->validate($request, [
'task_name' => 'required',
'task_description' => 'required',
]);
$task = Task::find($id);
$task->task_name = $request->input('task_name');
$task->task_description = $request->input('task_description');
$task->task_priority = $request->input('task_priority');
$task->task_assigned_by = $request->input('task_assigned_by');
$task->task_assigned_to = $request->input('task_assigned_to');
$task->task_to_be_completed_date = $request->input('task_to_be_completed_date');
$task->task_notes = $request->input('task_notes');
$task->task_status = $request->input('task_status');
if ($request->hasFile('images')) {
$files = $request->file('images');
foreach ($files ?: [] as $file) {
$name = time() . '-' . $file->getClientOriginalName();
$name = str_replace(' ', '-', $name);
$file->storeAs('public/upload', $name);
$task->images()->create(['name' => $name]);
$images = new Image;
$images->name = $name;
}
}
$task->save();
return redirect('/home')->with('success', 'Task Updated');
}
public function show($id)
{
$task = Task::find($id);
return view('tasks.show')->with('task', $task);
}
public function destroy($id)
{
$task = Task::findOrFail($id);
$images = Image::find($id);
$images = explode(',', $images['name']);
foreach ($images as $image) {
// $path = 'storage/app/public/upload/' . $image;
if (file_exists('../storage/app/public/upload/' . json_decode($image, true)['name'])) {
// print_r('file found');
// unlink('../storage/app/public/upload/' . base64_decode($image, true)['name']);
// dd('../storage/app/public/upload/' . json_decode($image, true)['name']);
// File::delete('../storage/app/public/upload/' . json_decode($image, true)['name']);
dd('../storage/app/public/upload/' . $task['image']);
File::delete('../storage/app/public/upload/' . json_decode($image, true)['name'] . $task['images']);
} else {
print_r('no sirve ' . __DIR__ . ' ' . $image . var_dump($image));
}
// dd($path);
// if (File::exists($path)) {
// File::delete($path);
// }
}
// $task->delete();
return redirect('home')->with('success', 'Task Deleted');
}
I have left some commented code included so you can see what I have tried. If I am missing anything, please let me know and I will edit my question.
Thank you in advance for your help. I have been stuck on this for a week.
EDIT
I have changed my destroy function. It still does not delete the files from the disk. Here is the function:
public function destroy($id)
{
// $task = Task::findOrFail($id);
$task = Task::with('images')->findOrFail($id);
// $images = Image::find($id);
// $images = $task->images($id)->get();
foreach ($task->images as $image) {
// dd(storage_path('app/public/upload/' . $image['name']));
Storage::delete(storage_path('app/public/upload/' . $image->name));
}
$task->images()->delete();
$task->delete();
return redirect('home')->with('success', 'Task Deleted');
}
I ended up calling the public folder for the delete function using Storage::disk('public')->delete('upload/' . $image->name);
That in the end helped me to delete the files from my disk. I hope this helps anyone who faces the same issue. Thank you Alzafan Christian for your help in this. You led me in the right direction.
I want to Update an image using Laravel storage file system in my admin data. However, there's an error when I attempt to upload an image
Iam using Laravel 5.7
Here is my create, the create is success
public function store(Request $request)
{
//
$product = new \App\Product;
$product->product_name = $request->get('product_name');
$product->desc = $request->get('desc');
$product->stock = $request->get('stock');
$product->price = $request->get('price');
$product->category = $request->get('category');
$img = $request->file('img');
$new_name = rand() . '.' . $img->getClientOriginalExtension();
$img->move(public_path('img'), $new_name);
$product->img = $new_name;
$product->save();
return redirect('admin')->with('success', 'Data Produk telah ditambahkan');
}
Here is my update
public function update(Request $request, $id)
{
//
$product = $request->all();
$product= \App\Product::find($id);
$new_name = $request->file('img')->getClientOriginalName();
$destinationPath = 'img/';
$proses = $request->file('img')->move($destinationPath, $new_name);
if($request->hasFile('img'))
{
$product = array(
'product_name' => $product['product_name'],
'desc'=> $product['desc'],
'stock'=> $product['stock'],
'price'=> $product['price'],
'category'=> $product['category'],
'img' => $new_name,
);
$product->save() ;
return redirect('admin')->with('success', 'Data Produk telah ditambahkan');
}
}
Call to a member function getClientOriginalName() on null
I think there is no image file attach while updating. You can use my code as reference.
Don't forget to check for the input field in your update field.
First check if there is image file or not. Then, go for getting name, extension and other staff.
public function update($id, Request $request)
{
$input = $request->all();
$product= \App\Product::find($id);
if (empty($product)) {
Flash::error('product not found');
return redirect(route('products.index'));
}
if ($request->hasFile('product_img')) {
$fileNameWithExt = $request->file('product_img')->getClientOriginalName();
$filename = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
$extension = $request->file('product_img')->getClientOriginalExtension();
$new_product_img = $filename . '_' . time() . '.' . $extension;
$path = $request->file('product_img')->move('images/products', $new_product_img);
Storage::delete('products/'.$product->product_img);
$input['product_img']= $new_product_img;
}
$product= $this->productRepository->update($input, $id);
Flash::success('product updated successfully.');
return redirect(route('products.index'));
}
I have been having issues with my image upload input. I am attempting to create a file upload input into my Laravel 5 project but I am running into problems with the path that is saved into the database image table.
The form is working and is posting, however, when the database saves the path to the image it is inputting: /Applications/MAMP/tmp/php/phptvwTYW instead of taking just the file name.
Additionally, the file is being moved to the correct public/img folder.
Code
public function store(PostRequest $request)
{
$this->createPost($request);
$destinationpath = public_path() . '/img/';
$filename = $request->file('image_url')->getClientOriginalName();
$request->file('image_url')->move( $destinationpath,$filename );
flash()->success('Your Post Has Been Created!');
return redirect('posts');
}
Here is the sample Controller Function currently using in my project
public function postCreateInternal(CreateDocumentInternalRequest $request) {
$data_information = $request->only(['title', 'assigned_to', 'folder_id', 'document_source']);
if ($request->hasFile('file_name') && $request->file('file_name')->isValid()) {
$document = $request->file('file_name');
#creating file Name
$mytime = Carbon::now();
$date_now = $mytime->toDateTimeString();
$date_now = $this->prepareFileNameString($date_now);
$document_extension = $document->getClientOriginalExtension();
$document_name = $this->prepareFileNameString(basename($document->getClientOriginalName(), '.' . $document_extension));
$document_fullName = $document_name . "_" . ($date_now) . "." . $document_extension;
$data_information['file_type'] = $document->getMimeType();
$data_information['file_size'] = $document->getSize();
$data_information['file_name'] = $document_fullName;
$data_information['file_download_type'] = "Internal";
$document->move(public_path() . '/uploads/documents/', $document_fullName);
}
if ($pot = $this->document->create($data_information)) {
$this->notification_admin->sendCreateDocument($data_information);
return redirect()->route('documents')->with('success', trans('document.create.msg_success'));
// return redirect()->route('update/document', $pot->id)->with('success', trans('document.create.msg_success'));
}
return redirect()->route('create/document')->with('error', trans('document.msg_error'));
}
CreateDocumentInternalRequest basically using for File and other data validation as per Laravel 5
And View File seems to like:
{!! Form::open(["class"=>"form-horizontal","data-parsley-validate"=>"data-parsley-validate",'role'=>'form','files'=>true]) !!}
<div class="form-group required {{ $errors->first('file_name', ' has-error') }}">
{!!Form::label('file_name', trans('document.label.file_name'), array('class' => 'col-md-4 control-label left-label'))!!}
<div class="col-sm-6">
{!! Form::file('file_name') !!}
{!! $errors->first('file_name', '<span class="help-block">:message</span>') !!}
</div>
</div>
{!! Form::close() !!}
In my current implementation, first i'm checking file uploaded, rename filename with current timestamp and re upload my desire location.
If you need any help my provided method let me know to improve in better way.
this is very simple way:
public function store(PostRequest $request)
{
$image_name = $request->file('image')->getClientOriginalName();
$request->file('image')->move(base_path().'/public/images', $image_name);
$post = ($request->except(['image']));
$post['image'] = $image_name;
Post::create($post);
Session::flash('success_message', 'Post has been added successfully!');
return redirect('teacher');
}
public function profileUpdate($id)
{
if(!Entrust::can('profile_update_employee'))
return Redirect::to('/dashboard')->withErrors(Config::get('constants.NA'));
if(!Helper::getMode())
return Redirect::back()->withErrors(Config::get('constants.DISABLE_MESSAGE'));
$employee = User::find($id);
if(!$employee)
return Redirect::to('employee')->withErrors(Config::get('constants.INVALID_LINK'));
$rules = array(
'photo' => 'image|image_size:<=2000|max:100000',
'date_of_birth' => 'date',
'date_of_joining' => 'date',
'date_of_leaving' => 'date',
'employee_code' => 'required|unique:profile,employee_code,'.$employee->Profile->id.',id'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
return Redirect::to('/employee/'.$id."#basic")->withErrors($validator);
Activity::log('Profile updated');
$profile = $employee->Profile ?: new Profile;
$photo = $profile->photo;
$data = Input::all();
$profile->fill($data);
if(Input::get('date_of_birth') == '')
$profile->date_of_birth = null;
if(Input::get('date_of_joining') == '')
$profile->date_of_joining = null;
if(Input::get('date_of_leaving') == '')
$profile->date_of_leaving = null;
if (Input::hasFile('photo') && Input::get('remove_photo') != 1) {
$filename = Input::file('photo')->getClientOriginalName();
$extension = Input::file('photo')->getClientOriginalExtension();
$file = Input::file('photo')->move('assets/user/', $employee->username.".".$extension);
DB::insert('insert into ez_profile (id, photo) values ($id, $photo)');
$img = Image::make('assets/user/'.$user->username.".".$extension);
$img->resize(200, null, function ($constraint) {
$constraint->aspectRatio();
});
$img->save('assets/user/'.$user->username.".".$extension);
$profile->photo = $employee->username.".".$extension;
} elseif(Input::get('remove_photo') == 1){
File::delete('assets/user/'.$profile->photo);
$profile->photo = null;
}
else
$profile->photo = $photo;
$employee->profile()->save($profile);
return Redirect::to('/employee/'.$id.'/#basic')->withSuccess(Config::get('constants.SAVED'));
}
Try this:
public function store(PostRequest $request, Post $post) {
$destinationpath = public_path() . '/img/';
$filename = $request->file('image_url')->getClientOriginalName();
$request->file('image_url')->move( $destinationpath,$filename );
$post->create([
'field1' => $val1,
'imageField' => $filename,
'field2' => $val2
]);
flash()->success('Your Post Has Been Created!');
return redirect('posts');
}
I found the solution to my question.
I had to make some changes to the store and createPost functions within my controller to make this work.
For the controller I have:
public function store(PostRequest $request)
{
$destinationpath = public_path() . '/img/';
$filename = $request->file('image_url')->getClientOriginalName();
$request->file('image_url')->move( $destinationpath,$filename );
$this->createPost($request, $filename);
flash()->success('Your Post Has Been Created!');
return redirect('posts');
}
private function createPost(PostRequest $request, $new_url)
{
$post = Auth::user()->posts()->create($request->all());
$post->image_url = $new_url;
$post->save();
$this->syncTags($post, $request->input('tag_list'));
return $post;
}
I hope this helps anyone else that may be running into this same problem.
Thank you everyone for the help!
its because you save before moving,
//before moving
$request->file('image_url')->getPath(); // returns Applications/MAMP/tmp/php/php...
to have the full path of your new moved file you can do this
//After moving
$res = $request->file('image_url')->move( $destinationpath,$filename );
$my_new_path = $res->getPath(); // returns [public_path]/img/filename.jpg
you can save it by update your post after moving the file, or use event to move it when saving
look here http://laravel.com/docs/master/eloquent#events
I have an edit form which has an image field where a user can upload a new image if he wants to.
But if the user does not upload a new photo I don't want to validate the image field and just use the photo that's already in the database. And not update the image field at all.
Here is my edit function:
public function postEdit($id) {
$product = Product::find($id);
// This should be in product model, just testing here
$edit_rules = array(
'category_id' => 'required|integer',
'title' => 'required|min:2',
'description' => 'required|min:10',
'price' => 'required|numeric',
'stock' => 'integer'
);
// Add image rule only if user uploaded new image
if (Input::has('image')) {
$edit_rules['image'] = 'required|image|mimes:jpeg,jpg,bmp,png,gif';
}
$v = Validator::make(Input::all(), $edit_rules);
if ($product) {
if ($v->fails()) {
return Redirect::back()->withErrors($v);
}
// Upload the new image
if (Input::has('image')) {
// Delete old image
File::delete('public/'.$product->image);
// Image edit
$image = Input::file('image');
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
Image::make($image->getRealPath())->resize(600, 600)->save('public/img/products/'.$filename);
$product->image = 'img/products/'.$filename;
$product->save();
}
// Except image because already called save if image was present, above
$product->update(Input::except('image'));
return Redirect::to('admin/products')->with('message', 'Product updated.');
}
return Redirect::to('admin/products');
}
Using this I can update all the values except the image.
If I don't upload a new photo it saves all other updated values.
If I do upload a new photo it just ignores it and saves all other updated values, doesn't upload the new photo.
Check if the request has the file:
public function update(Request $request)
{
// Update the model.
if($request->hasFile('photo')) {
// Process the new image.
}
// ...
}
public function update() {
$id=Input::get('id');
$rules= array('name'=>'required|regex:/(^[A-Za-z]+$)+/',
'detail'=>'required|regex:/(^[A-Za-z]+$)+/',
'images' => 'required|image');
$dat = Input::all();
$validation = Validator::make($dat,$rules);
if ($validation->passes()){
$file =Input::file('images');
$destinationPath = 'image/pack';
$image = value(function() use ($file){
$filename = date('Y-m-d-H:i:s') . '.' . $file->getClientOriginalExtension();
return strtolower($filename);
});
$newupload =Input::file('images')->move($destinationPath, $image);
DB::table('pkgdetail')
->where('id', $id)
->limit(1)
->update(array('name' => Input::get('name'), 'detail' => Input::get('detail'), 'image' => $newupload));
$data=PackModel::get_all();
return View::make('pkg_dis')->with('data',$data)
->withErrors($validation)
->with('message', 'Successfully updated.');
}
}
use Illuminate\Support\Facades\Input;
public function update(Request $request, $id)
{
if ($tag = Tag::find($id))
{
$this->validate($request, [
'tag_name' => 'required|min:3|max:100|regex: /^[a-zA-Z0-9\s][a-zA-Z0-9\s?]+$/u|unique:tags,tag_name,'.$id.',id',
]);
$tag->tag_name=$request->input('tag_name');
// get the image tag_img_Val
if($request->hasFile('tag_image'))
{
$this->validate($request, [
'tag_image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:1000',
]);
$img = $request->file('tag_image');
$old_image = 'uploads/' . $tag->tag_image;//get old image from storage
if ($img != '')
{
$image = rand() . '_' . ($img->getClientOriginalName());
$path = 'uploads/';
//Storing image
if ($img->move(public_path($path), $image))
{
$tag->tag_image = $image;
if ($tag->update())
{
if (is_file($old_image)) {
unlink($old_image); // delete the old image
}
return response()->json(['message' => 'Tag has been updated successfully.'],200);
}
else
{
unlink($image); // delete the uploaded image if not updated in database
return response()->json(['message' => "Sorry, Tag not updated"],500);
}
}
else
{
return response()->json(['message' => "Sorry, Image not moved"],500);
}
}
else
{
return response()->json(['message' => "Sorry, Image not uploaded"],500);
}
}
else
{
if($tag->update(Input::except('tag_image')))
{
return response()->json(['message' => 'Tag has been updated successfully.'],200);
}
else
{
return response()->json(['message' => "Sorry, Tag not updated"],500);
}
}
}
else
{
return response()->json(['message' => 'Tag not found'], 404);
}
}
You need to use multipart for form enctype
You can use another function to delete the images from the folder. like here
private function unlinkPostImages($images)
{
if(!empty($images)){
foreach ($images as $img){
$old_image = public_path('storage/' . $img->image);
if (file_exists($old_image)) {
#unlink($old_image);
}
}
}
}
Then call this function above image delete function. like this...
$this->unlinkPostImages($getId->images); // this will delete image from folder
$getId->images()->delete(); // --> this delete from database table $post->id
same this Click here..
my update function
public function update(UpdatePostRequest $request, Post $post)
{
//
$data = $request->only(['title', 'description', 'contents', 'price']);
// صورة الإعلان //
if ($request->hasFile('image')) {
Storage::disk('public')->delete($post->image);
$imagePath = $request->image;
$filename = Str::random(10).'-'.time().'-'.$imagePath->getClientOriginalName();
$image_resize = Image::make($imagePath->getRealPath());
$image_resize->fit(120);
$image_resize->orientate();
$image_resize->save(public_path('storage/images/' .$filename), 100);
$sImg = 'images/'. $filename;
$data['image'] = $sImg;
}
// -------- //
if ($request->hasFile('images'))
{
$getId = Post::find($post->id);
$this->unlinkPostImages($getId->images);
$getId->images()->delete();
$uploadPicture = array();
foreach ($request->file('images') as $photo) {
$file = $photo;
$filename = $file->getClientOriginalName();
$picture = date('His').'-'.$filename;
$file->move(public_path('storage/images/'), $picture);
array_push($uploadPicture, new PostImages(array('image' => 'images/'. $picture)));
}
$post->images()->saveMany($uploadPicture);
}
if ($request->input('contents')) {
$data['content'] = $request->contents;
}
//dd($data);
$post->update($data);
session()->flash('SUCCESS', 'تم تحديث الإعلان بنجاح.');
return redirect()->route('post.show', [$post->id, Post::slug($post->title)]);
}
In controller part:
$destinationPath = 'uploads';
$extension = Input::file('image')->getClientOriginalExtension();
var_dump($extension);
$fileName = rand(11111,99999).'.'.$extension;
Input::file('image')->move($destinationPath, $fileName);