Sorting not working on some fields using Yii - php

I have the following code
DataProvider:
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id, true);
$criteria->compare('firstname', $this->firstname, true);
$criteria->compare('lastname', $this->lastname, true);
$criteria->compare('email', $this->email, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'pagination' => array(
'pageSize' => 20
),
'sort' => array(
'defaultOrder' => 'id DESC'
)
));
}
GridView:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'columns'=>array(
array('name'=>'id','htmlOptions'=>array( 'width'=>'10%' )),
array('name'=>'email','htmlOptions'=>array( 'width'=>'15%' )),
array('name' => 'firstName', 'htmlOptions'=>array( 'width'=>'10%' ), 'value'=>'$data->firstname'),
array('name' => 'lastName', 'htmlOptions'=>array( 'width'=>'10%' ), 'value' => '$data->lastname'),
),
));
Now when I view this grid the sorting works on Id, email fields but not working on firstName, lastName
Can anybody tell me whats the problem with sorting on firsttName and lastName while it works fine on id and email fields?

Related

Yii Cgridview with duplicated column name from relational models

I am using Cgridview to display results for "User" model with relation from "UserFlag" model.
"User" model -> tbl_user (id, name, password, flag)
"Flag" model -> tbl_userFlag (id, flag)
The id means the same from both models. However, the flags means differently (I can't modify the database so have to stick with it) and I need to display them on the same gridview.
The problem I encounter is that
the gridview can show both flags correctly but it fails and shows error when I try to sort and filter the flag from "User" model. (However sorting and filtering work fine for the flag from "UserFlag" model.)
How can I solve it?
The error log:
CDbCommand failed to prepare the SQL statement: SQLSTATE[HY000]: General error: 1 ambiguous column name: flag.
"User" model:
class User extends CActiveRecord
{
public function relations()
{
return array(
'FLAG' => array(self::HAS_ONE, 'UserFlag','id'),
);
}
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('name',$this->username,true);
$criteria->compare('password',$this->password,true);
$criteria->compare('flag',$this->flag,true);
$criteria->with = array(
'FLAG' => array(
'select' => 'FLAG.flag',
'together' => true,
)
);
$criteria->compare('FLAG.flag',$this->flagFromB,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=> array(
'attributes'=>array(
'flagFromB' => array(
'asc' => 'FLAG.flag',
'desc' => 'FLAG.flag DESC',
),
'*',
),
),
));
}
"UserFlag" model:
Link to table tbl_userFlag (id, flag)
"User" view:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'username',
'password',
'email',
'flag',
array(
'name' => 'flagFromB',
'type' => 'raw',
'value' => '$data->FLAG->flag',
),
array(
'class'=>'CButtonColumn',
),
),
));
You can change your modal relationship.
User.php modal file.
<?php
class User extends CActiveRecord {
public function relations() {
return array(
'FLAG' => array(self::BELONGS_TO, 'UserFlag', 'id'),
);
}
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('name', $this->username, true);
$criteria->compare('password', $this->password, true);
$criteria->compare('flag', $this->flag, true);
$criteria->with = array(
'FLAG' => array(
'select' => 'FLAG.flag',
'together' => true,
)
);
$criteria->compare('FLAG.flag', $this->flagFromB, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort' => array(
'attributes' => array(
'flagFromB' => array(
'asc' => 'FLAG.flag',
'desc' => 'FLAG.flag DESC',
),
'*',
),
),
));
}
}
?>
I hope it will help.

CActiveDataProvider with custom value

