Yii Framework 1.1 CdbCriteria with multiple JOIN in GridView - php

I'm starting in the world Yii framework in version 1.1 and it's impossible for me to visualize the records brought from a pure query. It's been days since I can't solve it, it's probably something simple but with my poor knowledge I haven't been able to solve it yet. I show you my code to see if you can help me.
The relationships of the TblRecibo model, which is where I want to make the query are:
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'tblEstadoreciboHasTblRecibos' => array(self::HAS_MANY, 'TblEstadoreciboHasTblRecibo', 'idRecibo'),
'tblItemrecibowebs' => array(self::HAS_MANY, 'TblItemreciboweb', 'idRecibo'),
'idCalendario0' => array(self::BELONGS_TO, 'TblCalendario', 'idCalendario'),
'idDomicilioApertura0' => array(self::BELONGS_TO, 'TblDomicilio', 'idDomicilioApertura'),
'idDomicilio0' => array(self::BELONGS_TO, 'TblDomicilio', 'idDomicilio'),
'idPaquete0' => array(self::BELONGS_TO, 'TblPaquete', 'idPaquete'),
);
}
My model:
public function search()
{
$criteria = new CDbCriteria;
$criteria->alias = 'r';
$criteria->select = 'r.idRecibo,d.matricula,d.federado,e.nombre,d.calle,r.cantidad,cal.periodo,est.ult_modif,os.nombre ';
$criteria->join ='LEFT JOIN tbl_calendario as cal on r.idcalendario=cal.idcalendario '
.'LEFT JOIN tbl_estadorecibo_has_tbl_recibo as est on r.idrecibo=est.idrecibo '
.'LEFT JOIN tbl_domicilio as d ON r.iddomicilioapertura=d.idDomicilio '
.'LEFT JOIN tbl_entidad as e ON d.idEntidad=e.idEntidad '
.'LEFT JOIN tbl_itemreciboweb as rweb on r.idrecibo=rweb.idrecibo '
.'LEFT JOIN tbl_ooss as os on rweb.idooss=os.idooss';
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'pagination' => array('pageSize' => Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize']),
),
));
}
My controller:
public function actionIndex()
{
$model = new TblRecibo('search');
$model->unsetAttributes(); // clear any default values
if (isset($_GET['TblRecibo']))
$model->attributes = $_GET['TblRecibo'];
$this->render('admin', array(
'model' => $model,
));
}
My view:
<?php
$this->widget('bootstrap.widgets.TbGridView', array(
'type'=>'bordered striped',
'id' => 'tbl-recibo-grid',
'dataProvider' => $model->search(),
'htmlOptions' =>array('style' => 'font-size: 16px;font-weight: normal'),
'columns' => array(
'idrecibo',
'dom.matricula',
'dom.federado',
'ent.nombre',
'dom.calle',
'rec.cantidad',
'cal.periodo',
'est.ult_modif',
'os.nombre',
),
));
?>
When executing I have no error just that the GridView does not show the results of the queries. I know it should not be anything complicated because, debugging the values ​​are the issue is that I do not understand how to pass them to the Vista.

With select like r.idRecibo,d.matricula,d.federado, ... result will be returned with keys like idRecibo, matricula, federado etc. Tho handle such query you need to add all fields from joined tables to your model:
TblRecibo extends CActiveRecord {
public $matricula;
public $federado;
// ...
}
And then in grid view access them by:
'columns' => array(
'idRecibo',
'matricula',
'federado',
// ...
),
But for such custom queries it may be easier to use CSqlDataProvider instead of CActiveDataProvider - you will not need to add properties to model only for this search - result will be returned as array:
public function search() {
$from = 'FROM tbl_recibo as r '
. 'LEFT JOIN tbl_calendario as cal on r.idcalendario=cal.idcalendario '
. 'LEFT JOIN tbl_estadorecibo_has_tbl_recibo as est on r.idrecibo=est.idrecibo '
. 'LEFT JOIN tbl_domicilio as d ON r.iddomicilioapertura=d.idDomicilio '
. 'LEFT JOIN tbl_entidad as e ON d.idEntidad=e.idEntidad '
. 'LEFT JOIN tbl_itemreciboweb as rweb on r.idrecibo=rweb.idrecibo '
. 'LEFT JOIN tbl_ooss as os on rweb.idooss=os.idooss';
$count = Yii::app()->db->createCommand('SELECT COUNT(*) ' . $from)->queryScalar();
$sql = 'SELECT r.idRecibo,d.matricula,d.federado,e.nombre,d.calle,r.cantidad,cal.periodo,est.ult_modif,os.nombre ' . $from;
return new CSqlDataProvider($sql, array(
'totalItemCount' => $count,
'pagination' => array(
'pageSize' => Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize']),
),
));
}

