cybercog / laravel-ban

Laravel Ban simplify blocking and banning Eloquent models.
https://komarev.com/sources/laravel-ban
MIT License
1.07k stars 63 forks source link

$user->isBanned() not working #41

Closed INattivo closed 5 years ago

INattivo commented 5 years ago

Hi, I've installed component like instructions but I have some issue. Ban seam working if I sue method Ban() but if I put a future expired date, users are always not banned. Second $user->isBanned() give me always false. Can you help me?

I've Laravel 5.8 to protect routes I use this code in middleware Route::group(['middleware' => ['auth','logs-out-banned-user']], function () {......

Thanks

antonkomarev commented 5 years ago

Your title says that you want to make $user->isNotBanned() working, but in first comment you are testing if $user->isBanned(). What exactly you want to make? Be sure that user.banned_at database column has correct value, because both of these methods are just checking its value: https://github.com/cybercog/laravel-ban/blob/f99bdc90bebc7d2b8a01166ea8f68abaab2d74f3/src/Traits/HasBannedAtHelpers.php#L51-L64

INattivo commented 5 years ago

Thank you for the response. Sorry, I've done a mistake writing title, I correct it.

I have done some check and if I ban a user ($user->ban()) and invoke isBanned() method return always false.

If I try to login with this user I retrieve "This account is blocked."

User.banned_at is correct with yesterday date.

antonkomarev commented 5 years ago

Are you making isBanned check right after ban call (in the same request)? If yes, try to make a check on a fresh user model:

$user->ban();

if ($user->fresh()->isBanned()) {
  // Do some stuff
}
INattivo commented 5 years ago

No, banned are already done (not in same request) but with $user->fresh()->isBanned() working correctly. What is the reason of this behavior?

antonkomarev commented 5 years ago

When I'm saying that it's done in same request - it doesn't mean that both of the methods calls are in same controller. ban could be invoked in controller and then controller invokes some class which will invoke isBanned check for example. This happens because $user is immutable and not changing on it's ban method call until these changes will be refetched.

Why do you check if user was banned?

antonkomarev commented 5 years ago

In short: it happens because Bannable trait ban method in fact not changing attribute value of the model, but delegates this to BanService class. That means that mutated $user instance will be only in BanService. And fresh method refetching actual model state from the database.

INattivo commented 5 years ago

I've understood what you tell me if this appends in the same request. But happen in different request. If i use $user->fresh()->isBanned() give me true, now after i change again code with $user->isBanned(), give me always false.

antonkomarev commented 5 years ago

Can you provide a code samples how to reproduce it?

INattivo commented 5 years ago

Yes, this code work:

@foreach ($users as $user)
    <tr>
        <td><a href="{{Request::url()}}/{{ $user->id }}">{{ $user->user_name }}</a></td>
        <td>
            @foreach ($user->roles as $role)
                <span class="label label-default">{{$role->name}}</span>
            @endforeach
        </td>
        <td>{{ $user->email }}</td>
        <td>{{ $user->created_at }}</td>
        <td>@if($user->fresh()->isBanned()) YES @else NO @endif </td>
        <td>@if(!empty($user->last_login)){{ $user->last_login }}@endif</td>
    </tr>
@endforeach

This not work (always NO)

@foreach ($users as $user)
    <tr>
        <td><a href="{{Request::url()}}/{{ $user->id }}">{{ $user->user_name }}</a></td>
        <td>
            @foreach ($user->roles as $role)
                <span class="label label-default">{{$role->name}}</span>
            @endforeach
        </td>
        <td>{{ $user->email }}</td>
        <td>{{ $user->created_at }}</td>
        <td>@if($user->isBanned()) YES @else NO @endif </td>
        <td>@if(!empty($user->last_login)){{ $user->last_login }}@endif</td>
    </tr>
@endforeach

user.banned_at is polopated with data (not NULL)

antonkomarev commented 5 years ago

It's only frontend part. First of all - don't call fresh inside of the blade templates. If you need to call it - do it in controller. Could you show controller which performing ban of your user models & controller which displays users list from your example?

antonkomarev commented 5 years ago

@INattivo did you solve an issue?

antonkomarev commented 5 years ago

I'm closing this issue since there is no response and it might be already solved. Feel free to continue conversation here.