In my Yii project I need to search and sort data by some custom value. I have 'users' table and I need every User instance to have month_profit property which should combine SQL data + lots of my own calculations. At the moment I have in my User model:
public $month_profit;
public function search($pageSize = 10, $defaultOrder = '`t`.`reg_date` DESC')
{
$criteria = new CDbCriteria;
$criteria->with = array('money');
$requests_table = Requests::model()->tableName();
$requests_count_sql = "(SELECT COUNT(*) FROM $requests_table rt WHERE rt.partner_id = t.id) ";
$referrals_table = Referrals::model()->tableName();
$referrals_count_sql = "(SELECT COUNT(*) FROM $referrals_table reft WHERE reft.user_id = t.id) ";
$referrals_payed_sql = "(SELECT COUNT(*) FROM $referrals_table reft WHERE reft.user_id = t.id AND reft.status = 'Оплачено') ";
//$month profit_sql = ???;
$criteria->select = array(
'*',
$requests_count_sql . "as requests_count",
$referrals_count_sql . "as referrals_count",
$referrals_payed_sql . "as referrals_payed_count",
$month_profit_sql . "as month_profit",
);
$criteria->compare($requests_count_sql, $this->requests_count);
$criteria->compare($referrals_count_sql, $this->referrals_count);
$criteria->compare($referrals_payed_sql, $this->referrals_payed_count);
$criteria->compare($month_profit_sql, $this->month_profit);
$criteria->compare('t.id', $this->id);
$criteria->compare('t.reg_date', $this->reg_date, true);
$criteria->compare('username', $this->username, true);
$criteria->compare('password', $this->password, true);
$criteria->compare('site', $this->site, true);
$criteria->compare('status', $this->status, true);
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
'pagination' => array( 'pageSize' => $pageSize ),
'sort' => array(
'defaultOrder' => $defaultOrder,
'attributes' => array(
'id' => array(
'asc' => '`t`.`id` ASC',
'desc' => '`t`.`id` DESC',
),
'email' => array(
'asc' => '`t`.`email` ASC',
'desc' => '`t`.`email` DESC',
),
'requests_count' => array(
'asc' => 'requests_count ASC',
'desc' => 'requests_count DESC',
),
'referrals_count' => array(
'asc' => 'referrals_count ASC',
'desc' => 'referrals_count DESC',
),
'referrals_payed_count' => array(
'asc' => 'referrals_payed_count ASC',
'desc' => 'referrals_payed_count DESC',
),
'money' => array(
'asc' => 'money.profit',
'desc' => 'money.profit DESC',
),
'fullProfit' => array(
'asc' => 'money.full_profit',
'desc' => 'money.full_profit DESC',
),
'*',
),
)
));
}
E.g. I have a relation in my User model:
public function relations()
{
return array(
'clients' => array( self::HAS_MANY, 'Referrals', 'user_id'),
Let's say my month_profit will be equal: count of User's clients registered in last 30 days * 150. I need to somehow pass this data to search() and create CDbCriteria to sort users by month_profit. Is this even real? :) Should I create another function to calculate everything and then pass to search()? All my tries followed to failure so far.
I suppose you need something like the following, based on this guide http://www.yiiframework.com/wiki/319/searching-and-sorting-by-count-of-related-items-in-cgridview
First make a statistical query in relations at your User model:
'month_profit' => array(self::STAT, 'User', 'id', 'select'=>'COUNT(*) * 150', 'condition'=>'DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= reg_date'),
Then mark "month_profit" attribute as safe in search scenario in rules.
public function rules() {
return array(
...
array('username, ... , month_profit', 'safe', 'on' => 'search' ),
);
}
Add all these where each one is needed in User search() method:
$user_table = User::model()->tableName();
$month_profit_sql = "(SELECT COUNT(*) FROM user_table WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= reg_date)";
$criteria->select = array(
'*',
$requests_count_sql . "as requests_count",
$referrals_count_sql . "as referrals_count",
$referrals_payed_sql . "as referrals_payed_count",
$month_profit_sql . "as month_profit",
);
...
$criteria->compare($month_profit_sql, $this->month_profit);
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
'pagination' => array( 'pageSize' => $pageSize ),
'sort' => array(
'defaultOrder' => $defaultOrder,
'attributes' => array(
'id' => array(
'asc' => '`t`.`id` ASC',
'desc' => '`t`.`id` DESC',
),
...
'month_profit' => array(
'asc' => 'month_profit ASC',
'desc' => 'month_profit DESC',
),
'*',
),
)
));
Finally, modify your grid:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'username',
... ,
'month_profit',
array(
'class'=>'CButtonColumn',
),
),
));
Please, let me know if that worked.
EDIT
If that doesnt' work try it without the statistical query.

how to make search gridview with custom query in yii

I created a simple gridview using a custom query. This is working fine for me but search box doesn't work. How do I make the search box work?
Here is my code:
UserController.php
public function actionAdmin()
{
$sql = 'SELECT * FROM user';
$rawData = Yii::app()->db->createCommand($sql);
$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM (' . $sql . ') as count_alias')->queryScalar();
$model = new CSqlDataProvider($rawData, array(
'keyField' => 'id',
'totalItemCount' => $count,
'sort' => array(
'attributes' => array(
'id','title', 'type'
),
'defaultOrder' => array(
'id' => CSort::SORT_ASC, //default sort value
),
),
'pagination' => array(
'pageSize' => 10,
),
));
$this->render('admin', array(
'model' => $model,
));
}
Admin.php (View file)
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model,
'filter'=>$model,
'columns'=>array(
array('header'=>'firstname','value'=>'$data["firstname"]'),
array('header'=>'lastname','value'=>'$data["lastname"]'),
array('header'=>'username','value'=>'$data["username"]'),
),
)); ?>

