Change PUT request to POST request to include image update - laravel

I wrote a post edit method which at first consisted only of text. I did the update using a PUT request.
Now I want to include images to my posts, so I added it, and it works for my POST request of creating a post but doesn't work for my update post, when I want to change image, since PUT request doesn't support file uploads.
So now I'm stuck trying to change my update method from PUT request that only updates text to a POST request that updates both the text and an image if supplied.
This is the code I wrote so far:
public function update(Request $request, Post $post)
{
//store updated image
if($request->hasFile('image') && $request->file('image')->isValid()){
if($post->hasMedia('posts')) {
$post->media()->delete();
}
$post->addMediaFromRequest('image')->toMediaCollection('post', 's3');
}
$post->update(request()->validate([
'body' => 'required'
]));
return redirect($post->path());
}
I think that the $post->update doesn't work for the POST request. I just want to update a text if an update was given.
Using Laravel 6.
EDIT: My form layout structure (simplified)
<form action="action="/posts/{post}" method="POST">
#method('PUT')
#csrf
<div class="form-group row">
<input id="body" type="text" class="form-control" name="body" value="{{ old('body', $post->body) }}">
<input id="image" type="file" class="form-control" name="image">
<button type="submit" class="btn btn-primary">Update Post</button>
</form>
My routes:
Route::get('/posts/{post}/edit', 'PostsController#edit')->name('posts.edit');
Route::put('/posts/{post}', 'PostsController#update');

I tried your code and it worked fine with me , only added #csrf in form tag.
<form action="/posts/{post}" method="POST" enctype="multipart/form-data">
#csrf
#method('PUT')
<div class="form-group row">
<input id="body" type="text" class="form-control" name="body" value="{{ old('body', $post->body) }}">
<input id="image" type="file" class="form-control" name="image">
<button type="submit" class="btn btn-primary">Update Post</button>
</form>

Related

The PUT method is not supported for this route. Supported methods: GET, HEAD

I'm trying to learn Laravel, and I'm following a series of tutorials called laracast. I'm at episode 24, "Forms that submit PUT requests. The short story is that the markup uses a hidden value to set the method to PUT, although the forms method is set to POST. Still, when I do this, I get the error message from the title:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD.
From the tutorials, I'd expect POST to also be a supported method. However, when I try to fix this, all resources I can find simply tells me what I already know. PUT is not supported, but I can fake it/override it, and then they refer to what I have already done... Are there any other reasons why I might get this error message?
HTML Form:
<form method="POST" action="/competition-categories">
#csrf
#method('PUT')
<div class="form-group row">
<label for="competition-category-name-input" class="col-4 col-form-label">Name</label>
<div class="col-8">
<input id="competition-category-name-input" name="competition-category-name-input" type="text" class="form-control" required="required" value="{{ $competitionCategory->name }}">
</div>
</div>
<div class="form-group row">
<label for="competition-category-abbreviation-input" class="col-4 col-form-label">Abbreviation</label>
<div class="col-8">
<input id="competition-category-abbreviation-input" name="competition-category-abbreviation-input" type="text" class="form-control" required="required" value="{{ $competitionCategory->abbreviation }}">
</div>
</div>
<div class="form-group row">
<div class="offset-4 col-8">
<button name="submit" type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
web.php snippet:
//Competition Categories
Route::get('/competition-categories', 'CompetitionCategoryController#index');
Route::get('/competition-categories/create', 'CompetitionCategoryController#create');
Route::get('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#show');
Route::get('/competition-categories/{competitionCategory}/edit', 'CompetitionCategoryController#edit');
Route::post('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#store');
Route::put('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#udpate');
Route::delete('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#destroy');
Snippet from the controller:
public function update(Request $request, CompetitionCategory $competitionCategory)
{
$competitionCategory->update($this->validateCompetitionCategory());
return redirect()->route('competition-categories' , [$competitionCategory]);
}
You're forgetting the id in form, this should fix your problem:
action="/competition-categories/{{$competitionCategory->id}}"
The most common thing that this happens is your cache. When you add a new route or change something in your routes, always run after php artisan optimize to refresh you cache.
I recommend using the named-routes for more informations and messages see =>
https://laravel.com/docs/7.x/routing#named-routes

How to upload the pdf or doc file in laravel

