laravel soft delete using a form - laravel

Hi I am trying to soft delete and restore a user using a form, I am using a couple of packages for user auth and roles which are Zizaco Confide and Zizaco Entrust. I've added the following to the user.php model
use SoftDeletingTrait;
use ConfideUser;
use HasRole;
protected $softDelete = true;
and I've run a test as so to test this works:
Route::get('/deleteme', function(){
User::find(2)->delete();
return 'done';
});
and this updated the timestamp field, however I want to put this into my controller to neaten things up and give it a form. So I've done this in the table of users:
#if(empty($user->deleted_at))
{{Form::open(['method'=>'PATCH','action'=>
['UsersController#softDeleteUser',$user->id]])}}
<button type="submit">Suspend</button>
{{Form::close()}}
#else
{{Form::open(['method'=>'delete','action'=>
['UsersController#restoreUser',$user->id]])}}
<button type="submit">Re-activate</button>
{{Form::close()}}
#endif
and in my Controller:
public function softDeleteUser($id){
$user = User::find($id);
$user->delete();
// redirect
return Redirect::to('/admin');
}
public function restoreUser($id) {
User::find($id)->restore();
$user->save();
Redirect::to("/admin");
}
In my routes:
Route::post('/admin/user/{resource}/delete',
array('as' => 'admin.user.delete', 'uses'
=>'UsersController#softDeleteUser'));
Route::post('/admin/user/{resource}/restore',
array('as' => 'admin.user.restore',
'uses' =>'UsersController#restoreUser'));
However I get this error:
Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException
Any ideas what I'm doing wrong??

Well you've set your two forms to use the PATCH and DELETE method but your routes are set to POST (Route::post).
You can either change the routes:
Route::patch('/admin/user/{resource}/delete',
array('as' => 'admin.user.delete', 'uses'
=>'UsersController#softDeleteUser'));
Route::delete('/admin/user/{resource}/restore',
array('as' => 'admin.user.restore',
'uses' =>'UsersController#restoreUser'));
Or remove the method in your forms (it will default to POST)
{{Form::open(['action'=> ['UsersController#softDeleteUser',$user->id]])}}
<button type="submit">Suspend</button>
{{Form::close()}}
And
{{Form::open(['action'=> ['UsersController#restoreUser',$user->id]])}}
<button type="submit">Re-activate</button>
{{Form::close()}}

Related

Laravel policies strangely not working

The point is simple: I have a UserPolicy method that checks if a user wants to edit his/her own profile. So I did like this:
public function update(User $user, User $model)
{
return $user->id === $model->id;
}
And this is called in a UserController as it follows:
public function edit(User $user)
{
$this->authorize('update', $user);
return view('users.edit')->with('user', $user);
}
Everything is the same in a PostController and a PostPolicy, meant to check if a user can edit his/her own post and it works. The only difference is in their signature, since one has two users (the first one is the currently authenticated user injected by Laravel and the other is the instance I want to check it with) and the other has the above seen automatically injected authenticated user and a post instance. Anyway, it throws:
Symfony \ Component \ HttpKernel \ Exception \ AccessDeniedHttpException
This action is unauthorized.
I tried to dd($model) but I got the same exception.
Why? Thanks in advance!
EDIT
In my AuthServiceProvider is all set up, too:
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
Post::class => PostPolicy::class,
User::class => UserPolicy::class,
];
And so is my routes.php:
// Authentication Routes...
$this->post('login', 'Auth\LoginController#login')->name('login');
$this->post('logout', 'Auth\LoginController#logout')->name('logout');
// Registration Routes...
$this->post('register', 'Auth\RegisterController#register')->name('register');
// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController#sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController#reset');
Route::get('/', 'HomeController#index')->name('home');
Route::resource('posts', 'PostController');
Route::resource('users', 'UserController')->except('index', 'create', 'store');
Everything above is called right here:
#if ($user->id == Auth::id())
<a class="btn btn-link float-right p-0"
href="{{ route('users.edit', Auth::id()) }}">
<i class="fas fa-cog"></i>
Edit profile
</a>
<br><br><br>
#endif
I'm giving an answer myself: I tried to write the model and policy's full paths instead of registering the policies by the classes' names and it works (I don't know why, of course).
I did like this:
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
'App\User' => 'App\Policies\UserPolicy',
'App\Post' => 'App\Policies\PostPolicy',
];
Anyway, thanks everyone for trying to help me. Hope it will help someone else one day!
I just solved the same issue after fighting a whole day. Using full paths for register did not work for me. I fixed it by modifying my routes. I post my solution here hoping it may help someone someday.
If your routes are not protected by the authentication middleware, an AccessDeniedException will be thrown before applying your policies. The reason is that if your request comes in directly, you will never be treated as a logged-in user, so that you will be kicked off when trying to call $this->authorize('update') within the controller.
Route::middleware("auth:sanctum")->group(function () {
Route::post('/member/{id}', [MembersController::class, 'update']);
// ... and other path.
});

