I created a new attribute ("for example my_attribute"). Magento's store already has many attribute sets (approx 20).
It's a very time consuming process if I manually add the attribute to the sets because my server is very slow.
I want to assign this new attribute("my_attribute") to all attribute sets programmatically.
Can anyone can help me?
Thanks in advance.
It's quite simple. In a custom module setup script:
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$installer->addAttribute(
'catalog_product',
'your_attribute_code',
array(
'label' => 'Attribute Label',
'group' => 'General', // this will add to all attribute sets in the General group
// ...
)
)
$installer->endSetup();
For other utilities, see Mage_Eav_Model_Entity_Setup.
Here's something quick, dirty, and untested :)
<?php
$attributeId = ID_HERE;
$installer = new Mage_Catalog_Model_Resource_Eav_Mysql4_Setup('core_setup');
$entityType = Mage::getModel('catalog/product')->getResource()->getEntityType();
$collection = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter($entityType->getId());
foreach ($collection as $attributeSet) {
$attributeGroupId = $installer->getDefaultAttributeGroupId('catalog_product', $attributeSet->getId());
$installer->addAttributeToSet('catalog_product', $attributeSet->getId(), $attributeGroupId, $attributeId);
}
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$attributeCode = 'my_attribute';
$entity = Mage_Catalog_Model_Product::ENTITY;
// create a new attribute if it doesn't exist
$existingAttribute = $installer->getAttribute($entity, $attributeCode);
if (empty($existingAttribute)) {
$installer->addAttribute($entity, $attributeCode, array(<configure your attribute here>));
}
$attributeId = $installer->getAttributeId($entity, $attributeCode);
// add it to all attribute sets' default group
foreach ($installer->getAllAttributeSetIds($entity) as $setId) {
$installer->addAttributeToSet(
$entity,
$setId,
$installer->getDefaultAttributeGroupId($entity, $setId),
$attributeId
);
}
$installer->endSetup();
As Attributes are not assigned with any attribute set then, you can delete that attribute you created and then create required attribute programmatically.
In the Magento wiki's Programmatically Adding Attributes and Attribute Sets Section, It describes createAttribute as the function that will solve your problem because it will create attributes and also assign them to attribute sets.
Hope This Helps!!
Additionally, Mage_Eav_Model_Entity_Setup and Mage_Catalog_Model_Resource_Setup, which extends from the aforementioned class, have all of the methods that you need to create attributes, sets, and groups. They are fairly straightforward, and they will help you understand how you're supposed to do it properly and prevent you from from writing bad or redundant code. I find most of the articles floating around the Internet and even Magento's own wiki entries feature poorly written code.
Related
I added two text columns to sales_flat_quote_item in order to store data and for other reasons When i add product to cart. my problem is that i cant save the data. i tried a lot of examples but without any success.
here i add the coulmns :
$installer = $this;
$connection = $installer->getConnection();
$installer->startSetup();
$installer->getConnection()
->addColumn($installer->getTable('sales/quote_item'),
'pack_name',
array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
'nullable' => true,
'default' => null,
'comment' => 'pack_name'
)
);
$installer->endSetup()
;
this is the code in my observer where i try to save the data :
$quote_item = Mage::getModel('sales/quote_item')->load($quote->Id);
$quote_item->setPackName($string);
$quote_item->save();
any help?
It's not advisable to add columns to flat tables like this. The magic methods aren't working because your update to the schema goes against Magento best practices. If you just want a quick fix though, you can do it with raw SQL queries:
<?php
$transaction = Mage::getSingleton('core/resource')->getConnection('core_write');
try {
$transaction->beginTransaction();
$query_string = "UPDATE sales_flat_quote_item
SET pack_name='packname'
WHERE id='id'";
$transaction->query($query_string);
$transaction->commit();
}
catch (Exception $e) {
$transaction->rollBack();
}
Be careful though, it's not secure. Make sure your data is sanitized.
I want to update an existing form in Magento backend. Because I don't want to touch the original extension I copied the file and rewrote the class:
class Bleedo_xta_Block_Adminhtml_xta_Edit_Tab_information extends Hedox_xta_Block_Adminhtml_xta_Edit_Tab_information {
protected function _prepareForm() {
parent::_prepareForm();
$form = $this->getForm();
This works (if you found this article via Google, don't forget to insert this rewrite in your config.xml)
If I want to add a new field to this form you can easily do this by
$options = $form->getElement('options_form');
$options->addField('new_cost', 'text', array(
'name' => 'new_cost',
'label' => $this->__('New Cost'),
));
But how can I update an existing field? The problem is that I want to set an already existing field to "required". But if I'm using addField I get an error.
Thank you so much!
/* #var $elm Varien_Data_Form_Element_Text */
$elm = $this->getForm()->getElement('new_cost');
$elm->setData('required',1);
I want to change the attribute set of Magento. I searched through, and everyone suggested to delete the product and re-import it with new attribute set.
I did the same however after importing the data I could not see product reviews and associated blog post with product.
Can anyone tell me is it possible to get product reviews and associated blog post after re-importing the product with new attribute set.
Once set you can't change the attribute set of a product. But it's possible using this module so you don't have to reimport your data
https://marketplace.magento.com/flagbit-magento-changeattributeset.html
It's also possible to change the attribute set directly in the database.
Look up the attribute set ID in table eav_attribute_set
Change the attribute set ID in catalog_product_entity
Of course, be careful when changing data this way.
It is fiddly to do and a bit messy:
Make sure new attribute set is set up
Export the products you want to change
Delete the products that you are changing on the site
Change the attribute set on the downloaded file
Import changed file again
Open each changed product, set their attribute values, save it
Or do what I do, install this great extension from Amasty http://amasty.com/mass-product-actions.html - it makes changing a breeze and gives many more time saving and enhancing options.
Once you delete the product you can't get the old review.
You don't need to delete the product . You can change the attribute set by editing and use.
other wise create a new attribute set and create new product.
Yes. We can change product attribute set programmatically.
I prefer to create massaction in catalog product grid to multiselect product and then select massaction for the products.
Creating massaction in grid.php
$sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
->load()
->toOptionHash();
$this->getMassactionBlock()->addItem('changeattributeset', array(
'label'=> Mage::helper('catalog')->__('Change attribute set'),
'url' => $block->getUrl('*/*/changeattributeset', array('_current'=>true)),
'additional' => array(
'visibility' => array(
'name' => 'attribute_set',
'type' => 'select',
'class' => 'required-entry',
'label' => Mage::helper('catalog')->__('Attribute Set'),
'values' => $sets
)
)
));
Creating controller action for change attribute sets of the selected products.
public function changeattributesetAction()
{
$productIds = $this->getRequest()->getParam('product');
$storeId = (int)$this->getRequest()->getParam('store', 0);
if (!is_array($productIds)) {
$this->_getSession()->addError($this->__('Please select product(s)'));
} else {
try {
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')
->unsetData()
->setStoreId($storeId)
->load($productId)
->setAttributeSetId($this->getRequest()->getParam('attribute_set'))
->setIsMassupdate(true)
->save();
}
Mage::dispatchEvent('catalog_product_massupdate_after', array('products'=>$productIds));
$this->_getSession()->addSuccess(
$this->__('Total of %d record(s) were successfully updated', count($productIds))
);
}
catch (Exception $e) {
$this->_getSession()->addException($e, $e->getMessage());
}
}
$this->_redirect('adminhtml/catalog_product/index/', array());
}
You can add to your data patch apply function something like this:
public function apply(): self
{
$this->moduleDataSetup->getConnection()->startSetup();
/** #var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttributeToSet(
Product::ENTITY,
'Default',
'General',
CustomAttributesInterface::ATTRIBUTE_CODE_MANUFACTURER
);
$this->moduleDataSetup->getConnection()->endSetup();
return $this;
}
This changes the manufacturer products attribute to the Default attribute set. (By default this attribute has no attribute set.)
Hope it helps :)
I'm using SCP with success, I don't think the problem is there. Basically I've got an observer that looks for the "Add to cart" event and goes from there. Here's my observer method:
public function catalogProductLoadAfter(Varien_Event_Observer $observer)
{
// set the additional options on the product
$action = Mage::app()->getFrontController()->getAction();
if ($action->getFullActionName() == 'checkout_cart_add') {
// assuming you are posting your custom form values in an array called extra_options...
if ($options = $action->getRequest()->getParam('extra_options')) {
$product = $observer->getProduct();
// add to the additional options array
$additionalOptions = array();
if ($additionalOption = $product->getCustomOption('additional_options')) {
$additionalOptions = (array)unserialize($additionalOption->getValue());
}
foreach ($options as $key => $value) {
$additionalOptions[] = array(
'label' => $key,
'value' => $value,
'value' => $value,
);
}
// add the additional options array with the option code additional_options
$observer->getProduct()->addCustomOption('additional_options', serialize($additionalOptions));
}
}
}
All looks well and functions just fine. I've dropped in some Zend_Debug::dump statements at various points and have found where I think the issue is. $product doesn't contain any custom options, or at least doesn't appear to! I've done Zend_Debug::dump($product); and this gives me the following: https://gist.github.com/720a111bc299501726d7 The important thing to see here is that the product object shown is a child product of the configurable. ALL child products have custom options (I just had to set them to get to this stage!).
In the cart page the custom options are displayed correctly, as I've just set them. So why at this midpoint when I do Zend_Debug::dump($product); just before the foreach does the above gist not show any custom options, specifically line 9. My observer fails to do it's job because $additionalOptions ends up being blank, just displays as array {}. As such the foreach doesn't fire and the script falls over. So why are no custom options shown in the gist, yet they ARE there as they show on the product page AND they show after this script executes on the cart page?
To further "prove" this, I'm getting an Invalid argument for foreach() as a result.
Having an attribute set, how can I get a list of the attributes it contains (or better yet, just the custom attributes that don't belong to the Default attribute set)?
The attribute set itself can be obtained in several ways, such as:
$entityTypeId = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
$attributeSet = Mage::getResourceModel('eav/entity_attribute_set_collection')->setEntityTypeFilter($entityTypeId)->addFilter('attribute_set_name', 'Default');
Note that I need to use the attribute set, so getting the list of attributes from a product is not the solution I am looking for.
Mage::getModel('catalog/product_attribute_set_api')->items();
Gets the attribute sets themselves.
Mage::getModel('catalog/product_attribute_api')->items($setId);
Gets the attributes inside the attribute sets.
I believe the answer lies in this model
Mage::getModel('catalog/product_attribute_set_api')->items($setId);
The class is Mage_Catalog_Model_Product_Attribute_Api it seems to have two methods. The items() methods seems to do what you ask i.e. "Retrieve attributes from specified attribute set"
I hope that helps :)
The right way:
$attributes = Mage::getResourceModel('catalog/product_attribute_collection')
->setAttributeSetFilter($attributeSetId)
->getItems();
var_dump($attributes);
You can change resources 'catalog/product_attribute_collection' (customer, ...)
And Set ID $attributeSetId
Regarding Attribute Set, there is a good collection of code snippets in the following blog article:
http://www.blog.magepsycho.com/playing-with-attribute-set-in-magento/
Hope you will find them useful.
Thanks
You don't necessarily need to access the API class. There is a more natural approach available. If you have a product:
/** #var Mage_Catalog_Model_Product $product **/
$attributes = $product->getTypeInstance(true)->getSetAttributes($product);
If not:
$attributes = Mage::getModel('catalog/product')->getResource()
->loadAllAttributes()
->getSortedAttributes($attributeSetId);
I've been searching for an answer, I could'nt find it and I solve my problem with these lines;
$attributeSetId = /* set id */;
$attributes = array();
$groups = Mage::getModel('eav/entity_attribute_group')
->getResourceCollection()
->setAttributeSetFilter($attributeSetId)
->setSortOrder()
->load();
foreach ($groups as $node) {
$nodeChildren = Mage::getResourceModel('catalog/product_attribute_collection')
->setAttributeGroupFilter($node->getId())
//->addFieldToFilter('is_user_defined', true) # I was trying to get user defined attributes.
->addVisibleFilter()
->load();
if ($nodeChildren->getSize() > 0) {
foreach ($nodeChildren->getItems() as $child) {
$attr = array(
'id' => $child->getAttributeId(),
'text' => $child->getAttributeCode()
);
$attributes[] = $attr;
}
}
}
var_dump($attributes);