Magento API: Set dropdown attribute option for a storeview - api

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();

Related

Set Upload Folder when using FAL in TCA

Is it possible when using FAL, to set the upload destination folder directly in the TCA column? My configuration looks like this at the moment:
'images_outdoor' => Array (
'exclude' => 1,
'label' => 'Outdoor: ',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('images_outdoor', Array (
'appearance' => Array (
'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference'
),
'minitems' => 1,
'maxitems' => 6,
), $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']),
),
I have such columns in different TCAs and want their images to be saved in different folders. So a standard folder setting doesn't work here.
I know this one is old but here is a answer.
There are no supported way for TYPO3 6.2, but in the new TYPO3 7.6 LTS it should be possible to register a hook in your ext_localconf.php file, add this:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getDefaultUploadFolder'][] = 'VendorName\ExtensionName\Hooks\BackendUserAuthentication->getDefaultUploadFolder'
Create the file Classes/Hooks/BackendUserAuthentication.php and write something like this:
<?php
namespace VendorName\ExtensionName\Hooks;
classe BackendUserAuthentication {
public function getDefaultUploadFolder(Array $params, \TYPO3\CMS\Core\Authentication\BackendUserAuthentication $backendUserAuthentication) {
// Do what you wants here and return a object of \TYPO3\CMS\Core\Resource\Folder
}
}
The params array will contain this:
$_params = array(
'uploadFolder' => $uploadFolder, // The current \TYPO3\CMS\Core\Resource\Folder object, properly 1:/user_upload/
'pid' => $pid, // Page id
'table' => $table, // The table name
'field' => $field, // The field name
);
Now use the table and field name to change the upload folder - good look :)

Magento bundle products - selection_id cannot be null?

