I am a Laravel beginner and I want to build an API with Laravel 8.
I have posts and images and I want to store and update them.
My store method works and the images are saved in the database and public path in images folders, but in update method I can't save it in folder.
These are my codes:
PostController
public function store(Request $request )
{
$data = $request->all();
//validationg posts and images fields
$validator = Validator::make($data, [
'user_id' => 'required',
'category_id' => 'required',
'title' => 'required|max:150|unique:posts',
'body' => 'required',
'study_time' => 'required',
'tags' => 'nullable|string',
'image' => 'required',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors(), 'خطا در اعتبار سنجی']);
}
//separate tags
$tags = explode(",", $request->tags);
if ($request->hasfile('image')) {
//getting post images from request
$files = $request->file('image');
//saving name and path of images
foreach ($files as $file) {
$imageName = time().rand(1,10000).'.'.$file->extension();
$postTitle = $request->title; //post title for folder name and the images inside it
$imagePath = public_path(). '/images/posts/'.$postTitle;
$file->move($imagePath, $imageName);
$image = new Image;
$image->image = $imageName;
$image->path = $imagePath;
$images[] = $image; // make an array of uploaded images
}
}
$post = Post::create($data);
$post->images()->saveMany($images);//save imageas in image table
$post->tag($tags);//save tags in tags table
return response()->json([
'success' => true,
'message' => 'با موفقیت ثبت گردید ',
'data' => $post
]);
}
public function update(Request $request, $id)
{
$post_failed = Post::find($id);
if (is_null($post_failed)) {
return response()->json('پست مورد نظر یافت نشد ', 404);
}
$data = $request->all();
//validation posts and images fields
$validator = Validator::make($data, [
'user_id' => 'required',
'category_id' => 'required',
'title' => 'required|max:150|unique:posts',
'body' => 'required',
'study_time' => 'required',
'tags' => 'nullable|string',
'image' => 'required',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors(), 'خطا در اعتبار سنجی ']);
}
$tags = explode(",", $request->tags);
if ($request->hasfile('image')) {
$postTitle = $request->title; //post title for folder name and the images inside it
//delete last Images from database for updating images
Image::where('imageable_type', 'App\Models\Post')->where('imageable_id' , $id)->delete();
//delete last images images folder
File::delete(public_path('/images/posts/'.$postTitle));
$files = $request->file('image');
foreach ($files as $file) {
$imageName = time().rand(1,10000).'.'.$file->extension();
$imagePath = public_path(). '/images/posts/'.$postTitle;
$image = new Image();
$image->image = $imageName;
$image->path = $imagePath;
$images[] = $image;
}
}
$post = Post::find($id);
$post->user_id = $data['user_id'];
$post->category_id = $data['category_id'];
$post->title = $data['title'];
$post->body = $data['body'];
$post->study_time = $data['study_time'];
$post->tags = $data['tags'];
$post->save();
$post->images()->saveMany($images);
$post->tag($tags);
return response()->json([
'success' => true,
'message' => 'با موفقیت ویرایش گردید ',
'data' => $post
]);
}
The relation between posts and images is polymorphic one to many and I tested it with postman.
Postman
Database
And the path:
Please, help.
In store() method you saved images on disk by using
$imagePath = public_path(). '/images/posts/'.$postTitle;
$file->move($imagePath, $imageName);
In update() you deleted them
File::delete(public_path('/images/posts/'.$postTitle));
and determined path for new files
$imagePath = public_path(). '/images/posts/'.$postTitle;
but nothing happens after this. In whole update() method there is no code that could do something in storage, so of course nothing appears in folder ;)
So again use $file->move() or Storage facade to save files.
TIP
Also this is bad practice to repeat long code logic like that. It would be better to extract this and share between store/update.
Related
My All Data has been updated successfully but Image not update and old image not remove. I am using Query Builder.
Can anyone tell me what to do?
My Controller are given below
I want to know something new.
public function update(Request $request,$id)
{
$validatedData = $request->validate([
'name' => 'required|max:255',
'title' => 'required',
'details' => 'required',
]);
$data = array();
$data['name'] = $request->name;
$data['title'] = $request->title;
$data['details'] = $request->details;
$data['status'] = $request->status;
$image=$request->photo;
if ($image) {
$image_name = str_random(20);
$ext = strtolower($image->getClientOriginalExtension());
$image_full_name = $image_name.'.'.$ext;
$upload_path = 'public/upload/event';
$image_url = $upload_path.$image_full_name;
$success = $image->move($upload_path,$image_full_name);
if ($success) {
$data['photo'] = $image_url;
$img = DB::table('events')->where('id',$id)->first();
$image_path = $img->photo;
$done = unlink($image_path);
$user = DB::table('events')->where('id',$id)->update($data);
if ($user) {
$notification = array(
'messege' => 'Data Updated Successfully',
'alert-type' => 'success'
);
return redirect('admin/event')->with($notification);
}else{
return redirect()->back();
}
}
}else{
return redirect()->back();
}
//return redirect('admin/event')->with($notification);
}
I want to upload image for my posts and have polymorphism relation one to one (because I have other tables and they need image too ) between posts and images
And when I want to send request and store the image in database , I get this error:
BadMethodCallException: Call to undefined method App\Models\Image::move()
I'm creating an API so :
My postman :
My relations :
Image model :
class Image extends Model
{
use HasFactory;
protected $fillable = [
'image'
];
public function imageable(){
return $this->morphTo();
}
}
Post model :
class Post extends Model
{
use HasFactory;
use \Conner\Tagging\Taggable;
protected $fillable = [
'user_id' ,
'category_id' ,
'title' ,
'body' ,
'study_time',
'likes',
'status',
'tags',
];
public function image(){
return $this->morphOne(Image::class , 'imageable');
}
}
And the PostController , store() method :
public function store(Request $request )
{
$data = $request->all();
$validator = Validator::make($data, [
'user_id'=>'required',
'category_id'=>'required',
'title' => 'required|max:150|unique:posts',
'body' => 'required',
'study_time'=>'required',
'tags'=>'nullable|string',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors(), 'error']);
}
//separate tags
$tags = explode(",", $request->tags);
$image = new Image;
$getImage = $request->file('image');
$imageName = time().'.'.$getImage->extension();
$image->move(public_path('images'), $imageName);
$post = Post::create($data);
$post->image()->save($image);
//save tags
$post->tag($tags);
return response()->json([
"success" => true,
"message" => "successfull",
"data" => $post
]);
}
Where is my mistake?
After a month of this challenge, I was finally able to solve it :}
To make the code better and cleaner, I added another column to my image table : path
it's for saving path of image , and another column : image
and i added the path to my fillable in Image model and i edited the code to this :
public function store(Request $request )
{
$data = $request->all();
$validator = Validator::make($data, [
'user_id'=>'required',
'category_id'=>'required',
'title' => 'required|max:150|unique:posts',
'body' => 'required',
'study_time'=>'required',
'tags'=>'nullable|string',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors(), 'error']);
}
//separate tags
$tags = explode(",", $request->tags);
$image = new Image;
$getImage = $request->image
$imageName = time().'.'.$getImage->extension();
$imagePath = public_path(). '/images/posts';
$image->path = $imagePath;
$image->image = $imageName;
$getImage->move($imagePath, $imageName);
$post = Post::create($data);
$post->image()->save($getImage);
$post->tag($tags);
return response()->json([
"success" => true,
"message" => "successfully",
"data" => $post
]);
}
I am a beginner in laravel. I'm trying to submit a post with the option to upload multiple files if the user wants. I keep getting the error "Undefined variable: data." Where did I go wrong?
public function store(Request $request)
{
//validate
$this->validate($request, [
'title' => 'required|min:10',
'body' => 'required|min:20',
'filename' => 'nullable|max:2480',
'filename.*' => 'mimes:jpeg,jpg,png'
]);
//store Image
if($request->file('filename'))
{
foreach($request->file('filename') as $image)
{
$name=time().$image->getClientOriginalName();;
$image->move(public_path().'/images/', $name);
$data[] = $name;
}
}
$post= new Post();
$post->user_id = auth()->user()->id;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->filename=json_encode($data);
$post->save();
return back()->withMessage('Post created successfully.');
}
I think that it will be better to declare your array outside the foreach loop.
You can try something like this:
Outside your foreach loop.
$data = array();
Inside your foreach loop, try to populate the array like this:
array_push($data, $name);
public function store(Request $request)
{
//validate
$this->validate($request, [
'title' => 'required|min:10',
'body' => 'required|min:20',
'filename' => 'nullable|max:2480',
'filename.*' => 'mimes:jpeg,jpg,png'
]);
//Initialize an empty array
$data = array();
//store Image
if($request->file('filename'))
{
foreach($request->file('filename') as $image)
{
$name=time().$image->getClientOriginalName();;
$image->move(public_path().'/images/', $name);
//populate array here
array_push($data, $name);
}
}
$post= new Post();
$post->user_id = auth()->user()->id;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->filename=json_encode($data);
$post->save();
return back()->withMessage('Post created successfully.');
}
I am currently building a CRUD application using Laravel. It requires me to upload images and information but seems like there are some problems on storing the images to the localdisk folder.
Here is my controller code:
public function store(Request $request)
{
$lostitem =new Admin();
$this->validate($request, [
'date' => 'required',
'TimeFound' => 'required',
'AreaWhereFound' => 'required',
'image' => 'required',
'Remark' => 'required',
'DateClaimed' => 'required',
'TimeClaimed' => 'required',
'CategoryID'=>'required'
]);
$uuid = Str::uuid()->toString();
// $record = new Admin;
// return view('students.create');
$lostitem->code = $uuid;
$lostitem->date = $request->date;
$lostitem->TimeFound = $request->TimeFound;
$lostitem->AreaWhereFound = $request->AreaWhereFound;
$lostitem->image = $request->image;
if($request->hasfile('image'))
{
$filenameWithExt=$request->file('image')->getClientOriginalName();
$filename=pathinfo($filenameWithExt,PATHINFO_FILENAME);
$extension =$request->file('image')->getClientOriginalExtension();
$fileNameToStore=$filename.'_' .time().'.'.$extension;
$path=$request->file('image')->storeAs('public/images',$fileNameToStore);
// $file = $request->file('image');
// $extension =$file->getClientOriginalExtension();//getting image extensionimage
// $filename=time() ."." .$extension;
// $file->move('uploads',$filename->getClientOriginal);
// //getting from data base
}
else
{
// $lostitem->image = "";
$fileNameToStore='noimage.jpg';
}
$lostitem->image = $request->image ;
$lostitem->Remark = $request->Remark;
$lostitem->DateClaimed = $request->inputDateClaimed;
$lostitem->TimeClaimed = $request->TimeClaimed;
$lostitem->CategoryID = $request->CategoryID;
$lostitem->save();
return redirect(route('LostItem_add'))->with('successMsg', 'Record added!');
}
The other information is saved. I hope to get help.
Change Your controller code to this:
public function store(Request $request)
{
$lostitem =new Admin();
$this->validate($request, [
'date' => 'required',
'TimeFound' => 'required',
'AreaWhereFound' => 'required',
'image' => 'required',
'Remark' => 'required',
'DateClaimed' => 'required',
'TimeClaimed' => 'required',
'CategoryID'=>'required'
]);
$uuid = Str::uuid()->toString();
$lostitem->code = $uuid;
$lostitem->date = $request->date;
$lostitem->TimeFound = $request->TimeFound;
$lostitem->AreaWhereFound = $request->AreaWhereFound;
$lostitem->image = $request->image;
if($request->hasfile('image')){
$filenameWithExt=$request->file('image')->getClientOriginalName();
$filename=pathinfo($filenameWithExt,PATHINFO_FILENAME);
$extension =$request->file('image')->getClientOriginalExtension();
$fileNameToStore=$filename.'_' .time().'.'.$extension;
$path=$request->file('image')->move(public_path('images/'),$fileNameToStore);
}
else{
$fileNameToStore='noimage.jpg';
}
$lostitem->image = $request->image ;
$lostitem->Remark = $request->Remark;
$lostitem->DateClaimed = $request->inputDateClaimed;
$lostitem->TimeClaimed = $request->TimeClaimed;
$lostitem->CategoryID = $request->CategoryID;
$lostitem->save();
return redirect(route('LostItem_add'))->with('successMsg', 'Record added!');
}
And then access your image in the blade like this
<img src="{{ asset('images/'.$item->image) }}">
And make sure that you do have an folder named "images" in the public directory
Save the path of image in database
public function store(Request $request)
{
$lostitem =new Admin();
$this->validate($request, [
'date' => 'required',
'TimeFound' => 'required',
'AreaWhereFound' => 'required',
'image' => 'required',
'Remark' => 'required',
'DateClaimed' => 'required',
'TimeClaimed' => 'required',
'CategoryID'=>'required'
]);
$uuid = Str::uuid()->toString();
$lostitem->code = $uuid;
$lostitem->date = $request->date;
$lostitem->TimeFound = $request->TimeFound;
$lostitem->AreaWhereFound = $request->AreaWhereFound;
$lostitem->image = $request->image;
if($request->hasfile('image')){
$filenameWithExt=$request->file('image')->getClientOriginalName();
$filename=pathinfo($filenameWithExt,PATHINFO_FILENAME);
$extension =$request->file('image')->getClientOriginalExtension();
$fileNameToStore=$filename.'_' .time().'.'.$extension;
$path=$request->file('image')->move(public_path('images/'),$fileNameToStore);
}
else{
$fileNameToStore='noimage.jpg';
}
$lostitem->image = $path ;
$lostitem->Remark = $request->Remark;
$lostitem->DateClaimed = $request->inputDateClaimed;
$lostitem->TimeClaimed = $request->TimeClaimed;
$lostitem->CategoryID = $request->CategoryID;
$lostitem->save();
return redirect(route('LostItem_add'))->with('successMsg', 'Record added!');
}
& show it
<img src="{{ asset('images/'.$item->image) }}">
I updated and image is showed after that, but i need to delete the previous image (from folder) after updating with the new one.
//update
public function edit ($id)
{
$user = User::find($id);
// $user = User::where('id', $id)->first();
// $user = DB::table('users')->where('id', $id)->first();
return view('edit', compact('user'));
}
public function postEdit (Request $request) {
request()->validate([
'email' => 'required',
'fullname' => 'required',
'birthday' => 'required',
'address' => 'required|min:10',
]);
$image = $request->image;
// dd($image);
$id = $request->id;
$email = $request->email;
$fullname = $request->fullname;
$address = $request->address;
$birthday = $request->birthday;
$country = $request->country;
$image = $request -> file('image');
$destination = base_path().'/public/img';
$file_name = rand(100,1).date('h-i-s');
$image->move($destination, $file_name.".".$image->getClientOriginalExtension());
$img = $file_name.".".$image->getClientOriginalExtension();
User::where('id',$id)->update([
'image' => $img,
'email' => $email,
'fullname' => $fullname,
'birthday' => $birthday,
'address' => $address,
'country' => $country,
]);
return Redirect::to("dashboard")->withSuccess('Great! You have Successfully edited');
}
You can use File facade to delete a file:
use Illuminate\Support\Facades\File;
$pathToFile = base_path('public/img/'.$user->image);
File::delete($pathToFile);
You should first find the user and determine if he already has an image, sou you can delete it from the storage. Do it like this:
public function postEdit (Request $request) {
request()->validate([
'email' => 'required',
'fullname' => 'required',
'birthday' => 'required',
'address' => 'required|min:10',
]);
$user = User::where('id', $request->id)->first();
if($user->image){ //Check if user has image and delete it from storage
if (Storage::exists($user->image)) {
Storage::delete( $user->image ); //Dont forget to use your real paths. $user->image should be a path to an image.
}
}
$image = $request->image;
$id = $request->id;
$email = $request->email;
$fullname = $request->fullname;
$address = $request->address;
$birthday = $request->birthday;
$country = $request->country;
//Insert new image
$image = $request -> file('image');
$destination = base_path().'/public/img';
$file_name = rand(100,1).date('h-i-s');
$image->move($destination, $file_name.".".$image->getClientOriginalExtension());
$img = $file_name.".".$image->getClientOriginalExtension();
//Now update user
$user->update([
'image' => $img,
'email' => $email,
'fullname' => $fullname,
'birthday' => $birthday,
'address' => $address,
'country' => $country,
]);
return Redirect::to("dashboard")->withSuccess('Great! You have Successfully edited');
}