How to make CGridView column sortable using CSqldataprovider?

How to make CGridView columns sortable (On clicking column title) using CSqldataprovider.
In controller
$sql = "select id ,name, address
from User
where city = 'ABC' ";
$rawData = Yii::app()->db->createCommand($sql);
return $allMovies = new CSqlDataProvider($rawData, array(
'keyField' => 'id',
'sort'=>array(
'attributes'=>array(
'id', 'name', 'address',
),
),
'pagination' => array(
'pageSize' => 10,
),
));
In view
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'all_movies',
'dataProvider' => $allMoviesStats,
'columns' => array(
'id',
'name',
'address',
'city'
)
)
);?>
It is giving error
"error":{"code":99,"text":"Property \"CGridView.sort\" is not defined.
You need to create object for CDbCriteria and Sort class and try to use as below and change the code for your requirement.
public function search()
{
$criteria=new CDbCriteria;
$criteria->condition="active=1";
if($this->name=="Enter Country Name" || $this->name=='') {
$this->name='';
} else {
$this->name=$this->name;
}
$criteria->compare('name',$this->name,true);
$sort = new CSort;
$sort->defaultOrder = 'id DESC';
$sort->attributes = array(
'name' => array(
'asc' =>'name',
'desc' =>'name DESC',
),
...
... // attributes to sort
);
return new CActiveDataProvider('Country', array( //Country is nothing but you model class name
'criteria' =>$criteria,
'sort' => $sort,
'pagination'=>array('pageSize'=> 10),
));
}

Filtering data in CGridView based on relations

Hi everyone,
I am new to yii and I am performing crud operation using gii for model called city and I have relation with state model a city->state_id = state.state_id. Crud everything is working fine, but in that view part I want to filter based on state_name
In relations method,I have code this code
'state' => array(self::BELONGS_TO, 'MasState', 'State_Id'),
here is the code for search
public function search() {
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria = new CDbCriteria;
$MasState = new MasState;
$criteria->together = true;
$criteria->compare('state.State_Name',$MasState->State_Name,true);
$criteria->with= array('state');
$criteria->compare('City_Id', $this->City_Id);
$criteria->compare('State_Id', $this->State_Id);
$criteria->compare('City_Name', $this->City_Name, true);
$criteria->compare('Del_Flag', $this->Del_Flag);
$criteria->compare('Ts_Modified', $this->Ts_Modified, true);
$criteria->compare('Ts_Created', $this->Ts_Created, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
and admin.php page code
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'mas-city-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'header' => 'SL NO#',
'class' => 'CounterColumn'
),
array(
'name' => 'state.State_Name',
'header' => 'State Name',
'filter' => CHtml::activeTextField($model,'State_Name'),
'value' => '$data->state->State_Name',
),
'City_Name',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
I am getting error "Property "MasCity.State_Name" is not defined" I know city model does not have state_name but how to make it work. Plese help me
Thanks in advance
First in your search method you should do:
public function search() {
$criteria = new CDbCriteria;
$criteria->with= array('state');
$criteria->together = true;
//Get the relation value from the request
$criteria->compare('state.State_Name',Yii::app()->request->getParam('state_state_name'),true);
$criteria->compare('City_Id', $this->City_Id);
$criteria->compare('State_Id', $this->State_Id);
$criteria->compare('City_Name', $this->City_Name, true);
$criteria->compare('Del_Flag', $this->Del_Flag);
$criteria->compare('Ts_Modified', $this->Ts_Modified, true);
$criteria->compare('Ts_Created', $this->Ts_Created, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
And in your view:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'mas-city-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'header' => 'SL NO#',
'class' => 'CounterColumn'
),
array(
'name' => 'state.State_Name',
'header' => 'State Name',
'filter' => CHtml::textField('state_state_name', Yii::app()->request->getParam('state_state_name')),
'value' => '$data->state->State_Name',
),
'City_Name',
array(
'class'=>'CButtonColumn',
),
),
)); ?>

Categories