CgridView should be filled with Mongo data- YII - yii

Im trying to populate Cgridview with Mongo data, but getting error "Undefined offset: 0"
Here is my coding,
$sql="SELECT name FROM CRM_Field Where crm_base_contact_id = ".$base;
$names =Yii::app()->db->createCommand($sql)->query()-> readAll();
$mongo = new Mongo( Yii::app()->mongodb->connectionString);
$collection = $mongo->test->crm_contact_tmp;
$mongocol = $mongo->test->crm_contact_tmp->find(array('crm_base_contact_id' => array('$in' => array($base))));
$arrayDataProvider = new CArrayDataProvider (iterator_to_array($mongocol) );
?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' =>'BCImported-grid',
'dataProvider' =>$arrayDataProvider,
'columns' => $names,
)); ?>
Can anyone suggest the correct way to do this? Im getting empty grid but with number of records in grid shows correct, but no data displays!!!

The data you're getting back from mongo doesn't have zero-based integer keys, which CArrayDataProvider requires. Looks like it's got arrays as keys. I think setting the use_keys parameter to false should solve this, i.e.:
$arrayDataProvider = new CArrayDataProvider (iterator_to_array($mongocol, false) );

Related

yii CGridView dataprovider and filter

I know we can show a gridview with a model and it's search method and filter the results, but can we make a gridview with another dataprovider and another model like this and filter its results? Does filter needs to be a part of dataprovider?
$attr = Yii::app()->request->getParam($name);
$model = new User('search');
$model->unsetAttributes();
$model->setAttributes($attr);
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $myDataProvider,
'filter' => $model,
'columns' => array(
array(
'name' => 'username',
'type' => 'raw',
'value' => 'CHtml::encode($data->username)'
),
array(
'name' => 'email',
'type' => 'raw',
),
),
));
The above code doesn't work and I need to add a filter on a previously made data provider.
Btw $attr has a valid data, but grid is not filtered.
$model doesn't affect $myDataProvider since the data provider is not obtained using this model.
$model->search() returns a CActiveDataProvider which contains a CDbCriteria instance. Different CDbCriteria can be combined using mergeWith(). So if you would like the data to be filtered using the values from the $model
...
$model->setAttributes($attr);
$newDataProvider=$model->search();
$myDataProvider->criteria->mergeWith($newDataProvider->criteria);
$this->widget('zii.widgets.grid.CGridView', array(
...
Filter does not need to be a part of dataprovider, but data provider needs to take the model into account, if you want to use it for filtering.
The way this is done by default is to create the data provider using search method on your model, which sets conditions of your data provider based on model values, like so:
'dataProvider' => $model->search()
There is nothing preventing you from creating different data provider, for example:
'dataProvider' => $model->createAnotherDataProvider()
And in your User model:
public function createAnotherDataProvider() {
{
// create your second data provider here
// with filtering based on model's attributes, e.g.:
$criteria = new CDbCriteria;
$criteria->compare('someAttribute', $this->someAttribute);
return new CActiveDataProvider('User', array(
'criteria' => $criteria,
));
}

Problems returning result of CDbCriteria based query

I have a query as follows
$criteria1 = new CDbCriteria();
$criteria1->condition = 'id = 1';
$modelA=Table1::model()->find($criteria1);
I can pass it to a view and return the title and entry
$this->widget('bootstrap.widgets.TbBox', array(
title' => $modelA['title'],
'content' => $modelA['entry'] ));
Now I'd like to return a range of entries
$criteria2 = new CDbCriteria();
$criteria2->condition = 'id > 7';
$modelB=Table1::model()->findAll($criteria2);
(btw : I'm following a form as laid out here). I was expecting to be able to read the resulting array of values out as below, but ['title'] is now being seen as a undefined index (obviously I'm expecting to read this out in a loop but you get the point)
$this->widget('bootstrap.widgets.TbBox', array(
'title' => $modelB['title'][0],
'content' => $modelB['entry'][0]));
Where am I going wrong?
Thanks
No, the indexes should be specified in the different order: the number of a specific element first, then the name of the property. Additionally, it's better (=cleaner) to name the result of findAll so it'll show you (and any other reader) that it's a collection, not a single model:
$models = Table1::model()->findAll($criteria2);
// ...
$this->widget('bootstrap.widgets.TbBox', array(
'title' => $models[0]['title']
//...
));
But even that's not necessary if you use foreach (and you probably will):
foreach ($models as $model):
// ...
$this->widget('some.name', array(
'title' => $model['title']
);
endforeach;

My cgridview is showing only one record in yii

i am newbii in yii development and have an issue while displaying data using cgridview as it is showing only first record
Motel,Hotel,Roomcategory and halls are models in which PK and FK are passing ...
Code is here
$sponsorm = Motel::model()->find('MotelId=:MotelId', array(':MotelId'=>Yii::app()->user->id));
$sponsorhotel = Hotel::model()->find('hotelId=:hotelId', array(':hotelId'=>$sponsorm->MotelId));
$room = Roomcategory::model()->find('hotelId=:hotelId', array(':hotelId'=>$sponsorhotel->hotelId));
$halls = Halls::model()->find('hotelId=:hotelId', array(':hotelId'=>$sponsorhotel->hotelId));
echo CHtml::image(Yii::app()->request->baseUrl.'/img/4.png');
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'businessowner-grid',
'dataProvider'=>$room->search(),
//'filter'=>$sponsore,
'columns'=>array(
'roomCategoryNames',
'noOfRooms',
'price',
),
));
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'businessowner-grid',
'dataProvider'=>$halls->search(),
//'filter'=>$sponsore,
'columns'=>array(
'Type',
//'noOfHalls',
'seats',
'price',
),
));
Right now you are finding only one record because you use find to get one specific record. So you assign this record data to model variables and then you do
$model->search();
This searches from specific table multiple values but you have set the attributes so, that it matches only one record.
To get Motel gridview data use following code:
$sponsorm = $dataProvider=new CActiveDataProvider('Motel', array(
'criteria'=>array(
'condition'=>'MotelId = :MotelId',
'params' => array(':MotelId'=>Yii::app()->user->id)
),
));
It is doing the same as search() but the difference is that searching criteria is different. You can use also code below.
$motelModel = new Model();
$motelModel->MotelId = Yii::app()->user->id;
Now there is only one attribute assigned an is setting a criteria to match all rows what has this user id in MotelId field.
$modelModel->search();
Also, I see that you echo something between logic. Please do not do that. Output data only in views and keep the logic out of views. :)

