I have three models named:
content
category
contentCategory
and between content and category is a MANY_MANY relation like this:
public function relations()
{
return array(
'contents'=>array(self::MANY_MANY, 'Content',
'tbl_content_category(category_id, content_id)',
'order'=>'contents.id DESC',
'limit'=>'10',
'offset'=>'30',
),
);
}
and it work well. but I want to set offset parameter from $_GET variables. how can I do this?
Just set
'limit'=> Yii::app()->request->getQuery('limit', 10),
'offset'=> Yii::app()->request->getQuery('offset', 30),
Related
I am working with magento API and need to create dropdown options for different storeviews.
I found a function to to create a dropdown option for default storeview:
public function addAttributeOption($arg_attribute, $arg_value)
{
$attribute_model = Mage::getModel('eav/entity_attribute');
$attribute_options_model= Mage::getModel('eav/entity_attribute_source_table');
$attribute_code = $attribute_model->getIdByCode('catalog_product', $arg_attribute);
$attribute = $attribute_model->load($attribute_code);
$attribute_table = $attribute_options_model->setAttribute($attribute);
$options = $attribute_options_model->getAllOptions(false);
$value['option'] = array($arg_value,$arg_value);
$result = array('value' => $value);
$attribute->setData('option',$result);
$attribute->save();
}
This functions works fine, I can add a new attribut value for default storeview.
Example:
I have the attribute "mycolor" and call the function like
addAttributeOption("mycolor", "black")
Now I have a storeview for a german shop and like to set the german color. I would need something like
addAttributeOption("mycolor", "black", "schwarz", $storeview)
Means set the color option of storeview to schwarz where the color of the default value is black.
Does anybody has an Idea how can I do that?
Best regards
I figure you alreay found your solution but perhaps I can help someone else who's new to Magento like I am. Today I had to find a way to import attributes (Product Attributes only that is) from an external Products-Managing-System into Magento running with multiple store views, too. I don't know where the questioner's addAttributeOption function came from but the Magento installer script offers its very own addAttributeOption(). So I took a look into Setup.php where Magento's addAttributeOption() is defined:
{Your Magento Path}/app/code/core/Mage/Eav/Model/Entity/Setup.php
Now, in the Magento Version i'm working with (1.9.1.0) addAttributeOption() expects one argument, an array called $option. It's architecture looks as follows:
Array (
'attribute_id' => '{attributeId}',
'value' => array(
'{optionId}' => array(
'{storeId}' => '{labelName}',
),
),
'delete' => array(
//...
),
'order' => array(
//...
)
);
As you can see, 'value' expects an array and this array's key determines the storeID. In most addAttributeOption()-introductions I found on the web, the storeID is hard coded to 0 with no further explanation - 0 makes it the required default admin value. So, quite obviously by now, for adding Options with StoreView-dependent labels we simply have to add an extra array value for each StoreView like this:
Array (
'attribute_id' => $attribute_id,
'value' => array(
'option1' => array(
'0' => 'black', // required admin value
'1' => 'Schwarz (RAL 9005)', // if storeId = 1 is German
'2' => 'Black (RAL 9005)', // if storeId = 2 is English
),
'option2' => array(
'0' => 'blue',
'1' => 'Blau (RAL 5015)',
'2' => 'Blue (RAL 5015)',
),
// And so on...
)
);
Note: If your option's array-index is a number addAttributeOption() expects it to be the ID-Number of an already existing Option. This is great in case you want to update already existing options but this also means a new Option musn't be numeric. Hence I named them 'option1' & 'option2'.
You can call addAttributeOption() like this:
Mage::app();
$installer = Mage::getResourceModel('catalog/setup','catalog_setup');
$installer->startSetup();
// ...
// generate your Options-Array
// I called it $newOptions
$installer->addAttributeOption($newOptions);
$installer->endSetup();
I have a model with a boolean value, generated from a table like this:
CREATE TABLE receivable (
...
is_paid INTEGER DEFAULT NULL,
...
)
You should only take notice of the possible NULL value.
I have a gii-generated Receivable.php-model and a simple CGridView, like this:
$dataProvider = $model->search();
$dataProvider->pagination = ['pageSize'=>20];
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'filter'=>$model,
'columns'=>array(
'id',
[
'name'=>'is_paid',
'type'=>'raw',
'value'=>'($data->is_paid==1)?"PAID":"";',
'filter'=>['1'=>'PAID', '0'=>'0']
],
'someothercolumn',
['class'=>'CButtonColumn']
),
);
It should make sense so far? It does work fine I must say, with just one tiny problem - I want to allow filtering on null values as well!
'filter'=>['1'=>'PAID', '0'=>'0', null=>'null'] // This shows all records.
'filter'=>['1'=>'PAID', '0'=>'0', ''=>'null'] // This also shows all records.
'filter'=>['1'=>'PAID', '<>1'=>'null or zero'] // This shows 0-records only.
Well, now I'm at a loss. Is there any way I can use the CDataColumn.filter to allow the user to filter on null values? (Only display rows where 'is_paid'==null)
Edit: Values can be 1,0 or NULL, but the filter can only be applied for 1 or 0 (or show everything). How can I let the user display rows with null-values only?
Any help is much appreciated!
this is one way you can do it
1.'filter' => array('0' => Yii::t('app', 'No'), '1' => Yii::t('app', 'Yes')),
or something like this
2.is_paid:boolean
or something like this
3.'filter' => CHtml::listData(UserRegistry::model()->findAll(), 'id_user_registry', 'firstname' ),
In the above example i have the values in a db table
or something like this
4.'filter' => Lookup::items('option'),
and for the above example in the model you would have something like this
4. public static function items($type, $code)
{
if(!isset(self::$_items[$type]))
self::loadItems($type);
return isset(self::$_items[$type][$code]) ? self::$_items[$type][$code] : false;
}
private static function loadItems($type)
{
self::$_items[$type]=array();
$models=self::model()->findAll(array(
'condition'=>'type=:type',
'params'=>array(':type'=>$type),
//'order'=>'position',
));
foreach($models as $model)
self::$_items[$type][$model->code]=$model->name;
}
I'm using CGridView but one of the field is an array ['xx' ,'yy' , 'zz',...]
How can I display that i searched for an answer but did not find
is it possible to use something like DropDownlist to display the values in the array
I have a static array special_offer in a model;
It will filter by the value; This is a drop down list example;
I replaced a field within the cgridview with a array as follows:
array(
'name' => 'special_offer',
'value' => 'Package::$special_offer[$data->special_offer]',
'filter' => Package::$special_offer,
),
In order to use dropDownList in a CGridView column, your array needs to be associative. I recommend that you create a method in your model which converts it into an associative array, something like:
public function getAssociativeArray()
{
$array = array('xx', 'yy', 'zz'); // or use an attribute value
return array_combine(array_values($array), $array);
}
Then in your CGridView, add this as a column, replacing the model/field names with your own:
array(
'name' => 'yourFieldName',
'type' => 'raw',
'value' => 'CHtml::activeDropDownList($data, "yourFieldName", YourModel::model()->associativeArray)',
),
I have two tables tbl_business and business_contacts of the following structure:
tbl_business
---
business_id (PK)
othercolumns
and
business_contacts
---
contact_id (PK)
business_id
othercolumns
The scenario is that one business row has many contacts. I am using cGridview using gii's CRUD generator and needed to display firstname and lastname from business_contacts (one of multiple possible rows in the table) for each tbl_business record.
As far as I understand, I've updated the relation function in tbl_business's model as:
'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname')
and for the same, a contact relation is defined in the business_contacts' model as:
'contactbusiness' => array(self::BELONGS_TO,'BusinessContact','business_id')
I expected that would work for pulling related records so that I can have something in the grid like, business_id, contact_firstname, contact_lastname , ... otherbusinesstablecolumns .. but I'm only getting blank values under firstname and lastname .. could someone please help me understand the error? :(
So you are trying to display a table of Businesses (tbl_business) using CGridView? And in each Business's row you want to list multiple Contacts (business_contacts)?
CGridView does not support displaying HAS_MANY relations by default. CGridView makes it easy to list which Business a Contact BELONGS_TO (i.e. you can use a column name like contactbusiness.business_id), but not all of the Contacts that are in a business.
You can do it yourself though, by customizing a CDataColumn. (Note: this will not allow you to sort and filter the column, just view. You'll have to do a lot more work in to get those working.)
First, in your Business model, add a method like this to print out all of the contacts:
public function contactsToString() {
$return = '';
foreach ($this->businesscontacts as $contact) {
$return .= $contact->contact_firstname.' '.$contact->contact_firstname.'<br />';
}
return $return;
}
(EDIT: Or do this to print out just the first contact):
public function contactsToString() {
if($firstContact = array_shift($this->businesscontacts)) {
return $firstContact->contact_firstname.' '.$firstContact->contact_firstname;
}
return '';
}
Then make a new column in your grid and fill it with this data like so:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'business-grid',
'dataProvider'=>$model->yourDataProviderFunction(),
'columns'=>
'business_id',
array(
'header'=>'Business Contacts', // give new column a header
'type'=>'HTML', // set it to manual HTML
'value'=>'$data->contactsToString()' // here is where you call the new function
),
// other columns
)); ?>
EDIT2: Yet another way of doing this, if you just want to print out ONE of a HAS_MANY relation, would be to set up a new (additional) HAS_ONE relation for the same table:
public function relations()
{
return array(
'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname') // original
'firstBusinesscontact' => array(self::HAS_ONE, 'BusinessContact', 'business_id'), // the new relation
);
}
Then, in your CGridView you can just set up a column like so:
'columns'=>array(
'firstBusinesscontact.contact_firstname',
),
Getting only the first contact could be achieved like this also:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'business-grid',
'dataProvider'=>$model->yourDataProviderFunction(),
'columns'=>
'business_id',
//....
array(
'name' => 'contacts.contact_firstname',
'value' => '$data->contacts[0]->contact_firstname', // <------------------------
'type' => 'raw'
);
//....
),
Is there a way to change the default functionality in Zend_Db fetchall() method, so that it doesn't return this:
[0] => 100000055944231
[1] => 100000089064543
[2] => 100000145893011
[3] => 100000160760965
but this:
[100000055944231]
[100000089064543]
[100000145893011]
[100000160760965]
Although your question is actually flawed (noted by BartekR), I suppose you're trying to receive a simple array, instead of a multidimensional one.
You could do:
$results = $this->db->fetchAll($select);
$values = array_map(function($row) { return $row['column']; }, $results);
This will turn:
array(
array('column' => 'test'),
array('column' => 'test2'),
array('column' => 'test3'),
);
into
array(
'test',
'test2',
'test3'
);
(note; my example only works in PHP5.3+, if you're working with PHP5.2, you can define the function and use it by its name with array_map (e.g. array_map('methodName', $results))
I'm looking for a similar solution, I'm trying to load a field returned by the fetchAll($select) as the array key.. Without looping through the entire resultset.
So:
$results = $this->db->fetchAll($select, <FIELDNAME_TO_MAKE_KEY_OF_RESULTS_ARRAY>);
results[<my fieldname>]->dbfield2;
Further to Pieter's, I'd add the case where the rows are themselves arrays, and not just scalars; it's possible to nest the results, to as many fields as the query contains.
e.g. Here with two levels of nesting, respectively on field1 and field2.
$complex_results = array_map(function($row) { return array($row['field1'] => array($row['field2'] => $row)); }, $results);
As always, each row contains all fields, but $complex_results is indexed by field1, then field2 only.