Magento – Magento – Add / Remove Attributes to Existing Configurable Products

configurable-productmagento-1.7products-management

What is the correct procedure – rather than deleting the product and starting again to add or remove attributes to existing configurable products.

When creating a configurable product you are asked to choose which attributes to use for the product.

I have a lot of products i now need to remove some attributes for that were selected initially, and some that also need an attribute adding that were not initially selected.

Any help with this is appreciated – as deleting the products does not seem like the best approach to this. Especially as lots of other things are associated to the products.

Best Answer

Here is what seams to work for me for to remove an attribute from the configurable product.
This is the scenario.
All the configurable products were created wrong with the attribute brand as a configurable attribute for about 50 configurable products having about 200 simple associated products.
All the simple products associated to a configurable attribute have the same brand. The idea is to remove brand from configurable attributes and assign it as a simple attribute to the configurable product with the value of one of the simple products.
Here is the code that does this. The code is ran one time only. It can be added in an upgrade script or a simple php file.

<?php
//==>this is required only if you use a simple php file
error_reporting(E_ALL | E_STRICT);
$mageFilename = 'app/Mage.php';
require_once $mageFilename;
Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
umask(0);
Mage::app();
//<==

$brand = 'brand';
//get the attribute instance
$brandAttribute = Mage::getModel('eav/config')->getAttribute('catalog_product', $brand);
//if this attribute exists
if ($brandAttribute->getId()){
    //make the attribute apply to al types of products in case it's not
    $brandAttribute->setApplyTo(null);
    $brandAttribute->save();
    $resource = Mage::getSingleton('core/resource');
    //get an object with access to direct queries
    $connection = $resource->getConnection('core_write');
    //get all configurable products - you can specify additional filters here
    $collection = Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToFilter('type_id', 'configurable');
    foreach ($collection as $product){
        //the configurable attributes are stored in the table 'catalog_product_super_attribute'
        //remove the attribute references from that table. 
        //The constraints will take care of the cleanup.
        $q = "DELETE FROM {$resource->getTableName('catalog_product_super_attribute')}
            WHERE attribute_id = {$brandAttribute->getId()} AND product_id = {$product->getId()}";
        $connection->query($q);
        //get the simple products in the configurable product
        $usedProducts =  $product->getTypeInstance(true)->getUsedProducts(null, $product);
        foreach ($usedProducts as $p){
            //identify the first simple product that has a value for brand 
            //set that value to the configurable product.
            if ($brandValue = $p->getData($brand)){
                Mage::getSingleton('catalog/product_action')
                    ->updateAttributes(array($product->getId()), array($brand=>$brandValue), 0);
                break;
            }
        }
    }
}

For the numbers listed above, this took about 15 seconds to run on my local machine (not a powerful one). I'm sure that this can be optimized. Most probably there is no need to get all simple products of a configurable product to get the brand value, but I didn't bother.