Related

Using yii relations to get data across different models

I'm still new to Yii, but I'm trying to use relations() to join two tables and get all data from both table on each row pulled.
tables:
TABLE Artist KEYS(artist_Id, firstName, lastName)
TABLE Album KEYS(album_Id, title, artist_Id, genre)
// Album
public function relations()
{
return array(
'artist' => array(self::BELONGS_TO, 'Artist', 'artist_Id'),
'track' => array(self::HAS_MANY, 'Track', 'track_Id')
);
}
// Artist
public function relations()
{
return array(
'album' => array(self::HAS_MANY, 'Album', 'album_id')
);
}
// logic for getting information
$dataProvider=new CActiveDataProvider('Album');
foreach($dataProvider->getData() as $key){
echo '<br>' . $key->artist_Id; // does work
echo '<br>' . $key->firstName; // doesn't work
}
With this code, I can get and display the correct artist_Id for the album. However, I want to display the artist firstName and lastName with the artist_Id.
I needed to change my $dataProvider variable and how I was trying to access in the view index.php
$dataProvider = new CActiveDataProvider('Album');
-to-
$dataProvider = new CActiveDataProvider('Album', array('criteria' => array('with' => array('artist'))));
and changing view index.php to one of the two:
'name' => 'artist.lastName',
or
'value' => '$data->artist->firstName'

YII dataProvider relation CDbCriteria

I have a problem regarding the use of CDbCriteria in a controller index action. I have 2 classes: event and attendee.
the class event has many attendee, and i want my event index action to render only the list of events of which the current loggedin user is an attendee...
$criteria = new CDbCriteria(array(
'order'=>'event_date desc',
'with' => array('attendees'=>array('alias'=>'attend')),
'condition'=>'attend.uid = ' . Yii::app()->user->id,
));
$dataProviderAtt=new CActiveDataProvider('Event',
array(
'criteria' => $criteria,
)
);
$this->render('index',array(
'dataProvider'=>$dataProviderAtt,
));
this does not work in DB with the message:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'user'
my relations in attendee class are set like this:
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'user' => array(self::BELONGS_TO, 'YumProfile', 'uid', 'alias'=>'user'),
);
}
I tried to change the defaultscope in attendee model and define multiple aliases:
public function defaultScope()
{
static $counter = 0;
return array(
'with' => array('user'=>array('alias'=>'user'.($counter++))),
//'with' => 'user',
'order' => 'score DESC',
);
}
but it does not seem to fix the issue and I then have more errors. Is my criteria correctly set?
Thx guys for your help
you are looking for
'on' => 'attend.uid = ' . Yii::app()->user->id,
as in your relation to the user
function relations()
{
return array(
'user' => array(
self::BELONGS_TO,
'attendees',
'',
'on' => 'attendees.uid = ' . Yii::app()->user->id,
),
);
}

Writting query using CDbcriteria for CgridView in YII.?