I am trying to upload the pdf or doc file on the website made up in laravel. This is my blade page.
<form action="{{ route('file.upload.post') }}" method="POST" enctype="multipart/form-data">
#csrf
<div class="row">
<input type="text" class="form-control-file" name="title" id="title" aria-
describedby="fileHelp", placeholder="title">
<input type="text" class="form-control-file" name="firstName" id="firstName" aria-
describedby="fileHelp", placeholder="First Name">
<input type="text" class="form-control-file" name="lastName" id="lastName" aria-describedby="fileHelp", placeholder="Last Name">
<input type="text" class="form-control-file" name="isReviewed" id="isReviewed" aria-describedby="fileHelp", placeholder="isReviewed">
<div class="col-md-6">
<input type="file" name="paper" class="form-control">
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-success">Upload</button>
</div>
</div>
</form>
This is my controller
public function fileUploadPost(Request $request)
{
$request->validate([
'firstName'=>'required',
'lastName'=>'required',
'isReviewed'=>'required',
'paper' => 'required|mimes:pdf,xlx,csv|max:2048',
]);
$Submission= new Submission;
$Submission->title= $request['title'];
$Submission->first_name= $request['firstName'];
$Submission->last_name= $request['lastName'];
$Submission->isReviewed= $request['isReviewed'];
$fileName= time().'.'.$request->paper->extension();
$old_path = Request::file('paper')->getPathName(); Storage::disk('Paper')->move($old_path,
public_path($fileName));
$Submission->save();
return back()
->with('success','You have successfully upload file.')
->with('file',$fileName);
}
I am getting an error saying that
Non-static method Illuminate\Http\Request::file() should not be called statically
to fix this i
use Illuminate\Support\Facades\Request
instead of
use Illuminate\Http\Request;
but then I get an error saying I cannot use validation. Any kind of help is appreciated.
You don't need to use the facade for this. You can still use the standard Illuminate\Http\Request class.
To get the file, you should use:
$request->file('paper')
rather than
Request::file('paper')

How to set a route to a controller and access it via a form? [duplicate]

This question already has answers here:
Laravel form post to controller
(2 answers)
Closed 3 years ago.
I'm trying to set a route to my "MessagesController" so that a i can access it from my form, How do i set a route to the controller and access it from action form ?
This is my Form code
<form action="#" id="ajax-contact" method="GET" enctype="multipart/form-data" >
{{csrf_field()}}
<div class="input-field">
<input type="text" class="form-control" name="name" id="nom" required
placeholder="Nom">
</div>
<div class="input-field">
<input type="email" class="form-control" name="email" id="email" required
placeholder="E-mail">
</div>
<div class="input-field">
<textarea class="form-control" name="message" id="message" required
placeholder="Message"></textarea>
</div>
<button class="btn" type="submit">Soumettre</button>
</form>
What should i write inside my web.php to set a route so i can acces my MessageController.php what should i write inside the action attribute ?
Okay not sure what you want but here is the whole thing
REQUEST(FORM) => ROUTE => CONTROLLER => RESPONSE
So you want to go from FORM to Controller you have to :
Create a controller (in App\Http\Controllers) and a method
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class MyController extends Controller
{
// This method will handle the form
// $request is where the form data will be
public function handleForm(Request $request){
// this means dump all form values
dd($request->all());
}
}
Create a route ( In simple words, this will link between FORM & Controller method ) in web.php
// The request need to be POST to /handle-data
Route::post('handle-data','MyController#handleForm');
finally this should be your form
<form action="/handle-data" id="ajax-contact" method="POST" enctype="multipart/form-data" >
{{csrf_field()}}
<div class="input-field">
<input type="text" class="form-control" name="name" id="nom" required
placeholder="Nom">
</div>
<div class="input-field">
<input type="email" class="form-control" name="email" id="email" required
placeholder="E-mail">
</div>
<div class="input-field">
<textarea class="form-control" name="message" id="message" required
placeholder="Message"></textarea>
</div>
<button class="btn" type="submit">Soumettre</button>
</form>
If you want to make this as an ajax call
$( "#ajax-contact" ).submit(function( event ) {
event.preventDefault();
var data = $(this).serializeArray();
$.post('/handle-data', data ).then(function(response){
console.log(response);
});
});
if you want to test the ajax way, change the dd($request->all()); to return response()->json($request->all());
That should be it :)
Edit routes inside web.php to point to submit method in MessagesController:
Route::post('submit', 'MessagesController#submit')->name('submit');
then set form action to:
<form action="{{ route('submit') }}" id="ajax-contact" method="POST" enctype="multipart/form-data">
You should POST from a form.

Laravel Update Function Not Running Correct Response