Custom function in Controller with resource wont work

I have created my own custom function in my RoomsController
public function join($id){
return $id;
}
Then I want to pass variable to it and it says MethodNotAllowedHttpException
And my Form looks like this
{{Form::open(['action'=> ['RoomsController#join', $room->id], 'method' => 'POST' ])}}
{{Form::submit('Join', ['class' => 'btn btn-danger'])}}
{{Form::close()}}
Also have these routes
Route::get('/','PagesController#index');
Route::get('/about', 'PagesController#about');
Route::get('/services', 'PagesController#services');
Route::get('/register', 'PagesController#register');
Route::get('/logout', 'PagesController#logout');
Route::get('/rooms/join', 'RoomsController#join');
Route::resource('posts','PostsController');
Route::resource('rooms','RoomsController');
Auth::routes();
Route::get('/dashboard', 'DashboardController#index');
I have tried in many different ways i dont know why it is not working. All update edit destroy resource functions are working. Thank's for helping :)
You're submitting a POST request but the route is expecting a GET request. If you change your route to Route::post('/rooms/join', 'RoomsController#join'); it should work
change the method to post and put the route below the resource route
Route::resource('rooms','RoomsController');
Route::post('/rooms/join', 'RoomsController#join');

Laravel Editing post doesn't work

There are routes
Route::get('posts', 'PostsController#index');
Route::get('posts/create', 'PostsController#create');
Route::get('posts/{id}', 'PostsController#show')->name('posts.show');
Route::get('get-random-post', 'PostsController#getRandomPost');
Route::post('posts', 'PostsController#store');
Route::post('publish', 'PostsController#publish');
Route::post('unpublish', 'PostsController#unpublish');
Route::post('delete', 'PostsController#delete');
Route::post('restore', 'PostsController#restore');
Route::post('change-rating', 'PostsController#changeRating');
Route::get('dashboard/posts/{id}/edit', 'PostsController#edit');
Route::put('dashboard/posts/{id}', 'PostsController#update');
Route::get('dashboard', 'DashboardController#index');
Route::get('dashboard/posts/{id}', 'DashboardController#show')->name('dashboard.show');
Route::get('dashboard/published', 'DashboardController#published');
Route::get('dashboard/deleted', 'DashboardController#deleted');
methods in PostsController
public function edit($id)
{
$post = Post::findOrFail($id);
return view('dashboard.edit', compact('post'));
}
public function update($id, PostRequest $request)
{
$post = Post::findOrFail($id);
$post->update($request->all());
return redirect()->route('dashboard.show', ["id" => $post->id]);
}
but when I change post and click submit button, I get an error
MethodNotAllowedHttpException in RouteCollection.php line 233:
What's wrong? How to fix it?
upd
opening of the form from the view
{!! Form::model($post, ['method'=> 'PATCH', 'action' => ['PostsController#update', $post->id], 'id' => 'edit-post']) !!}
and as result I get
<form method="POST" action="http://mytestsite/dashboard/posts?6" accept-charset="UTF-8" id="edit-post"><input name="_method" type="hidden" value="PATCH"><input name="_token" type="hidden" value="aiDh4YNQfLwB20KknKb0R9LpDFNmArhka0X3kIrb">
but why this action http://mytestsite/dashboard/posts?6 ???
Try to use patch instead of put in your route for updating.
Just a small tip you can save energy and a bit of time by declaring the Model in your parameters like this:
public function update(Post $id, PostRequest $request)
and get rid of this
$post = Post::findOrFail($id);
EDIT
You can use url in your form instead of action :
'url'=> '/mytestsite/dashboard/posts/{{$post->id}}'
Based on the error message, the most probable reason is the mismatch between action and route. Maybe route requires POST method, but the action is GET. Check it.
Try to send post id in hidden input, don't use smt like that 'action' => ['PostsController#update', $post->id]
It contribute to result action url.

