Yii2 Filters with Sqldataprovider - mysql

I have following code in my search() function of search model. Data is displaying correctly in gridview but i'm not able to use searching functions of gridview.
public function search($params)
{
$totalCount = Yii::$app->db->createCommand('SELECT COUNT(*) FROM patient_test')->queryScalar();
$query = new Query();
$query->select('patient.id as id,patient_test.receipt_number,patient.name as patient_id, GROUP_CONCAT(test_group.name) as test_group_id, patient.age as patient_test_age')
->from('patient_test');
$query->join = [
['LEFT JOIN', 'patient', 'patient_test.patient_id = patient.id'],
['LEFT JOIN', 'test_group', 'patient_test.test_group_id = test_group.id']];
$query->groupBy(['patient_test.patient_id', 'patient_test.receipt_number', 'patient_test.is_sample_received', 'patient_test.is_ready']);
$dataProvider = new SqlDataProvider([
// 'db' => Yii::$app->db,
'sql' => $query->createCommand()->sql,
'totalCount' => $totalCount,
'sort' => [
'attributes' => [
'patient_id' => [
'desc' => ['patient_id' => SORT_DESC ],
'default' => SORT_DESC,
],
],
], 'pagination' => [
'pageSize' => $pagination,
]
]);
$this->load($params);
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;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'is_sample_received' => $this->is_sample_received,
]);
$query->andFilterWhere(['like', 'patient_test.receipt_number', $this->receipt_number])
->andFilterWhere(['like', 'patient.name', $this->patient_id])
->andFilterWhere(['like', 'test_group.name', $this->test_group_id])
->andFilterWhere(['like', 'patient.age', $this->patient_test_age])
->andFilterWhere(['like', 'patient.mobile_no', $this->patient_test_mobile]);
return $dataProvider;
}
from this, my code is working fine but filtration/searching not working

Related

Yii2 Sorting and filtering from a linked table through a table

