3

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

  • 2
    Can you give the exact foreign key error you're getting – Luke Collymore Nov 8 '14 at 12:57
  • 1
    I am not able to check the duplicate() method at the moment but I guess that some reference to a same object in the cloned one remains and could cause the error. For example the stock item. Hope helps. – Alessandro Ronchi Nov 8 '14 at 14:52
  • @AlessandroRonchi, exactly! I've set stock data twice for the same product which led to the error. I removed $clone->setStockData($stockArray); now it's working fine. pls add the comment as answer. – Shathish Nov 10 '14 at 5:09
1

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.

6

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.

0

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);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.