Php Laravel基于角色限制值

Php Laravel基于角色限制值,php,laravel,Php,Laravel,我的用户可以具有以下角色之一:管理员、发布者和创建者。当他们是发布者或创建者时,他们只能访问X customer分配给他们的帖子 通常,我会做以下操作来获得所有帖子: $posts = \App\Models\Posts::with('Customer')->all(); 但现在我需要根据角色进行筛选。我试图避免出现几种情况(如下面的示例),因为将来我可能会添加更多的代码逻辑: if (Admin) // Get all else // Get all where customer

我的用户可以具有以下角色之一:管理员、发布者和创建者。当他们是发布者或创建者时,他们只能访问X customer分配给他们的帖子

通常,我会做以下操作来获得所有帖子:

$posts = \App\Models\Posts::with('Customer')->all();
但现在我需要根据角色进行筛选。我试图避免出现几种情况(如下面的示例),因为将来我可能会添加更多的代码逻辑:

if (Admin)
 // Get all
else
 // Get all where customer is assigned to user
注意:管理员用户不需要分配给任何客户,他们可以访问所有内容

我希望Laravel能够理解一个用于Elount的自定义函数,比如:

$posts = \App\Models\Posts::with('Customer')->filtered()->all();
过滤函数必须查看角色和客户Id,例如:

public function filtered($userId, $customerId)
{
    // Has always access to everything
    if (\App\User::isAdmin())
        return true;

    return \App\Models\UsersCustomers::where('user_id', $userId)
        ->where('customer_id', $customerId)
        ->exists();
}

我知道作用域,但我很难找到如何正确地实现它。

已解决

如文件所述

全局作用域允许您为给定对象的所有查询添加约束 模型

全局作用域的问题是,至少在我的例子中,如果有帖子分配给某个客户,X用户有权访问该客户,但随后该访问被删除,它将返回404页

因此,我不再使用全局作用域,而是使用局部作用域

局部作用域允许您定义所需的公共约束集 可在整个应用程序中轻松重复使用。例如,您可以 需要经常检索所有被认为“受欢迎”的用户

在Customers模型类中,我创建了以下函数:

public function scopeHasAccess($query)
{
    // Access to everything
    if (\App\User::isAdmin())
        return $query;

    $userId = \Auth::id();    
    
    return $query->whereRaw("(SELECT COUNT(id) FROM users_customers WHERE user_id = '{$userId}' AND customer_id = customers.id) > 0");
}
这允许我使用如下函数
\App\Models\Customers::where('type',$type)->hasAccess()->get()但在更复杂的查询中:

\App\Models\Posts::with('Related')
    ->with('Customer')
    ->where('types', $types)
    ->whereHas('Customer', function($query)
    {
        $query->hasAccess();
    });
    ->get();

已解决

如文件所述

全局作用域允许您为给定对象的所有查询添加约束 模型

全局作用域的问题是,至少在我的例子中,如果有帖子分配给某个客户,X用户有权访问该客户,但随后该访问被删除,它将返回404页

因此,我不再使用全局作用域,而是使用局部作用域

局部作用域允许您定义所需的公共约束集 可在整个应用程序中轻松重复使用。例如,您可以 需要经常检索所有被认为“受欢迎”的用户

在Customers模型类中,我创建了以下函数:

public function scopeHasAccess($query)
{
    // Access to everything
    if (\App\User::isAdmin())
        return $query;

    $userId = \Auth::id();    
    
    return $query->whereRaw("(SELECT COUNT(id) FROM users_customers WHERE user_id = '{$userId}' AND customer_id = customers.id) > 0");
}
这允许我使用如下函数
\App\Models\Customers::where('type',$type)->hasAccess()->get()但在更复杂的查询中:

\App\Models\Posts::with('Related')
    ->with('Customer')
    ->where('types', $types)
    ->whereHas('Customer', function($query)
    {
        $query->hasAccess();
    });
    ->get();

你看过模型政策了吗?感觉像是在重塑模型策略,但我可能错了。@user3532758我不知道策略,但在快速阅读后,这似乎也是一个好方法。你看过模型策略吗?感觉像是在重塑模型策略,但我可能错了。@user3532758我不知道策略,但快速阅读后,这似乎也是一个好方法。