Good day everyone. I'm trying to add a filter for the associated phone_digital field but I get the following error
Structure -
1 table - ClientClient - first_name, patronymic, last_name, age.
2 table - ClientPhone - client_id, phone_digital.
ClientClient (model)
class ClientClient extends \yii\db\ActiveRecord
{
public static function tableName(){
return 'client_client';
}
public function rules(){
return [
[['age'], 'integer'],
[['first_name', 'patronymic', 'last_name'], 'string', 'max' => 255],
];
}
public function attributeLabels(){
return [
'id' => 'ID',
'first_name' => 'First Name',
'patronymic' => 'Patronymic',
'last_name' => 'Last Name',
'age' => 'Age',
'phone_digital' => 'Phone Digital',
];
}
public function getclientPhone(){
return $this->hasOne(clientPhone::class, ['client_id' => 'id']);
}
public function getPhone(){
return $this->hasOne(clientPhone::class, ['phone_digital' => 'id']);
}
public function getDigital(){
return $this->hasOne(ClientPhone::className(), ['id' => 'phone_digital']);
}
public function getPhoneDigital(){
return $this->phone->phone_digital;
}
}
ClientSearch (model)
class ClientSearch extends Clientclient
{
public $phonedigital;
public function rules(){
return [
[['id', 'age'], 'integer'],
[['first_name', 'phonedigital', 'patronymic', 'last_name'], 'safe'],
];
}
public function scenarios(){
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
public function search($params){
$query = Clientclient::find()->orderBy('phone_digital');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->joinWith(['phonedigital' => function($query) { $query->from(['phonedigital' => 'ClientPhone']); }]);
$dataProvider->sort->attributes['phone'] = [
'asc' => ['phonedigital.phone_digital' => SORT_ASC],
'desc' => ['phonedigital.phone_digital' => SORT_DESC],
];
$query->andFilterWhere([
'id' => $this->id,
'age' => $this->age,
]);
$query->andFilterWhere(['like', 'first_name', $this->first_name])
->andFilterWhere(['like', 'patronymic', $this->patronymic])
->andFilterWhere(['like', 'last_name', $this->last_name])
->andFilterWhere(['like', 'phonedigital.phone_digital', $this->getAttribute('phonedigital')]);
return $dataProvider;
}
}
What do I need to do to make this work?
I guess you should put your orderBy after your join
check the commented lines:
public function search($params){
// do not put the join of a related table at the beginning because it's not related yet
$query = Clientclient::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->joinWith(['phonedigital' => function($query) { $query->from(['phonedigital' => 'ClientPhone']); }]);
// orderBy only after call the relacion
$query->orderBy('phonedigital.phone_digital');
$dataProvider->sort->attributes['phone'] = [
'asc' => ['phonedigital.phone_digital' => SORT_ASC],
'desc' => ['phonedigital.phone_digital' => SORT_DESC],
];
$query->andFilterWhere([
'id' => $this->id,
'age' => $this->age,
]);
$query->andFilterWhere(['like', 'first_name', $this->first_name])
->andFilterWhere(['like', 'patronymic', $this->patronymic])
->andFilterWhere(['like', 'last_name', $this->last_name])
->andFilterWhere(['like', 'phonedigital.phone_digital', $this->getAttribute('phonedigital')]);
return $dataProvider;
}
I hope it helps you, and sorry about my ingles

Yii2- How to restrict a user from viewing others data in index page

I am working on yii2 in my project, I have users and their roles. Each role is given access to a Module and a Sub Menu. There is a sub-menu named SIM List in which all the SIM records can be viewed. There is a field named issued_to which tells us that which SIM has been issued to which user.
Unless a SIM is issued to any user, the issued_to field will remain empty. Once issued the name of the user will appear on the SIM List.
Now I want to manage it in such a way that only a specific user can see the list. For example 5 Sims have been issued to a user named U. Now the user U should only see that SIM records which are issued to him, otherwise the list should be empty.
In my Index controller I am getting issued_to field name which is empty by default.
public function actionIndex()
{
$searchModel = new SimsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
By doing like below I can get issued_to user id
$model = $dataProvider->getModels()[0];
$user_id = $model['issued_to'];
var_dump($user_id);
exit();
Now in this controller, I want to add a check of user_id which gives me only the records which are of that specific user.
Index View
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
'imsi',
'sim_number',
'operator_name',
'data_details',
'sms_details',
'monthly_bill',
//'created_by',
[
'label' => 'Created By',
'value' => function ($data) {
if (is_object($data))
return $data->created->name;
return ' - ';
},
//'filter' => Html::activeDropDownList($searchModel, 'created_by', \app\models\User::toArrayList(), ['prompt' => "Created By", 'class' => 'form-control']),
],
'created_at',
// 'updated_at',
'status',
// 'updated_by',
//'sim_stauts',
[
'label'=>'SIM Status',
'value'=>function($a){
return $a->getStatusvalue();
}
],
//'issued_to',
[
'label' => 'Issued To',
'value' => function ($d) {
if(is_object($d->user))
//return $d->user->name;
return $d->issued_to == '' ? '' : $d->user->username;
return ' - ';
// return $d->user->name;
},
'filter' => Html::activeDropDownList($searchModel, 'issued_to', \app\models\User::toArrayList(), ['prompt' => "Users", 'class' => 'form-control']),
],
//'returned_by',
[
'label' => 'Returned By',
'value' => function ($d) {
if(is_object($d->user2))
//return $d->user->name;
return $d->returned_by == '' ? '' : $d->user->username;
return ' - ';
// return $d->user->name;
},
'filter' => Html::activeDropDownList($searchModel, 'returned_by', \app\models\User::toArrayList(), ['prompt' => "Users", 'class' => 'form-control']),
],
'historic',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
Update 1
My search model is below
public function search($params)
{
$query = Sims::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
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;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'created_by' => $this->created_by,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'updated_by' => $this->updated_by,
'sim_stauts' => $this->sim_stauts,
'issued_to' => $this->issued_to,
'returned_by' => $this->returned_by,
'historic' => $this->historic,
]);
$query->andFilterWhere(['like', 'imsi', $this->imsi])
->andFilterWhere(['like', 'sim_number', $this->sim_number])
->andFilterWhere(['like', 'operator_name', $this->operator_name])
->andFilterWhere(['like', 'data_details', $this->data_details])
->andFilterWhere(['like', 'sms_details', $this->sms_details])
->andFilterWhere(['like', 'monthly_bill', $this->monthly_bill])
->andFilterWhere(['like', 'status', $this->status]);
return $dataProvider;
}
How can I achieve it? Any help would be highly appreciated.
As per your description, you have the user_id saved inside the issued_to field and you need to only fetch the results that have the current logged in user_id saved in the field issued_to.
I assume that your search in the grid view is visible to only logged-in users.
You should set the issued_to param manually by first getting the queryParams array from the request object Yii::$app->request->queryParams; which has the array in the same format as the POST has i.e ['ModelName']['field_name'] so you need to infact set the issued_to as
$arrayParams['SimSearch']['issued_to']=Yii:$app->user->id;
Your actionIndex should look like below
public function actionIndex()
{
$searchModel = new SimsSearch();
$queryParams=Yii::$app->request->queryParams;
//check if user or one of the managers
$isAdmin=in_array(Yii::$app->user->identity->user_role,[1,6]);
//set params if normal user
if(!$isAdmin){
$queryParams['SimsSearch']['issued_to']=Yii::$app->user->id;
}
$dataProvider = $searchModel->search($queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Hope this helps you out.

Yii2 Undefined index

My controller:
$params = Yii::$app->request->queryParams;
$query4 = (new \yii\db\Query())
->select(['monthsubmit', 'modeler'])
->from('sku3d')
->groupBy(['monthsubmit', 'modeler'])
->orderBy(['monthsubmit'=>SORT_DESC]);
$query4->andFilterWhere(['like', 'monthsubmit', $params['monthsubmit']])
->andFilterWhere(['like', 'modeler', $params['modeler']]);
$dataProvider4 = new ActiveDataProvider([
'query' => $query4,
]);
MY view:
<?php echo GridView::widget([
'dataProvider' => $dataProvider4,
'filterModel' => true,
'pjax'=>true,
'panel' => [
'type' => GridView::TYPE_PRIMARY,
'heading' => '<h3 class="panel-title"><i class="glyphicon glyphicon-user"></i>Submitted SKU by Month</h3>',
],
'columns' => [
// 'monthsubmit',
[
'attribute'=>'monthsubmit',
'filter' => Html::input('string', 'monthsubmit')
'width'=>'310px',
'group'=>true, // enable grouping
],
[
'attribute'=>'modeler',
'width'=>'180px',
'filter' => Html::input('string', 'modeler')
'group'=>true, // enable grouping
],
]
]);
?>
I have created sqlDataProvider in my controller and its working. My problem is when i try to create a filter option since im not using the search model for my gridview, it return error Undefined index: monthsubmit.
Please tell me where I'm wrong.
Thank you.
In your controller, you should do as this
$modeler = Yii::$app->request->get('modeler');
$monthsubmit = Yii::$app->request->get('monthsubmit');
$query4 = (new \yii\db\Query())
->select(['monthsubmit', 'modeler'])
->from('sku3d')
->groupBy(['monthsubmit', 'modeler'])
->orderBy(['monthsubmit'=>SORT_DESC]);
$query4->andFilterWhere(['like', 'monthsubmit', $monthsubmit])
->andFilterWhere(['like', 'modeler', $modeler]);
$dataProvider4 = new ActiveDataProvider([
'query' => $query4,
]);

Yii2 gridview filter with comparison operators

How to filter gridview results with a column greater than specified value?
My gridview have a column amount. When user searches as 1000, i want to filter results as amount greater than 1000. How do i do this?
Now my search model is like this.
public function search($params) {
$query = Service::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['defaultOrder' => ['id' => SORT_DESC,
]]
]);
$this->load($params);
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;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'patient_id' => $this->patient_id,
'service' => $this->service,
'duty_type' => $this->duty_type,
'staff_manager' => $this->staff_manager,
'from_date' => $this->from_date,
'to_date' => $this->to_date,
'branch_id' => $this->branch_id,
'status' => $this->status,
'CB' => $this->CB,
'UB' => $this->UB,
'DOC' => $this->DOC,
'DOU' => $this->DOU,
]);
$query->andFilterWhere(['like', 'estimated_price', $this->estimated_price])
->andFilterWhere(['like', 'amount', $this->amount])
->andFilterWhere(['like', 'days', $this->days])
->andFilterWhere(['like', 'service_id', $this->service_id]);
return $dataProvider;
}
query->andFilterWhere(['like', 'estimated_price', $this->estimated_price])
->andFilterWhere(['>', 'amount', $this->amount])
->andFilterWhere(['like', 'days', $this->days])
->andFilterWhere(['like', 'service_id', $this->service_id]);
If you want to include entered amount in search result, use >=.

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous Yii2

