Magento – Assign Configurable Product Images to Associated Products

catalogconfigurable-productimagemagento-1.7module

My store have around 20000 products and now i want to generate google feed with simple products but associated products don't have images, only configurable products have images. Now what i want is to associated configurable product image to its all associated product so when i generate feed associated products takes the image of its main configurable product.

I have try this by create a module but

<?php 
 class Ebiz_Assignimage_IndexController extends Mage_Core_Controller_Front_Action {        

    public function indexAction()
    {   

        $collectionConfigurable = Mage::getResourceModel('catalog/product_collection')
                                    ->addAttributeToFilter('type_id', array('eq' => 'configurable'));                                       

        //  echo '<pre>'; print_r($collectionConfigurable->getData()); die;
            foreach ($collectionConfigurable as $_configurableproduct) {
                $product = Mage::getModel('catalog/product')->load($_configurableproduct->getId()); 
                if($product->isSaleable()) {    

                    $childIds = Mage::getModel('catalog/product_type_configurable')->getChildrenIds($product->getId());
                    foreach($childIds[0] as $key=>$val) {
                        $associatedProduct = Mage::getModel('catalog/product') ->load($val);

                        $associatedProduct->setImage($product->getImage())                                              
                                        ->save();
                    //}             
                }           
            } 
        die;
    }
?>

This script is working but its taking too much time as there are large number of products
is there any better to do this.

Please let me know any better solution or any modification required in my current approch

Best Answer

I had the same issue and here is what I've used. It's a 'quick and dirty' script that works with the database directly, so back up you DB before trying it. Also add the table prefix if you have one.

$resource = Mage::getSingleton('core/resource');
$attributes = array('image', 'thumbnail', 'small_image');
$connection = $resource->getConnection('core_write');
$collection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect($attributes)
    ->addAttributeToFilter('type_id', 'configurable')
    ->setOrder('sku', 'ASC');

foreach($collection as $product){
    //$product->load($product->getId());//not sure if this is needed
    $simpleProductsIds = $product->getTypeInstance()->getUsedProductIds();
    $q = "SELECT * FROM catalog_product_entity_media_gallery WHERE entity_id = {$product->getId()}";
    $result = $connection->query($q)->fetchAll();
    foreach ($result as $row){
        $q = "SELECT * FROM catalog_product_entity_media_gallery_value where value_id = {$row['value_id']}";
        $valueResult = $connection->query($q)->fetchAll();
        foreach ($simpleProductsIds as $id){
            $q = "INSERT INTO catalog_product_entity_media_gallery SET
                attribute_id= {$row['attribute_id']},
                entity_id = {$id},
                value = '{$row['value']}'
            ";
            $connection->query($q);
            $lastInsert = $connection->lastInsertId();
            foreach ($valueResult as $val){
                $q = "INSERT INTO catalog_product_entity_media_gallery_value SET
                    value_id = {$lastInsert},
                    store_id = {$val['store_id']},
                    label = '{$val['label']}',
                    position = {$val['position']},
                    disabled = {$val['disabled']}
                ";
                $connection->query($q);
            }
        }
    }
    //update media images
    $data = array();
    foreach ($attributes as $attribute){
        $data[$attribute] = $product->getData($attribute);
    }
    Mage::getSingleton('catalog/product_action')
        ->updateAttributes($simpleProductsIds, $data, 0);
    echo "Done with product: ".$product->getId()."<br />";
}

It took about 20 seconds for 80 configurable products and about 400 simple products associated to configurable.
If you have 20k products I don't think it's a good idea to iterate the product collection like I did. You can use Mage::getSingleton('core/resource_iterator'). More about it here.