When I attempt to update a record in my Laravel application, it is running the wrong URL causing an error 404. This function was working fine when I was developing locally however now it is hosted on a one.com server, it has stopped working.
edit.blade.php
<form method="POST" action="gins/{{ $gins->id }}">
#method('PATCH')
#csrf
<div class="field">
<label class="label" for="gin">Gin</label>
<div class="control">
<input type="text" class="input" name="gin"
placeholder="Gin" value="{{ $gins->gin }}">
</div>
</div>
<div class="field">
<label class="label" for="size">Bottle Size(ml)</label>
<div class="control">
<input type="text" class="input" name="size"
placeholder="Size (ml)" value="{{ $gins->size }}">
</div>
</div>
<div class="field">
<label class="label" for="price">Price(£)</label>
<div class="control">
<input type="text" class="input" name="price"
placeholder="Price of Gin" value="{{ $gins->price }}">
</div>
</div>
<div class="field">
<div class="control">
<button type="submit" class="button is-success">Update Record
</button>
</div>
</div>
</form>
Route
Route::patch('gins/{gin}', 'PostsController#update')->middleware('auth');
Auth::routes();
Controller
public function update(Request $request, $id)
{
$gins = \App\Gins::findOrFail($id);
$gins->gin = request('gin');
$gins->size = request('size');
$gins->price = request('price');
$gins->save();
return redirect('gins');
}
The URL for the edit page is Laravel/gins/7/edit. When I click the submit button it's returning the URL Laravel/gins/7/gins/7 when it should be redirecting back to Laravel/gins/7.
The 7 in the Url is the record id from the particular record I'm attempting to update.
It's always a bad idea to hardcode urls like that. The following
<form method="POST" action="gins/{{ $gins->id }}">
in a route like laravel/gins/ would evaluate to laravel/gins/gins/7.
Also, routes change all the time in a dynamic web application. For this reason, I'd suggest you to use Named Routes.
For example:
Route::patch('gins/{gin}', 'PostsController#update')
->middleware('auth')
->name('posts.update');
and then change your form action to this:
<form method="POST" action="{{ route('posts.update', ['gin' => $gins->id]) }}">
I would also clean up your update() method a bit.
public function update(Request $request, $id)
{
$gins = \App\Gins::findOrFail($id);
$gins->gin = request('gin');
$gins->size = request('size');
$gins->price = request('price');
$gins->save();
// change this to a named route as well
return redirect('gins');
// or if you just want to return back to the previous page, you can do
// return back();
}

Laravel 5.4 - Updating a resource

I'm building a blog post to learn Laravel 5.4 and am struggling to find any examples of how to update a Post anywhere.
My form is as follows
<form method="POST" action="/posts/{{ $post->id }}/edit">
{{ csrf_field() }}
<div class="form-group">
<label for="title">Title</label>
<input name="title" type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="{{ $post->title }}" required>
</div>
<div class="form-group">
<label for="description">Description</label>
<input name="description" type="text" class="form-control" id="exampleInputPassword1" value="{{ $post->title }}" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
My Routes are as follows
Route::get('/posts/{post}/edit', 'PostsController#edit');
Route::patch('/posts/{post}', 'PostsController#update');
And my controller methods are
public function edit( Post $post )
{
return view('posts.edit', compact('post'));
}
public function update(Request $request, Post $post )
{
Post::where('id', $post)->update($request->all());
return redirect('home');
}
I get a MethodNotAllowedHTTPException error but am not sure which part / parts of this I am getting wrong.
I'm assuming it must be the point at which I'm using the PATCH function, or potentially just the way I'm mass-assigning the new values. Any help would be greatly appreciated.
you should use
{{ method_field('PATCH') }}
as your form field
and change action to
/posts/{{ $post->id }}
like this:
<form method="POST" action="/posts/{{ $post->id }}">
{{ csrf_field() }}
{{ method_field('PATCH') }}
<div class="form-group">
<label for="title">Title</label>
<input name="title" type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="{{ $post->title }}" required>
</div>
<div class="form-group">
<label for="description">Description</label>
<input name="description" type="text" class="form-control" id="exampleInputPassword1" value="{{ $post->title }}" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
There are a couple of things you have missed out.
Firstly, as #Maraboc pointed out in the comments you need to add method spoofing as standard HTML forms only allow for GET and POST methods:
<input type="hidden" name="_method" value="PATCH">
or
{{ method_field('PATCH') }}
https://laravel.com/docs/5.4/routing#form-method-spoofing
Then you will also need to omit the "edit" uri in your forms action:
<form method="POST" action="/posts/{{ $post->id }}">
or
<form method="POST" action="{{ url('posts/' . $post->id) }}">
https://laravel.com/docs/5.4/controllers#resource-controllers
(scroll down a little bit to the Actions Handled By Resource Controller section)
You also may find it helpful to watch https://laracasts.com/series/laravel-5-from-scratch/episodes/10
Hope this helps!
When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application's users. Laravel's resource classes allow you to expressively and easily transform your models and model collections into JSON.

Resources