Use column alias in dataProvider

In my model I have a relation() like this.
'notRelUser' => array(
self::HAS_MANY,
'LocationUser',
'location_id',
'condition' => 'notRelUser.status is null',
'on' => 'notRelUser.user_id = ' . Yii::app()->user->getId(),
'with' => array('parent_location'),
'select' => array('*', 'name AS canApply'),
),
and this
public $canApply;
In my controller I have this
$regions = Location::model()->with('notRelUser')->findAll();
$arrayCanApply = new CArrayDataProvider($regions);
I then am trying to print out the value of canApply in a widget for datagrid
<?php $this->widget('bootstrap.widgets.TbGridView', array(
'dataProvider'=>$arrayCanApply,
'columns'=>array(
array('name'=>'name', 'header'=>'Name'),
array('name' => 'canApply', 'value'=>'$data->canApply', 'header'=>'CanApply'),
),
));
But the column with canApply is empty.
I have also tried without the $data-> part.
How can I print this alias?
(I know the value of the alias i trivial, but I will change that later)
UPDATE:
I can get the value by using select in CDbCriteria - but I want to do it in relation.
This does work.
$criteria = new CDbCriteria;
$criteria->select = '("foobar") AS canApply';
$regions = Location::model()->with('notRelUser')->findAll($criteria);
but it seems odd that I have to create a $criteria on everytime
you need to declare can canApply as an attribute of the model
in your model decalare canApply as an attribute
public $canApply;
I also had the same problem. Try 'value'=>'$data->notRelUser->canApply'
instead of 'value'=>'$data->canApply'. Also, you need to declare attribute
public $canApply;
in your LocationUser model, not in Location model.

Yii - Widgets - Explanation

I am trying to use drop down list widget :
$this->widget('ext.multiselect.JMultiSelect',array(
'model'=>$model,
'attribute'=>'attribute',
'data'=>$data,
// additional javascript options for the MultiSelect plugin
'options'=>array()
));
What I want to know is that Details of each option available in the widget array Like what is 'attribute' , 'model' and'data' represent , as I an unable to understand it form the documentation.
The model param is the model you are creating the multi select for.
The attribute is the model attribute you are creating the multi select for.
The data is an array of key/value pairs for the list items you want to display in the multi select.
For example, if you had a model 'User' and in that model you had a field 'access_rights' and you wanted to have that field as a multi select box with a few values, you might do something like:
In your controller:
$model = new User;
$data = array(
'admin_area'=>'Admin Area Access',
'product_area'=>'Product Area Access',
'customer_area'=>'Customer Area Access',
... etc
);
In your form in your view file:
$this->widget('ext.multiselect.JMultiSelect',array(
'model'=>$model,
'attribute'=>'access_rights',
'data'=>$data,
// additional javascript options for the MultiSelect plugin
'options'=>array()
));
Edit:
To add data to the multi select options from another model you can use the CHtml::listData() method, this takes an active record result set and converts it into an array of key/value pairs so you can use in any of the other CHtml methods that require a key/value pair. To do this you simply get the records you're after from the database using active record, eg;
$myData = Data::model->findAll();
You can then put that into the listData() method and it'll create your array:
$this->widget('ext.multiselect.JMultiSelect',array(
'model'=>$model,
'attribute'=>'access_rights',
'data'=>CHtml::listData($myData, 'id', 'name'),
// additional javascript options for the MultiSelect plugin
'options'=>array()
));
(where 'id' and 'name' are the fields from the model table that you want to be the 'key' and 'value' within the array)
echo $form->dropDownList($model, 'category', CHtml::listData(TblCategory::model()->findAll(),
'id', 'category_name'), array('empty' => '---Select Category---',
'style' => 'width:350px;')), array() ?>
<?php echo $form->error($model, 'category'); ?>