I am trying to create a bundled product programmatically, and setting the options via this:
$new_options[$count] = array(
'required' => 0,
'position' => 1,
'parent_id' => $parentProduct->getId(),
'type' => 'select',
'title' => $product->getName(),
'default_title' => $product->getName()
);
$new_selections[$count] = array(array(
'product_id' => $product->getEntityId(),
'selection_qty' => $child['qty'],
'selection_can_change_qty' => 0,
'position' => 0,
'is_default' => 1,
'selection_price_type' => 0,
'selection_price_value' => 0.0
));
...
$parentProduct->setBundleOptionsData($new_options);
$parentProduct->setBundleSelectionsData($new_selections);
Which looks correct (as described in https://stackoverflow.com/a/4415800/494643). However, it is not working - I get an SQL exception complaining that Column 'selection_id' cannot be null'. How do I get around this? The selection id is an auto_increment column, so I can't get it until it is created, but it looks like it cannot be created?
The solution lies in the _beforeSave function of the Mage_Bundle_Model_Selection model.
This causes it to attempt to write the selection_id to the catalog_product_bundle_selection_price table, before it has saved the selection object - and therefore before it has generated a selection_id. The answer therefore is to force it to generate an id before it saves, so looking again at the _beforeSave function, we can see that it only saves the price if the store is not 0.
Specifically, this part:
$storeId = Mage::registry('product')->getStoreId();
if (!Mage::helper('catalog')->isPriceGlobal() && $storeId) {
which means that if we set the store id of the registry product to 0 first, we can cause it to save the selection, without saving the price. We would then need to reset the store to the previous value, and save again, to record the price - although only after having reloaded the object to get the newly generated selection id.

yii cache dependency referrer

I'm building a small webshop. This shop has categories and products. 1 product can have multiple categories.
At the productpage a breadcrumb-path shows the referring category-name (via urlReferrer).
Im trying to get Yii to cache by page with OutputCache, depending on the referrer (the category, since this would change the breadcrump-trail).
Here is my non-working filter:
public function filters() {
return array(
array(
'COutputCache',
'duration' => 3600,
'varyByExpression' => array($this->getReferringCategory()),
'varyByParam' => array('id','slug'),
'dependency' => array(
'class' => 'CDbCacheDependency',
'sql' => 'SELECT MAX(date_updated) FROM product WHERE product_id = '.Yii::app()->request->getParam('id'),
),
)
);
}
Does anybody have a good approach for this?
Best regards, thanks!
'varyByExpression' param should be a PHP expression (it would be evaluated by eval) or PHP callback (would be evaluated by call_user_func_array())
if you use php >=5.4.0, try something like this:
'varyByExpression' => function(){return $this->getReferringCategory();},
Or like this, for older versions:
'varyByExpression' => '$this->getReferringCategory()',

Restricting a category for a certain country in Prestashop 1.5

I need to restrict a category to a set of countries in Prestashop 1.5.
This restriction would prevent the shipping of a product belonging to such a category; as such, the users would still be able to see the products but they would not be able to buy them.
Ideally, I wanted to develop a module that would insert a list of countries (checkbox style, as in the Modules -> Payment page (AdminPayment)) inside a category's edit page, but I haven't been able to do so.
Why can't i simply paste the following code inside the renderForm() function?
Only the description is visible if i do so...
array(
'items' =>Country::getCountries(Context::getContext()->language->id),
'title' => $this->l('Country restrictions'),
'desc' => $this->l('Please mark the checkbox(es) for the country or countries for which you want to block the shipping.'),
'name_id' => 'country',
'identifier' => 'id_country',
'icon' => 'world',
),
EDIT:
I managed to get the list of countries working:
array(
'type' => 'checkbox',
'label' => $this->l('Restricted Countries').':',
'class' => 'sel_country',
'name' => 'restricted_countries',
'values' => array(
'query' => Country::getCountries(Context::getContext()->language->id),
'id' => 'id_country',
'name' => 'name'
),
'desc' => $this->l('Mark all the countries you want to block the selling to. The restrictions will always be applied to every subcategory as well')
),
Now, I can save these values by checking if the value "submitAddcategory" is being submitted in the postProcess function and by running an insert query there. Similarly, I can also load the IDs of the blocked countries from the database, but how can I tick the respective select boxes in the list of countries?
My initial "quick and dirty" idea was to use jQuery selectors inside a document.ready(), but the code gets inserted before everything else and, as such, it won't work because jQuery isn't even loaded yet.
How can this be done?
Cheers
I solved it by using the following code right before the end of the renderForm() function.
The Pièce de résistance was $this->fields_value, as sadly I didn't known of its existence.
public function getRestrictedCountries($obj)
{
// Loading blacklisted countries
$country = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT DISTINCT id_country
FROM `'._DB_PREFIX_.'category_country_restriction`
WHERE id_category = ' . (int)Tools::getValue('id_category') . ';');
$blacklisted_countries = array();
if (is_array($country))
foreach ($country as $cnt)
$blacklisted_countries[] = $cnt['id_country'];
// Global country list
$c_todos = Country::getCountries(Context::getContext()->language->id);
// Crossmatching everything
foreach ($c_todos as $c)
$this->fields_value['restricted_countries_'.$c['id_country']] = Tools::getValue('restricted_countries_'.$c['id_country'], (in_array($c['id_country'], $blacklisted_countries)));
}
PS: The table I am reading from is basically an associative table between 'category' and 'country'

SugarCRM - Add leads with auto-incremented ID

I use the SOAP API to add new leads to SugarCRM. Additionally, I use a plugin to assign an auto-incremented lead ID whenever a new lead is created (http://www.sugarforge.org/projects/autoincrement/).
Now, the plugin works fine, if I create a new lead via frontend. But, if I use the SOAP API, the function from the module, which assigns the auto-increment ID to the lead, does not trigger.
I create the lead via
$module = 'Leads';
$params = array(
'session' => $session,
'module_name' => $module,
'name_value_list' => array(
array('name' => 'id', 'value' => ''),
//array('name' => 'int_lead_id_c', 'value' => ''),
array('name' => 'first_name', 'value' => $_POST["first_name"]),
array('name' => 'last_name', 'value' => $_POST["last_name"]),
array('name' => 'phone_home', 'value' => $_POST["phone"]),
array('name' => 'email1', 'value' => $_POST["email"]),
array('name' => 'assigned_user_id', 'value' => '1'),
)
);
//Create the Lead record
$lead_result = $soapclient->call('set_entry', $params);
The function in the module is this one:
class SugarFieldAutoincrement extends SugarFieldBase {
/**
* Override the SugarFieldBase::save() function to implement the logic to get the next autoincrement value
* and format the saved value based on the attributes defined for the field.
*
* #param SugarBean bean - the bean performing the save
* #param array params - an array of paramester relevant to the save, most likely will be $_REQUEST
* #param string field - the name of the field
*/
public function save(&$bean, $params, $field, $properties, $prefix = '') {
}
}
How can I make sure, that this function is also triggered, when adding leads via SOAP API?
Thanks a lot for your help! :-)
David
You would need to set the field type to 'autoincrement' and the dbType to 'int' in the vardef record for the field.
If I'm not mistaken, the Database has a UUID() trigger on insert for most tables, so you should be able to completely remove the id field.
If you want to trigger the function before saving, you can use beforeSave logic hook.