I'm using Excel write in Yii.
Every time I generate the Excel it gives me just the header but no output, although my database contains rows.
controller:
$sql = "SELECT trucker as Trucker, (SELECT COUNT(*) FROM courses where association_trucker_id = assoc_truckerid) as Units, CONCAT(buss_add_add,', ',buss_add_prov,', ',buss_add_city,', ',buss_add_zip) as Address, CONCAT(rep_lname,', ',rep_fname,' ',rep_mname) as 'Contact Person', rep_telno as 'Office No', rep_email as Email FROM `students`"; // your sql
$rawData = Yii::app()->db->createCommand($sql)->queryAll(); // you get them in an array
$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM (' . $sql . ') as count_alias')->queryScalar();
$model = new CArrayDataProvider($posts,
array(
'totalItemCount' => $count,
'sort' => array(
'attributes' => array(
'trucker'
),
),
'pagination' => array(
'pageSize' => 5000000, // large number so you export all to excel
),
)
);
$this->renderPartial('truckerexcel', array(
'model' => $model, 'truckerid' => $truckerlist,
));
View:
<?php
$this->widget('EExcelWriter', array(
'dataProvider' => $model,
'title' => 'EExcelWriter',
'stream' => TRUE,
'fileName' => 'TRUCKERS_'.date('Y-m-d', time()).'.xls',
'columns' => array(
'trucker'
),
));
?>
Instead of
$model = new CArrayDataProvider($posts,
you should be using the variable $rawData:
$model = new CArrayDataProvider($rawData,
Related
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.
I am trying to use CGridView with custom query, and trying to build a very simple with no sorting and stuff.
My View contains simple CGridView
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
));
And my controller passes the $dataProvider to the view
$count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM ( ' . $query . ' ) as count')->queryScalar();
$dataProvider=new CSqlDataProvider($query, array(
'keyField' => false,
'totalItemCount'=>$count,
'pagination'=>array(
'pageSize'=>10,
),
));
I don't have a keyField therefore I have set it to false. Moreover, I have tried printing out data using var_dump, data is present in the variable, but still I get this undefined offset error.
You need to set the mapping for sorting.
/*
Query results
array(
array(
'id' => 1,
'username' => 'username',
'email' => 'email'
),
...
)
*/
return new CSqlDataProvider($query, array(
'keyField' => 'id', //required, any field from query results
'totalItemCount'=> $count,
'pagination' => array(
'pageSize' => 10
),
'sort' => array(
'defaultOrder' => array(
'username' => CSort::SORT_DESC,
),
'attributes' => array(
'username',
'email',
),
),
));
//grid.columns
array(
array(
'name' => 'id' //WO sort
),
array(
'name' => 'username', //with sort (isset in dp.sort.attributes)
),
)
you have to provide keyfield other than false, change keyfield primary key of your query Table
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"]'),
),
)); ?>
I have User model which contain a function that calculates the average revenue per user. Now i want apply sorting in CGridView on the column which is associated with getAvgRevenue() function. While license is relation in the User model.
Here is my code,
public class User{
$user_id;
$email;
public function getAvgRevenue(){
$count = 0;
$revenue = 0;
foreach ($this->license as $license){
$revenue += $license->price;
$count++;
}
if($count!= 0){
$averageRevenue = $revenue/$count;
return $averageRevenue;
}
else{
return null;
}
}
}
In Controller
$modelUser = new CActiveDataProvider('User', array(
'sort' => array(
'attributes' => array(
'user_id',
'email',
'averagerevenue'
),
'defaultOrder' => array(
'user_id' => CSort::SORT_ASC,
),
),
));
In view
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'user-grid',
'dataProvider' => $modelUser,
'columns' => array(
array(
'header' => 'User ID',
'name' => 'user_id',
),
array(
'header' => 'Email',
'name' => 'email',
),
array(
'header'=>'Average Revenue',
'value'=>'$data->averagerevenue',
),
)
));
?>
Sorting is applicable on user_id and email but Average Revenue column is not sortable. how to specify model method in sort() of CActiveDataprovider
Please help me to solve the problem.
Try this:
$modelUser = new CActiveDataProvider('User', array(
'sort' => array(
'attributes' => array(
'user_id',
'email',
'avgRevenue' //here's the change for you
),
'defaultOrder' => array(
'user_id' => CSort::SORT_ASC,
),
),
));
And your gridview column should be:
array(
'header'=>'Average Revenue',
'value'=>'avgRevenue',
),
and you can read more info on it over here:
http://www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/
I followed the tutorial. But I can find no way to populate a form select from a database like this:
// Blog/src/Blog/Form/BlogItemForm.php
$blogCategoryTable = new Model\BlogCategoryTable;
$this->add(new Element\Select('category_id',
array('label' => 'Category', 'value_options' => $blogCategoryTable->getFormChoices())
));
Does anyone have any ideas?
I use a function to retrieve the data and set it to the form:
From my factory:
$option_for_select = $this->model->getWhatEver();
$this->add($factory->createElement(array(
'name' => 'what_ever',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'options' => $option_for_select,
),
'options' => array(
'label' => 'What ever:',
),
)));
From the model:
public function getWhatEver()
{
$sql = "SELECT something";
$statement = $this->adapter->query($sql);
$res = $statement->execute();
// set the first option
$rows[0] = array (
'value' => '0',
'label' => 'Top',
'selected' => TRUE,
'disabled' => FALSE
);
foreach ($res as $row) {
$rows[$row['triplet_id']] = array (
'value' => $row['col1'],
'label' => $row['col2'],
);
}
return $rows;
}