Laravel 5: allow user to edit post if he's the owner of the post or the owner of the forum category
So how can I check if the users is the owner of the article OR the owner of the category to display and allow EDIT?
Use Laravel’s new authorization component.
EDIT: I think you’re misunderstanding how authorization should be used. It should be used to check if the current user can perform an action (or not). Therefore, you don’t want to be defining multiple methods for different users types.
Take editing a post for example. There’s the name of your authorization check: @can('edit', $post)
. You don’t need to define a different one for regular users, and another for moderators. Just add the logic to your edit post method:
class PostPolicy
{
public function edit(User $user, Post $post)
{
// If user is administrator, then can edit any post
if ($user->isModerator()) {
return true;
}
// Check if user is the post author
if ($user->id === $post->author_id) {
return true;
}
return false;
}
}
As you can see, I’m doing the different checks in the same method, so in your Blade template you can just do this:
@can('edit', $post)
<a href="{{ route('post.edit', $post->getRouteKey()) }}">Edit post</a>
@endcan
Hope this clears things up.
Related videos on Youtube
Halnex
Updated on September 15, 2022Comments
-
Halnex over 1 year
So far I was able to allow the user to edit his own posts but whenever I through the
if he's owner of the subreddit/category
condition, it stops working altogether.I have these 3 table
Users: id, name, email... Subreddits: id, name, user_id... Posts: id, link, title, user_id, subreddit_id...
This is the
edit()
method inPostsController.php
public function edit(Post $post, Subreddit $subreddit) { if(Auth::id() !== $post->user_id) { return view('home')->withErrors('You cannot do that'); } else { return view('post/edit')->with('post', $post)->with('subreddit', $subreddit); } }
And this is the view
@if(Auth::id() == $post->user_id) <a href="{{ action('PostsController@edit', [$post->id]) }}">Edit</a> @endif
This works fine, it only checks if the logged in user_id is the same as the posts's user_id and updating goes through.
But if I added
if(Auth::id() == $subreddit->user_id)
it stops working. It displays the "Edit" link on the view on all the posts but clicking on any of them gives me the validation errorYou cannot do that
even for posts that I own.So how can I check if the users is the owner of the article OR the owner of the category to display and allow EDIT?
Updated method with
$subreddit->user_id
public function edit(Post $post, Subreddit $subreddit) { if(Auth::id() == $post->user_id || Auth::id() == $subreddit->user_id) { return view('post/edit')->with('post', $post)->with('subreddit', $subreddit); } else { return view('home')->withErrors('You cannot do that'); } }
View
@if(Auth::id() == $post->user_id || Auth::id() == $subreddit->user_id) <a href="{{ action('PostsController@edit', [$post->id]) }}">Edit</a> @endif
This will allow me to edit my own posts but will still give me the validation error
You cannot do that
on posts in my own forum category/subreddit.This is the
Gate
policies that I've tried but it also didn't workclass AuthServiceProvider extends ServiceProvider { // Authorizations and Permissions public function boot(GateContract $gate) { parent::registerPolicies($gate); $gate->define('update-post', function ($user, $post) { return $user->id === $post->user_id; }); $gate->define('mod-update-post', function ($user, $subreddit) { return $user->id === $subreddit->user_id; }); }
PostsController.php
public function edit(Post $post, Subreddit $subreddit, User $user) { if(Gate::denies('update-post', $post) && Gate::denies('mod-update-post', $subreddit)) { return view('home')->withErrors('You cannot do that'); } else { return view('post/edit')->with('post', $post)->with('subreddit', $subreddit); } }
View
@can('update-post', $post) <a href="{{ action('PostsController@edit', [$post->id]) }}">Edit</a> @endcan
With the above code, I am finally able to edit posts if 'update-post' is true but I cannot check if
mod-update-post
is also true, I keep receiving the validation errorYou cannot do this
dd($subreddit)
inside edit() method shows an empty array. https://cryptbin.com/x6V6wX#26810f755a62f6c8837c0c0fe0371dcfEDIT: I think I've solved it. I used
$post->subreddit->user->id
instead of$subreddit->user_id
because that was returning null. And now it all seems to work based on if posts belongs to user or user is forum owner.But the edit link on the view still shows whether or not I have access. I am unable to double check for
update-post
andmod-update-post
simultaneously. and using@can('update-post', $post)
only works once, I cannot double check that. -
Halnex over 8 yearsI tried that before, I added a new policy
mod-update-post
that wouldreturn $user->id === $subreddit->user_id;
but I couldn't check for two@can
on the view and I found no documentation on the subject. -
Martin Bean over 8 yearsThat’s because you’re supposed to define a role for what you’re checking for, instead of combining them, i.e.
@can('edit', $post)
. Just do two boolean checks in that method on your policy instead of trying to combine checks in your view (which you shouldn’t be). -
Halnex over 8 yearsI have edited my post and added my gate policies, but it is still not working properly. I can see the EDIT link now on my posts but cannot edit them, getting the validation error.
-
Halnex over 8 yearsI refined my code, Gate policy
update-post
is working, butmod-update-post
is not. And I still need to use@can
on the view otherwise everyone would be able to see the EDIT link. -
Martin Bean over 8 yearsYes. So use
@can('edit', $post)
and then add your logic that determines whether the user can edit the post or not, and show the link if so. -
Halnex over 8 yearsWell I solved it by using the Gate facade within the if statement. Works like a charm. and I switched back to the Gate policies, better.
-
Martin Bean over 8 yearsI’ve updated my answer to give you an example of how you should be doing authorization checks.
-
Halnex over 8 yearsThank you for that. But I am still confused about
isModerator
where is that coming from? in PhpStorm, I'm gettingMethod not found in App\User
- do I need to create that? -
Martin Bean over 8 yearsYes. It’s example code for demonstration purposes; not to be copy-and-pasted. I don’t know how you designate how users are moderators; that’s up to you to implement.
-
Lord Jesus about 3 yearsI use the same policy as you mentioned. However, how do you handle if I copied the edit URL of the post and logout then login to a different user and paste it, still allowing me to edit the post (even though I am not the rightful owner to edit).