Attempt to update users table generates MethodNotAllowedHttpException, Laravel-4 - php

UsersController:
public function update($id)
{
if( ! $this->user->isValid(Input::all()))
{
return Redirect::back()->withInput()->withErrors($this->user->errors);
}
$user = $this->user->find($id);
$user->save();
return Redirect::route('users.index');
}
Route:
Route::resource('users','UsersController');
Model:
protected $table = 'users'
edit.blade.php:
{{ Form::model($user, array('route'=>array('users.update','$user'=>'id'))) }}
I notice that this does NOT generate a "PUT" action. The page source:
<form method="POST" action="https://zocios.com/users/id" accept-charset="UTF-8"><input name="_token" type="hidden" value="...">
Hitting the Update User button gets me:
Exception \ MethodNotAllowedHttpException
Is the problem "$user->save();"? Something else I'm doing wrong? Thanks!

You need to specify the method:
{{ Form::model($user, array('method' => 'put', 'route'=>array('users.update','$user'=>'id'))) }}
There is no other method than GET and POST that is accepted (despite the specs), so the framework does the job of identyfying hidden input in your form _method to make it work.

Related

Symfony Turbo Clear form after the success submit

I'm trying to clear my form after the form submit but unfortunately, it doesn't work
Here's my controller.
#[Route('/', name: 'homepage', methods: ['GET', 'POST'])]
public function index(Request $request, FooRepo $fooRepo): Response
{
$foo = new Foo();
$form = $this->createForm(FooType::class, $foo);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$fooRepo->save($foo, true);
if (TurboBundle::STREAM_FORMAT === $request->getPreferredFormat()) {
// If the request comes from Turbo, set the content type as text/vnd.turbo-stream.html and only send the HTML to update
$request->setRequestFormat(TurboBundle::STREAM_FORMAT);
return $this->render('shared/success.html.twig', ['status' => "Success!"]);
}
return $this->redirect($this->generateUrl("homepage"));
}
return $this->render('home/index.html.twig', [
controller_name' => 'HomeController',
'form' => $form
]);
}
So far, I tried the unset and redirect from this How can I clear form values after successful form submission but no success.
Here's my sample UI:
{{ form_start(form) }}
<input type="text" name=" {{ field_name(form.name) }} " placeholder="enter name"/>
<button type="submit">Save</button>
{{ form_end(form) }}
I'm using turbo that's why there's no page reload when I hit submit. There's no issue in saving but when the ajax call finished, the field doesn't clear after the submission. Any help?

How to encrypt id in URL laravel

I want to encrypt the id in URL I'll show my controller code and route. I've already used Crypt::encrypt($id); in my controller but it's not working properly so I've commented that line in my controller
this is my controller
public function update(TenderRequest $request,$id){
$tender = TenderMaster::findOrFail($id);
//Crypt::encrypt($id);
if($request->extend_date < $request->end_date || $request->bid_status > 0){
return 'unsuccess';
} else{
$transaction = DB::transaction(function () use($request,$tender,$id) {
$tender->extend_date = $request->extend_date;
$tender->remarks = $request->remarks;
$tender->update($request->all());
});
return 'BID '.$tender->ref_no.' Succesfully Updated';
}
}
}
this is my route
Route::post('tender/update/{id}','Tender\TenderMasterController#update')->name('bid.update');
this is my blade
<form action="{{route('bid.update' ,Crypt::encrypt('id'))}}" class="form-horizontal" id="bid-update" method="POST">
{{ csrf_field() }}
#method('POST')
#include ('tender.form', ['formMode' => 'edit'])
</form>
Put this in your form action tag
<form action="/tender/update/{{Crypt::encrypt('id')}}" class="form-horizontal" id="bid-update" method="POST">
{{ csrf_field() }}
#method('POST')
#include ('tender.form', ['formMode' => 'edit'])
</form>
And replace this line of your controller:
$tender = TenderMaster::findOrFail($id);
With this:
$tender = TenderMaster::findOrFail(Crypt::decrypt($id));
And don't forget to add this line above in your controller
use Illuminate\Support\Facades\Crypt;
Hopefully it'll work
there's function encrypt and decrypt
but, i would like to disagree with idea of encrypting user id, its far from best practice
i would like to recommend you to use policy, policy guide
Use laravel builtin encryption to achieve this:
While adding your route in frontend, encrypt id with encryption helper like this:
{{route('bid.update', encrypt($id))}}
Now, In your controller, decrypt the id you have passed.
public function update($id, Request $request){
$ID = decrypt($id);
$tender = TenderMaster::findOrFail($ID);
..
...
}
I hope you understand.
Here is the docs:
https://laravel.com/docs/6.x/helpers#method-encrypt
https://laravel.com/docs/6.x/helpers#method-decrypt