I am trying to show my data in gridview and in process have written the following query which I am trying to write using CDBCriteria,
//query
SELECT user. * , jobs. * , COUNT( jobs.user_id )
FROM user
INNER JOIN jobs ON user.id = jobs.user_id
GROUP BY user.id
I have tried the following thing:
$criteria = new CDbCriteria;
$criteria->select ='user.*,jobs.*';
$criteria->select ='COUNT(jobs.user_id)';
$criteria->select ='user';
$criteria->join ='INNER JOIN jobs ON user.id = jobs.user_id';
$criteria->group ='user.id';
return new CActiveDataProvider('manageemployers', array(
'criteria'=>$criteria,
my view have the following code.
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' =>$model->search(),
// 'filter' => $model,
'columns' => array(
array(
'name' => ' Employer ID',
'type' => 'raw',
'value' => 'CHtml::encode($data->id)',
'htmlOptions' => array('style'=>'width:90px;','class'=>'zzz'),
// 'filter'=>'false' /* for hiding filter boxes */
[...]
?>
My contoller
public function actionManageEmployers() {
$user_id = Yii::app()->session['user_id'];
if (Yii::app()->user->getId() === null)
$this->redirect(array('site/login'));
$model = new ManageEmployers();
$model->user_id = $user_id;
$this->render('manageemployers', array('model' => $model,
));
}
But its not working. Please help me on this one. Thanks!
If you have table relations set up, then in your User model (that refers to your user table) try writing your CDbCriteria like so:
$criteria = new CDbCriteria();
$criteria->with = array('jobs' => array('joinType' => 'STRAIGHT_JOIN'));
$criteria->together = true;
$criteria->addCondition('id = jobs.user_id');
return new CActiveDataProvider('manageemployers', array(
'criteria' => $criteria
));
EDIT
So now I'm able to understand your problem and I tried to fix it with this.
i think i had the solution, you don't need to get the data in the search() like you did it. you can use relations and other stuff to get your data.
firstly i would add a relation to your user-model like this:
'jobs' => array(self::HAS_MANY, 'Jobs', 'user_id')
after that, you can access all jobs of the user with $model->jobs
then you need to undo your changes of the search()-function. I mean that it must look like this:
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('attribute',$this->attribute);
//this is just an example ^
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
changes in the action:
$model = new ManageEmployers();
to this:
$model = new ManageEmployers("search");
changes in the view:
add something like this to your colums array:
array(
'name' => 'Total Jobs Posted',
'value' => 'count($data->jobs)',
'htmlOptions' => array('style'=>'width:90px;','class'=>'zzz'),
)

Displaying data from two tables in Yii CGridView

I want to show 2 tables with a right join, but the code I wrote does not work as expected. Can anyone tell me what I am doing wrong ?
view : admin.php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'punish-grid',
'dataProvider' => $model->searchJoin(),
'type' => 'striped bordered condensed',
'filter' => $model,
'columns' => array(
array(
'header' => 'No',
'type'=>'raw',
'htmlOptions'=>array('style'=>'width: 25px'),
'value'=>'$this->grid->dataProvider->pagination->currentPage
*$this->grid->dataProvider->pagination->pageSize + $row+1',
),
// i want to display p.kode,p.status from table status
'berlaku_punish',
'nilai',
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
),
),
));
and my model : BasePunish.php
public function relations() {
return array(
'idStatus' => array(self::BELONGS_TO, 'Status', 'id_status'),
);
}
public function searchJoin() {
$criteria = new CDbCriteria;
$criteria->select = 'p.kode,p.status,t.nilai,t.berlaku_punish';
$criteria->join= 'RIGHT JOIN status p ON (t.id_status=p.id)';
$criteria->condition = 't.id_status IS NULL';
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
'sort'=>array(
'defaultOrder'=>'kode ASC',
),
)
);
}
I might really did not understand what you are asking but still if nothing is working for you then you can try this
array(
'header'=>'Products',
'value'=>array($model,'gridCreateUser'),
),
In this, the value will try to find the function gridCreateUser in the class of which $model is the object. In your case i guess $model is the object of the BasePunish.
So in your BasePunish.php create a function gridCreateUser() and then you can return the value which you want to display in your widget.
eg:-
In your BasePunish.php
public function gridCreateUser($data)
{
// you can access the object $data here
// do what ever you want to do
$value='return whatever you want to return';
return $value;
// this $value will be displayed there
}

Data Provider relation not getting required data

Guardian model:(relation)
'studentsGuardians' => array(self::HAS_MANY, 'StudentsGuardian', 'guardian_id'),
Student model relation:
'studentsGuardians' => array(self::HAS_MANY, 'StudentsGuardian', 'student_id'),
Students Guardian model relation:
'guardian' => array(self::BELONGS_TO, 'Guardian', 'guardian_id'),
'student' => array(self::BELONGS_TO, 'Student', 'student_id'),
Now in controller i want to select those students whose guardian_id=id but my code select all records without filtering. my code is
public function actionAssignGuardian($id)
{
$dataProvider = new CActiveDataProvider('Student',
array(
'criteria' => array(
'with'=>array('studentsGuardians',
array('criteria'=>
array('with'=>array('guardian','condition'=>' guardian_id=:id',
'params'=>array('id'=>$id))))),
),
));
$this->renderPartial('Pages/_assignGuardian', array(
'dataProvider' => $dataProvider,
'id'=>$id,
));
}
Kindly point me to correct way that how could i select those students whose guardian_id= given id in function. I am new to yii.
Thanks.
Add this line into Student model (below previous relation line studentsGuardians)
'guardians' => array(self::HAS_MANY, 'Guardian', array('guardian_id'=>'guardian_id'),'through'=>'studentsGuardians'),
Then you can do query like this
$dataProvider = new CActiveDataProvider('Student',
array(
'criteria' => array(
'with'=>array(
'guardians' =>array(
'condition'=>' guardian_id=:id',
'params'=>array('id'=>$id)
)))
));
(You should also dump $id to make sure that it is valid value)

Categories