0

I added External Scope for User Model. Simply created Scope, with the name DeveloperScope

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Auth;

class DeveloperScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        if(Auth::user()->id != 1){
            $builder->where('id', '<>', 1);
        }
    }
}

Then, I called this scope for User model.

User Model

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\Scopes\DeveloperScope;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    use SoftDeletes;
    use Authenticatable, CanResetPassword;


    protected $table = 'users';

    protected $fillable = ['first_name', 'last_name', 'email', 'password'];

    protected $hidden = ['password', 'remember_token'];

    protected $dates = ['deleted_at'];

    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope(new DeveloperScope);
    }
}

It works well, when I don't use Auth::class inside DeveloperScope class. The reason is that, I just want to hide the main user for another users for all Eloquent methods. Of course, I can use session instead of Auth and retrieve user id. But it is still interesting for me, why browser gives an error: ERR_EMPTY_RESPONSE while using Auth::class ?

2 Answers 2

1

The method what you are looking for is exactly Auth::hasUser(). The method was added in Laravel 5.6 through my PR. (So you need to upgrade Laravel first)

[5.6] Add ability to determine if the current user is ALREADY authenticated without triggering side effects by mpyw · Pull Request #24518 · laravel/framework

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class DeveloperScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        if (!Auth::hasUser() || Auth::user()->id != 1) {
            $builder->where('id', '<>', 1);
        }
    }
}

Just call Auth::hasUser() to prevent Auth::user() from causing side effects.

Sign up to request clarification or add additional context in comments.

Comments

0

Try injecting the Illuminate\Auth\Guard class and then call the user method on it. e.g.:

$this->auth->user();

You should be fine with just type-hinting it since Laravel will automatically new up an instance for you.

For more info check out the API: https://laravel.com/api/5.2/Illuminate/Auth/Guard.html

6 Comments

As I understand, you mean calling __construct function and retrieve auth. Why inject Guard? We could just inject Auth. But both of them will not work. I tried. Also, it is possible just return Auth::user() from construct. Now, this will work :) But this will duplicate sql.
The Auth facade points to Illuminate\Auth\Guard so that should work. And Auth::user() will not have duplicate SQL because if the user isn't in the session it will fetch it, otherwise it will just receive it from the session store.
public function __construct(Guard $auth){$this->auth = $auth->user();} right?
No, just $this->auth = $auth and then use it like this: $this->auth->user();
The problem is not coming from construct. in my User model I can't instantiate interface Guard. However, static::addGlobalScope(new DeveloperScope) is missing $auth. Can't figure out how to call $auth in my scope. static::addGlobalScope(new DeveloperScope (new Guard) ) is not working too.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.