Search code examples
phpgridviewyii2yii2-model

Yii2 Gridview filter by permission


I have a super admin, that can create users and can assign specific locations for each user. This is stored in a simple table, where we get the ID of the user and the ID of the location.

Then, I have a table of clients. Each client also has a location, named loc_id. How can I filter so that in the Gridview a user can only see the clients that live in a location that the user has a permission to view (a user is a kind of admin that can manipulate the data of a client in their jurisdiction)?

I get the user id by

$userId = \Yii::$app->user->identity->id

and then find the locations that he can view with

$userLocation = Userlocations::find()-where(['user_id' => $userId])->all();

But now how can I apply this to a standard Gridview with a Search Model and a DataProvider, so that I can still filter and sort the GridView by the other properties?

$searchModel = new AsociatiiSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);

Solution

  • First inside your AsociatiiSearch class you need to add a public attribute:

    class AsociatiiSearch {
        public $userLocation;
        ...
    

    Then inside your controller action you find the userLocation:

    $userId = \Yii::$app->user->identity->id
    $userLocation = Userlocations::find()-where(['user_id' => $userId])->all();
    $searchModel = new AsociatiiSearch();
    $searchModel->userLocation = $userLocation;
    
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);
    

    Finally, on AsociatiiSearch search method you can just add another filter using the global userLocation:

    $query->andFilterWhere(['userLocation' => $this->userLocation]);