Hello,
I’m learning Yii2 and I’m trying to build various scenarios.
I do not understand, for GridView, if we can really create grids with any kind of SQL query, while keeping the Filtering(search)/Sort etc.
For example, the classic User + Roles tables. In this case, Yii2, User and auth_ tables.
With the following code, I managed to display a GridView without column search (filtering):
<?php
$query = (new Query())
->select("user.id,user.username,user.created_at,GROUP_CONCAT(auth_assignment.item_name ORDER BY auth_assignment.item_name SEPARATOR ',') as roles")
->from('user')
->join('LEFT OUTER JOIN','auth_assignment','auth_assignment.user_id = user.id')
->join('INNER JOIN','auth_item',' auth_item.name = auth_assignment.item_name AND auth_item.TYPE = 1')
->groupBy('user.id,user.username,user.created_at');
$provider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 5,
],
'sort' => [
'defaultOrder' => [
'created_at' => SORT_DESC,
],
'attributes' => ['username','roles','created_at']
],
// what column is used as KEY for action buttons
'key' => 'id'
]);
?>
<?= GridView::widget([
'dataProvider' => $users_provider,
'columns' => [
'id',
'username',
'roles',
['attribute' => 'created_at', 'format' => ['date', 'php:d/m/Y H:i:s']],
['class'=>'yii\grid\ActionColumn'],
],
'layout' => '{summary}{items}{pager}',
'filterPosition' => FILTER_POS_FOOTER,
'rowOptions' => function ($model, $key, $index, $grid) {
},
'emptyText' => '-',
'showFooter' => true,
]);
?>
As you can see, I do not use ActiveRecords for this, I haven’t actually well understood how to do it for joined tables. And personally I prefer to write my SQL queries.
How can I add the filtering functionality? If I check a generated Gii example, I see the _search, ClassSearch model etc. How should I adapt this to my approach? In my approach, I could still add the UserSearch.php model this way:
<?php
public function search($params)
{
$query = (new Query())
->select("user.id,user.username,user.created_at,GROUP_CONCAT(auth_assignment.item_name ORDER BY auth_assignment.item_name SEPARATOR '<br>') as roles")
->from('user')
->join('LEFT OUTER JOIN','auth_assignment','auth_assignment.user_id = user.id')
->join('INNER JOIN','auth_item',' auth_item.name = auth_assignment.item_name AND auth_item.TYPE = 1')
->groupBy('user.id,user.username,user.created_at');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
//$this->load($params);
$this->id = $_GET['id'];
$this->username = $_GET['username'];
$this->roles = $_GET['roles'];
/*
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
*/
$query->andFilterWhere([
'id' => $this->id,
]);
$query->andFilterWhere(['like', 'username', $this->username])
->andFilterWhere(['like', 'roles', $this->roles]);
return $dataProvider;
}
?>
and it kind of works if I play with the url GET vars, but of course this is dummy. There is no $this->load($params) and no $this->validate(), not to mention no filter form boxes on the columns.
Thanks a lot for your help!