Move existing category attribute into new group
Question
I basically want to move an existing category attribute into a newly created group in my setup file. This is the way I expected it to work:
$installer = new Mage_Eav_Model_Entity_Setup('core_setup');
$installer->startSetup();
$entityTypeId = 'catalog_category';
$installer->addAttribute($entityTypeId, 'my_attribute', array(
'group' => 'Adams Group',
'input' => 'text',
'type' => 'varchar',
'label' => 'My Attribute Label',
'visible' => 1,
'required' => 0,
'user_defined' => 1,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE
));
$installer->updateAttribute($entityTypeId, 'meta_title', array(
'group' => 'Adams Group'
));
$installer->endSetup();
It adds the new attribute to the group as expected, but it doesn't move meta_title in the new group. I suppose I'm using the wrong code. Any help much appreciated.
Solution
You can move an attribute of Mage_Catalog_Model_Category to a new group, through an installer script, by performing the following logic.
Prerequisites:
- The catalog attribute must already exist
- The group which you are moving the attribute TO must already exist
The only changes here that should be necessary, are the values of the top two variables ($attribute_code and $attribute_group_name).
<?php
/**
* Moving a category attribute from one group to another.
*/
$this->startSetup();
$attribute_code = 'your_attribute_code'; // Catalog Category attribute we want to move
$attribute_group_name = 'Some Group Name'; // Group we want to move it to (must already exist).
// Some necessary objects for this operation.
$conn = $this->getConnection();
$read = Mage::getSingleton('core/resource')->getConnection('core_read');
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
// Fetch the id of the attribute we want to move
$attribute_id = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_category', $attribute_code)->getId();
// Fetch the 'entity_type_id' for a Magento category.
$entity_type_id = Mage::getModel('eav/entity_type')->loadByCode('catalog_category')->getId();
// Fetch the 'attribute_set_id' for Magento categories (unlike products, there's only one for categories)
$tbl = $conn->getTableName('eav_attribute_set');
$sql = "SELECT `attribute_set_id` FROM `{$tbl}` WHERE `entity_type_id` = :entity_type_id";
$bnd = array('entity_type_id' => $entity_type_id);
$attribute_set_id = $read->fetchCol($sql, $bnd);
$attribute_set_id = $attribute_set_id[0];
// Now we'll need the 'attribute_group_id' for the group we want to move the attribute TO
$tbl = $conn->getTableName('eav_attribute_group');
$sql = "SELECT `attribute_group_id` FROM `{$tbl}` WHERE `attribute_set_id` = :attribute_set_id AND `attribute_group_name` = :attribute_group_name";
$bnd = array('attribute_set_id' => $attribute_set_id, 'attribute_group_name' => $attribute_group_name);
$attribute_group_id = $read->fetchCol($sql, $bnd);
$attribute_group_id = $attribute_group_id[0];
// We now have all the information we need to move our attribute to the new group.
$tbl = $conn->getTableName('eav_entity_attribute');
$sql = "UPDATE `{$tbl}` SET `attribute_group_id` = :attribute_group_id WHERE `entity_type_id` = :entity_type_id AND `attribute_set_id` = :attribute_set_id AND `attribute_id` = :attribute_id";
$bnd = array('attribute_group_id' => $attribute_group_id, 'entity_type_id' => $entity_type_id, 'attribute_set_id' => $attribute_set_id, 'attribute_id' => $attribute_id);
$write->query($sql, $bnd);
$this->endSetup();
If we read this code carefully, one will see that all that really is happening here, is that we're finding the ID of the group, and updating the attribute_group_id
column in the eav_entity_attribute
table, for the record which contains our attribute. Personally, I find it easier to just do this directly in the database. However you asked how to do this via an installer script ;)
OTHER TIPS
From memory, I think it's something like -
$installer->addAttributeToGroup($entityTypeId, $attributeSetId, array('group' => 'Adams Group'), 'meta_title');
Not tested it though sorry.
Doing it the correct way
This is how you do it for product attributes, and it should work by changing the entity type id:
$setup = new Mage_Catalog_Model_Resource_Setup('core_setup');
Load your attribute:
$attribute = Mage::getModel('eav/entity_attribute')
->loadByCode('catalog_product', 'my_attribute');
Get attribute set ID (if you have multiple attribute sets, you'll have to do this for every attribute set):
$setId = $setup->getAttributeSetId(Mage_Catalog_Model_Product::ENTITY, 'Default');
Get attribute group ID (in this case I'm moving an attribute into the Visibility tab):
$groupId = $setup->getAttributeGroupId(Mage_Catalog_Model_Product::ENTITY, $setId, 'Visibility');
And lastly, call addAttributeToSet
:
$setup->addAttributeToSet(Mage_Catalog_Model_Product::ENTITY, $setId, $groupId, $attribute->getId());
It turns out that this is not possible to do with an existing function through the setup file.