Laravel 5 - insert multiple users

I have a simple User - Department relationship. My User Model has the following
public function department() {
return $this->belongsTo('App\Department', 'departmentId');
}
And my Department Model has
public function user() {
return $this->hasMany('App\User');
}
At the moment I am working with the departments side of things. My index function looks like the following
public function index() {
$departments = Helper::returnDepartmentsFromLdap();
return view('departments.index', compact('departments'));
}
What it basically does it gets all the departments from LDap (Active Directory) and displays them. On the index page for departments, I have
{!! link_to_route('departments.updateDepartments', 'Update Database', null, array('class' => 'btn btn-info')) !!}
So the database can be updated if new departments are added to our server. I do not have a create function as it is not needed.
Anyways, at the moment, my routes are like so
Route::model('departments', 'Department');
Route::bind('departments', function($value, $route) {
return App\Department::whereId($value)->first();
});
Route::resource('departments', 'DepartmentsController', ['except' => ['show', 'edit', 'create', 'delete', 'update', 'destroy']]);
Route::post('departments/updateDepartments', array('as' => 'departments.updateDepartments', 'uses' => 'DepartmentsController#updateDepartments'));
And in my updateDepartments function I am simply doing the following for now
public function updateDepartments()
{
dd("TEST");
}
If I click on the button on my index page to update the database, which should trigger the above, I am seeing a MethodNotAllowedHttpException.
Am I missing something obvious here?
try to use get:
because you can only pass data using get method with link link_to_route
Route::get('departments/updateDepartments', array('as' => 'departments.updateDepartments', 'uses' => 'DepartmentsController#updateDepartments'));
Route::post('departments/updateDepartments', ...) means you only allow POST requests on that route. Make sure the form method is POST instead of GET (default) on your index page

Laravel 4 route

I've got a problem with using URL::route. There is a public function in my controller called AuthController called delete_character, here's how it looks:
public function delete_character()
{
$player->delete();
return View::make('index')->with('danger', 'You have successfully deleted your character!');
}
Also, I've created a named route:
Route::post('delete_character', array(
'as' => 'delete_character',
'uses' => 'AuthController#delete_character'
));
All I want to do is to execute the $player->delete. I don't want it to be a site, just when I click a button it's gonna delete the player.
I've also done the button:
<td><a class="btn btn-mini btn-danger" href="{{ URL::route('delete_character') }}"><i class="icon-trash icon-white"></i> Delete</a></td>
But I constantly get MethodNotAllowedHttpException. Any hints?
In my example, I am using GET request method (POST is used when form is being submited, for instance) to capture this action.
I pass ID of client I wish to delete in the reqeust URL, which results into URL in this form: http://localhost:8888/k/public/admin/client/delete/1 (You should post it from form, according to your example/request).
Not posting whole solution for you to force you to learn! My answer is not 100% identical to your situation, but will help, for sure.
// routes.php
Route::group(['prefix' => 'admin'], function(){
Route::get('client/delete/{id}', 'Admin\\ClientController#delete');
});
// ClientController.php
<?php
namespace Admin;
use Client;
class ClientController extends BaseController
{
...
public function delete($clientId)
{
$client = Client::findOrFail($clientId);
// $client->delete();
// return Redirect::back();
}
...
}
// view file, here you generate link to 'delete' action
delete

Resources