Laravel unable to delete records, but methods are specified as delete

I want to delete records from database through my website. I have specified my methods as DELETE but it doesn't seem to be working.
In my form method, I have specified it as DELETE
<form method = "DELETE" action = "/admin_delete_bitstamp/{{ $data->bitstamp_api_id }}">
<button type = "submit" name = "delete" class = "btn">Delete</button>
</form>
In my routes file, I have also specified it as DELETE
Route::delete("/admin_delete_bitstamp/{id}", "Bitstamp_Access_C#destroy");
This is my delete function
public function destroy($id) {
$api = Bitstamp_Access_M::find($id);
$api->delete();
return redirect()->back();
}
The error message that I am getting is "The GET method is not supported for this route. Supported methods: DELETE."
I apologize if this is a rookie mistake.
Please try following code in view file:
<form method = "POST" action = "/admin_delete_bitstamp/{{ $data->bitstamp_api_id }}">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button type = "submit" name = "delete" class = "btn">Delete</button>
</form>

Adding token to view make laravel

I have link like this with token:
Submit New
which produce url:
http://example.com/users/submit/20?_token=fpf0LwHyf0JGBg0fnixjRFo1B5GgUM3RDp6dVgUU
Now in my controller I've added condition which check one column in database and based on this is returning different views.
public function wrongIdSubmit($Id) {
$submits = self::$user->where('submit_id', $Id)->first();
if (!$txid) {
App::abort(404);
}
if($submits->submit_id > 3) {
return View::make('fail',[
'submits' => $submits
]);
}
else {
return View::make('submit',[
'submits' => $submits
]);
}
}
My question is how to pass this token ?_token={{ csrf_token() }} to return View::make along with $submits variable? Because like is now I've got error
production.ERROR: Illuminate\Session\TokenMismatchException
You must add the token to the form itself. You cannot pass it in the URL. Add the following to your form:
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
Laravel provide function which returns you direct input hidden field with token.
csrf_field()
It will Generates an HTML hidden input field containing the value of the CSRF token.
so you can try like this:
return View::make('fail',[
'submits' => $submits,
'token' => csrf_field()
]);
and in view just print:
{!! $token !!}
or direct also like:
{!! csrf_field() !!}
out put will be like:
<input type="hidden" name="_token" value="*****" />
Best of luck..

Laravel Form Model Binding not submitting

I'm having some trouble using form model binding with L4. My form is being populated, and the routes are correct but it's not submitting correctly.
Controller:
public function edit($id)
{
$transaction = Transaction::where('id', '=', $id)->get();
return View::make('transaction')->with('transactions', $transaction);
}
public function update($id)
{
$transaction = Transaction::find($id);
$input = Input::all();
$transaction->status = $input['status'];
$transaction->description = $input['description'];
$transaction->save();
}
View:
#foreach($transactions as $transaction)
{{ Form::model($transaction, array('route' => array('transactions.update', $transaction->id))); }}
{{ Form::text('description'); }}
{{ Form::select('status', array('R' => 'Recieved', 'S' => 'Shipped', 'P' => 'Pending'), 'R'); }}
{{ Form::submit('Submit'); }}
{{ Form::close(); }}
#endforeach
I'm assuming that your transactions.* routes are being generated via Route::resource().
Per the documentation, Laravel generates the following routes for a resource:
Verb Path Action Route Name
GET /resource index resource.index
GET /resource/create create resource.create
POST /resource store resource.store
GET /resource/{resource} show resource.show
GET /resource/{resource}/edit edit resource.edit
PUT/PATCH /resource/{resource} update resource.update
DELETE /resource/{resource} destroy resource.destroy
You'll see that resource.update is expecting a PUT/PATCH request, but Laravel forms default to POST.
To fix this, add 'method' => 'PUT' to the array of form options, like so:
{{ Form::model($transaction, array(
'method' => 'PUT',
'route' => array('transactions.update', $transaction->id)
)); }}
This will add a hidden input, <input type="hidden" name="_method" value="PUT" />, to your form which tells Laravel to spoof the request as a PUT.

Categories