working with Laravel 5.6 and MySQL. I am going to update categoryname and image in my categories table using the following controller function?
public function update(Request $request, $id)
{
if ($request->isMethod('get'))
return view('categories.form', ['image' => Category::find($id)]);
else {
$rules = [
'categoryname' => 'required',
];
$this->validate($request, $rules);
$image = Category::find($id);
if ($request->hasFile('image')) {
$dir = 'images/';
if ($image->image != '' && File::exists($dir . $image->image))
File::delete($dir . $image->image);
$extension = strtolower($request->file('image')->getClientOriginalExtension());
$fileName = str_random() . '.' . $extension;
$request->file('image')->move($dir, $fileName);
$image->categoryimage = $fileName;
} elseif ($request->remove == 1 && File::exists('images/' . $image->image)) {
File::delete('images/' . $image->post_image);
$image->categoryimage = null;
}
}
$image->categoryname = $request->categoryname;
$image->save();
return redirect()->route('categories.index');
}
and route
Route::match(['get', 'put'], 'category/update/{id}', 'CategoryController#update');
and edit form
#if(isset($image))
<form method="PUT" action="http://localhost:8000/category/update/{{$image->id}}" enctype="multipart/form-data">
<input type="hidden" name="_method" value="put">
<label for="description" class="col-form-label col-md-3 col-lg-2">Description</label>
<div class="col-md-8">
<input class="form-control" autofocus placeholder="Description" name="categoryname" type="text" id="categoryname" value="{{ isset($image) ? $image->categoryname : '' }}">
<label for="image" class="col-form-label col-md-3">Image</label>
<div class="col-md-5">
<img id="preview"
src="{{asset((isset($image) && $image->categoryimage!='')?'images/'.$image->categoryimage:'images/noimage.png')}}"
height="200px" width="200px"/>
<input class="form-control" style="display:none" name="image" type="file" id="image" name="_token" value="{{ csrf_token() }}">
<br/>
Add Image |
<a style="color: red" href="javascript:removeImage()">Remove</a>
<input type="hidden" style="display: none" value="0" name="remove" id="remove">
but when I try to update data it is not updating. only refresh to the same page. no, any error
url look like this
http://localhost:8000/category/update/21?categoryname=tractorrer&image=&remove=0 //tractorrer is updated category name
how can fix this problem?
Theres a few things concerning about your code examples. Like only having 1 method called update for both GET and PUT routes. Probably not a good habit to get into. Especially since, if it is a get route, you're not updating anything. So already the method name / description of what it does, is wrong.
But that aside, you are not seeing anything because you cannot use method="PUT" on your form. You need to use method="POST" and then inside your form, you need these lines. One to tell the form that this is a patch request, and one to put the csrf token in.
{{csrf_field()}}
{{ method_field('PATCH') }}
and I would update your route to PATCH, not PUT.
First.
Have you dump all of the request like this to check whether it contains categoryname.
dd($request->all());
If the dd does not print categoryname value, then it seems to be the problem when you sending request.
Then.
Try using method="POST" instead of method="PUT" If you have not try yet.
I have never used PUT with form submit before
First,
You set POST instead of PUT of form method.
Second,
Your codes look a little messy. I updated your action codes;
public function update(Request $request, $id)
{
if ($request->isMethod('get')){
return view('categories.form', ['image' => Category::find($id)]);
} else{
$rules = [
'categoryname' => 'required',
];
$this->validate($request, $rules);
$image = Category::find($id);
if ($request->hasFile('image')) {
$dir = 'images/';
if ($image->image != '' && File::exists($dir . $image->image))
File::delete($dir . $image->image);
$extension = strtolower($request->file('image')->getClientOriginalExtension());
$fileName = str_random() . '.' . $extension;
$request->file('image')->move($dir, $fileName);
$image->categoryimage = $fileName;
} elseif ($request->remove == 1 && File::exists('images/' . $image->image))
{
File::delete('images/' . $image->post_image);
$image->categoryimage = null;
}
$image->categoryname = $request->categoryname;
$image->save();
return redirect()->route('categories.index');
}
}
Can you try again with my directives. I hope it helping your problem.
Related
I am working on a laravel crud project. Now i want to store files like .xlsx and .docx
But i keep getting errors in my controller and browser:
Controller:
public function store(Request $request)
{
$request->validate([
'title'=>'required',
'description_short'=>'',
'description_long'=>'',
'file'=>'',
'language_id'=> [
'required', 'exists:language,id'
],
]);
$fileName = $request->file->getClientOriginalName();
$filePath = 'files/' . $fileName;
$path = Storage::disk('public')->put($filePath, file_get_contents($request->file));
$path = Storage::disk('public')->url($path);
$file = new File([
'title'=> $request->get('title'),
'description_short'=> $request->get('description_short'),
'description_long'=> $request->get('description_long'),
'file'=>$request->get('file'),
'language_id'=> $request->language_id,
]);
$file->save();
return back();
}
Here i get the error: Undefined method 'url'
Create page:
<form method="post" action="{{ route('admin.language.store') }}" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="title">{{('name')}}</label>
<input type="text" class="form-control" name="name"/>
</div>
<div class="form-group">
<label for="value">{{('file')}}</label>
<input type="file" class="form-control" name="file"/>
</div>
<button type="submit" class="btn btn-primary">Add language</button>
</form>
the browser error i get is : Call to a member function getClientOriginalName() on string.
if i need to provide more information i will gladly do so!
file is reserved keyword in Request class to get submitted Files in post method.
You can not use file in input. So first you have to change file name in input box.
After that you can do like below.
$request->file('file_input_name')->getClientOriginalName();
$file = $request->file->getClientOriginalName();
fixed it
Let's say that I want to upload 3 images a.jpeg, b.jpeg and c.jpeg
I've successfully selected the images that i want to upload.
Sent them to the Controller and checked with print_f() to see if they're actually to the controller. They were.
Then when I've checked my img folder only c.jpeg were successfully uploaded while rest are not.
What is the reason of this?
// AdminController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\Http\Redirect;
use Image;
// Route
Route::post('/upload', 'AdminController#store')->name('upload');
// AdminController#store:
public function store(Request $request){
if ($request->hasfile('images')) {
foreach ($request->images as $image) {
$name = time() . '.' . $image->getClientOriginalExtension();
print_r($name."<br>"); // to see if they're actually passed.
Image::make($image)->save(public_path('img/new/'. $name));
}
}
return('done');
}
<form action="{{ route('upload') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" name="images[]" id="exampleInputFile" multiple />
</div>
{{ csrf_field() }}
<button type="submit" class="btn btn-default">Submit</button>
</form>
Problem was that I was using the time() function and not rand() or any similar function that returns a random value.
So the code shoud look like this now:
public function store(Request $request){
if ($request->hasfile('images')) {
foreach ($request->images as $image) {
$name = rand() . '.' . $image->getClientOriginalExtension();
print_r($name."<br>"); // to see if they're actually passed.
Image::make($image)->save(public_path('img/new/'. $name));
}
}
return('done');
}
I have edit blade file in my laravel application. in this edit form update data saving to two tables to vehicles and uploads. I have following codes in edit blade file update images to uploads table,
#foreach( $vehicles-> uploads as $upload)
<img id="preview"
src="{{asset((isset($upload) && $upload->resized_name!='')?'images/'.$upload->resized_name:'images/noimage.png')}}"
height="200px" width="200px"/>
<input class="form-control" style="display:none" name="files[]" type="file" id="files" name="_token" value="{{ csrf_token() }}" enctype="multipart/form-data">
<br/>
Add Image |
<a class="button is-outlined" href="/myads/{{$upload->id}}/delete" onclick="return confirm('Are you sure to want to delete this record?')" >Delete</a></td>
<hr>
#endforeach
#endif
update controller is,
$photos = $request->file('files');
if (!is_array($photos)) {
$photos = [$photos];
}
if (!is_dir($this->photos_path)) {
mkdir($this->photos_path, 0777);
}
for ($i = 0; $i < count($photos); $i++) {
$photo = $photos[$i];
$name = sha1(date('YmdHis') . str_random(30));
$save_name = $name . '.' . $photo->getClientOriginalExtension();
$resize_name = $name . str_random(2) . '.' . $photo->getClientOriginalExtension();
Image::make($photo)
->resize(250, null, function ($constraints) {
$constraints->aspectRatio();
})
->save($this->photos_path . '/' . $resize_name);
$photo->move($this->photos_path, $save_name);
$upload = Upload::find($id);
$upload->filename = $save_name;
$upload->resized_name = $resize_name;
$upload->original_name = basename($photo->getClientOriginalName());
$upload->vehicle_id = $vehicle->id;
$upload->save();
}
and route is,
Route::post('myads/{id}', [
'uses' => '\App\Http\Controllers\VehicleController#update',
])->name('vehicles.edit');
but when I attach image and click update buttons it is not update image in uploads table. how can fix this problem?
I think that you used wrong method in the update controller.
if (!is_array($photos)) {
$photos = [$photos];
}
Please try this method to convert string to array.
if (!is_array($photos)) {
$photos = explode(' ', $photos);
}
Your HTML code is wrong.
Don't use style="display:none" in input element. Browser will ignore it if they are hidden.
Don't merge CSRF Token with Input files.
Try this:
#foreach( $vehicles-> uploads as $upload)
<img id="preview" src="{{asset((isset($upload) && $upload->resized_name!='')?'images/'.$upload->resized_name:'images/noimage.png')}}" height="200px" width="200px"/>
<input class="form-control" name="files[]" type="file" id="files" enctype="multipart/form-data">
{{ csrf_field() }}
<br/>
Add Image |
<a class="button is-outlined" href="/myads/{{$upload->id}}/delete" onclick="return confirm('Are you sure to want to delete this record?')" >Delete</a>
<hr>
#endforeach
Using Laravel 5.4, I'm tring to setup a form where a user can enter a food name and its image. While trying to upload a PNG or JPG image, I get the following Validation Error:
The image must be an image.
If I remove the validation for image, I get a FatalErrorException:
Call to a member function getClientOriginalExtension() on null
which is a helper function provided by Intervention/Image library. This could mean that the image didn't upload at all.
FORM
<form action="/hq/foods" method="POST">
{{ csrf_field() }}
<input type="text" name="name">
<input type="file" name="image">
<button type="submit" class="btn btn-success ">
ADD FOOD ITEM
</button>
</form>
CONTROLLER
public function store(Request $request) {
$this->validate($request, [
'name' => 'required|min:2|max:255',
'image' => 'required|image'
]);
$food_category = FoodCategory::find($request->food_category_id);
$food = new Food;
$food->name = $request->name;
$image = $request->file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
$location = public_path('img/foods/' . $filename);
Image::make($image)->resize(800, 400)->save($location);
$food->image = $filename;
$food->save();
Session::flash('success',
'
<h4>Success!</h4>
<p>The food item has been added to the Menu.</p>
');
return back();
}
What am I missing?
To upload images you need to add:
enctype="multipart/form-data"
to your form so instead of:
<form action="/hq/foods" method="POST">
you should use
<form action="/hq/foods" method="POST" enctype="multipart/form-data">
If you use Laravelcollective
{!! Form::open(['method'=>'post','files' => true,'url'=>'/hq/foods']) !!}
OR
Using HTML
<form action="/hq/foods" method="POST" enctype="multipart/form-data">
you need to add enctype="multipart/form-data" in your from
I have a 2 tables, Courses and Lessons:
Course:
id, user_id, title
Lessons:
id, course_id , title
And I have updated their Eloquent Relationship.
Now my problem is, how to create a lesson without using a parameters in the form? Because i think it's not a good practice and prone to security issues, like editing the html tag.
<form method="POST" action="{{url('/lesson/store/3')}}" class="form-horizontal" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label class="control-label col-sm-2" for="title">Title:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="title" name="title" placeholder="Enter title">
</div>
</div>
</form>
From my route:
Route::group(['prefix' => 'lesson'] , function(){
Route::get('create/{course_id}' , 'LessonController#create');
Route::post('store/{course_id}' , 'LessonController#store');
});
And my controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Course;
use App\Lesson;
class LessonController extends Controller
{
public function create($course_id)
{
$course = Course::find($course_id);
return view('lesson.create' , compact('course'));
}
public function store(Request $request, $course_id)
{
$lesson = new Lesson;
$lesson->title = $request->title;
$lesson->course_id = $course_id;
$lesson->description = $request->description;
$lesson->episode = $request->episode;
if($request->hasFile('video'))
{
$file = $request->file('video');
$extension = $file->getClientOriginalExtension();
$video = 'course' . $course_id . '_ep' . $request->episode . $extension;
$destinationPath = public_path() . '/uploads/lessons/';
$file->move($destinationPath, $video);
$lesson->video = $video;
}
$lesson->save();
return redirect('course/show/' . $course_id);
}
}
and also, hidden input is not also advisable.
Another option is to have a hidden input with the id which will be passed with the form submission to your controller.