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 in PostsController.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 error You 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 work
class 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 error You cannot do this
dd($subreddit)
inside edit() method shows an empty array. https://cryptbin.com/x6V6wX#26810f755a62f6c8837c0c0fe0371dcf
EDIT: 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
and mod-update-post
simultaneously. and using @can('update-post', $post)
only works once, I cannot double check that.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With