Helo, could someone explain me why I'm getting this error? What I was doing is that I'm trying to filter my GridView according to the id's, but it displays this error message. I've tried to search related information, but couldn't find what would be useful.
Here is my Search function:
public function search($params)
{
$query = Sale::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$query->joinWith('item');
$dataProvider->setSort([
'attributes' => [
'id',
'customer_name',
'customer_surname',
'customer_phone',
'customer_email',
'code',
'comment',
'sign',
'price' => [
'asc' =>['item.price' => SORT_ASC],
'desc' =>['item.price' => SORT_DESC],
],
'item_id' => [
'asc' =>['item.name' => SORT_ASC],
'desc' =>['item.name' => SORT_DESC],
]
]
]);
$this->load($params);
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;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
]);
$query->andFilterWhere(['like', 'customer_name', $this->customer_name])
->andFilterWhere(['like', 'item.name', $this->item_id])
->andFilterWhere(['like','sign', $this->sign])
->andFilterWhere(['like', 'customer_surname', $this->customer_surname])
->andFilterWhere(['like', 'customer_phone', $this->customer_phone])
->andFilterWhere(['like', 'customer_email', $this->customer_email])
->andFilterWhere(['like', 'code', $this->code])
->andFilterWhere(['like', 'comment', $this->comment]);
return $dataProvider;
}
It should work, because id has been added to setSort() and filter statements... Thank you for any help
It should'nt work, cause u join item table, which propably have another id column. Change this:
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
]);
to:
// grid filtering conditions
$query->andFilterWhere([
'sale.id' => $this->id,
]);
Another way is to use aliases for tables.