Question

I use the following script (inside a controller - action for now) for duplicating a product programatically.

public function createAction(){
    $data = $this->getRequest()->getParams();

    $product = Mage::getModel('catalog/product');
    $_product = $product->load($data['prod_id']);

    $clone = $_product->duplicate();
    $clone->setSku($data['dup_prod_sku']);
    // $clone->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);

    $clone->setPrice($data['dup_prod_price']);
    $clone->setSpecialPrice($data['dup_prod_sp_price']);
    $manage_stock = $data['dup_manage_stock'];
    $qty = ($data['dup_prod_stock'] == "") ? 0 : trim($data['dup_prod_stock']);
    $is_in_stock = $data['dup_is_in_stock'];
    if($manage_stock == 1){
        $stockArray = array(
                        'use_config_manage_stock' => 0,
                        'manage_stock' => 1,
                        'qty' => $qty,
                        'is_in_stock' => $is_in_stock,
                    );
    } else{
        $stockArray = array(
                        'use_config_manage_stock' => 0,
                        'manage_stock' => 0,
                    );
    }
    $clone->setStatus(1);
    $_idArray = Mage::helper('marketplace/vendor')->getVendorIdFromUserId();
    $_vendor = Mage::getModel('marketplace/vendorcode')->getCollection()
                            ->addFieldToSelect('attr_opt_id')
                            ->addFieldToFilter('vend_user_id', array('eq' => $_idArray['user_id']))
                            ->getFirstItem();
    $clone->setVendor($_vendor->getAttrOptId());
    $clone->setTaxClassId(4);
    $image_url = $this->getBaseImagePath($_product->getImage());
    $clone->setMediaGallery(array());
    $clone->setStockData($stockArray);
    try{
        $clone->getResource()->save($clone);
        $new_product = $product->load($clone->getId());
        $new_product->addImageToMediaGallery($image_url, array ('image', 'small_image', 'thumbnail'), false, false);
        $new_product->save();
        $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($clone->getId());
        foreach($stockArray as $key => $val){
            $stockItem->setData($key, $val);
        }
        $stockItem->save();
    } catch(Exception $e){
        Mage::log($e->getMessage());
    }
    $this->_redirect('*/*/productgrid');
}

This works well and the product gets duplicated with supplied SKU and overwritten prices from a form.

  • I can see the product in product grid in admin panel.
  • Visibility is set to Catalog, Search
  • Product is in stock
  • Enabled and tagged to correct category and website.

But still I cant get it to display in the category page in the frontend, whereas I can see the products duplicated from admin panel without any problem.

Moreover If I try to reindex, Product Flat Data isn't getting reindexed and is throwing SQL foreign key constraint error.

NOTE: Vendor is a custom attribute

Was it helpful?

Solution

It seems that some reference to a same object in the cloned one remains and cause the error.

Removing $clone->setStockData($stockArray) seems to solve the issue.

OTHER TIPS

I believe the simplest way to do this is to use the product's "duplicate" method. You'll have to reload the duplicated product, should you need then to change any of it's properties and save again:

// assume $product is a loaded product to duplicate
$duplicated = $product->duplicate();
// re-load the duplicated product to set it's SKU
$duplicated = $duplicated->load( $duplicated->getId() );
$duplicated->setSku( 'newsku' );
$duplicated->save();

This is what Magento does itself, when "duplicate" button is pressed in the Admin.

Just wanted to add this to Dmitri's correct answer- if you encounter this error "...Argument 3 passed to Mage_Catalog_Model_Resource_Abstract::_canUpdateAttribute()..." after setting the SKU and saving the duplicated product, it means that you need to set store scope.

Something like this- Mage::app()->setCurrentStore(// store id here);

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top