Reputation: 55
I have created a script in magento which create the bundle product and it is working fine. But i want to also update the created bundle product with new products of selection. Here it is my code and it is not working:
public function updateBundleProduct($pro_id,$cPrdcts){ $bundleProduct = Mage::getModel('catalog/product'); $bundleProduct->load($pro_id); $bundleProduct->setName('test product bundle bundlea'); $bundleSelections = array(); $bundleSelections = array( '0' => array( //option ID '0' => array( 'product_id' => '70', 'delete' => '', 'selection_price_value' => '10', 'selection_price_type' => 0, 'selection_qty' => 1, 'selection_can_change_qty' => 0, 'position' => 0, 'is_default' => 1, 'selection_id' => 71, 'option_id' => 14 ), '1' => array( 'product_id' => '84', 'delete' => '', 'selection_price_value' => '10', 'selection_price_type' => 0, 'selection_qty' => 1, 'selection_can_change_qty' => 0, 'position' => 0, 'is_default' => 1, 'selection_id' => 72, 'option_id' => 14 ) ) //get all selected products list and data ); $bundleOptions = array(); $bundleOptions = array( '0' => array( 'title' => 'All Items2', 'option_id' => 14, 'delete' => '', 'type' => 'multi', 'required' => '1', 'position' => '1' ) ); $bundleProduct->setData('_edit_mode', true); //flags for saving custom options/selections $bundleProduct->setCanSaveCustomOptions(true); $bundleProduct->setCanSaveBundleSelections(true); $bundleProduct->setAffectBundleProductSelections(true); //registering a product because of Mage_Bundle_Model_Selection::_beforeSave Mage::register('product', $bundleProduct); //setting the bundle options and selection data $bundleProduct->setBundleOptionsData($bundleOptions); $bundleProduct->setBundleSelectionsData($bundleSelections); // echo ''.print_r($bundleProduct,true).''; exit; $bundleProduct->save(); }
But instead of adding the product items it is deleted my previous options.
Upvotes: 3
Views: 2943
Reputation: 1872
Researching this for some time, I found that it was certainly common to build some arrays of product info and "manually build" the bundle product from these arrays, just like you do.
It was surprising, and seems unsophisticated, so it was time to check how Magento handles updating when using the standard Magento Admin Panel. And fact is, Magento actually uses the same technique of building up an array of data. You can edit a bundle product, fire up your Web console, and take a look at the data POSTed in when you save it.
Magento bundle products consist of groups, called options, that contain products, called selections.
To update some bundle product options with new selections, you could create an array like this:
$selectionData = array(
//'selection_id' => 'not set, so Magento will create a new one',
'option_id' => $option->getId(),
'product_id' => $product->getId(),
'delete' => '',
'selection_price_value' => '0.00',
'selection_price_type' => '0',
'selection_qty' => '1.0000',
'selection_can_change_qty' => '1',
'position' => '0',
);
The array structure is a copy of what is POSTed when updating a bundle product in Magento Admin Panel.
You can then use that data to build a new selection, as done in app/code/core/Mage/Bundle/Model/Product/Type.php
$resource = Mage::getResourceModel('bundle/bundle');
$bundleProduct = YOUR_BUNDLE_PRODUCT;
// app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
$optionCollection = $bundleProduct->getTypeInstance(true)->getOptionsCollection($bundleProduct);
$selectionCollection = $bundleProduct->getTypeInstance(true)->getSelectionsCollection(
$bundleProduct->getTypeInstance(true)->getOptionsIds($bundleProduct),
$bundleProduct
);
$options = $optionCollection->appendSelections($selectionCollection);
// needed because of app/code/core/Mage/Bundle/Model/Selection.php:73
Mage::register('product', $bundleProduct);
// process each option
foreach ($options as $option) {
$selections = $option->getSelections();
// process each selection
foreach ($selections as $selection) {
$usedProductIds = array();
$productCollection = YOUR_PRODUCT_COLLECTION;
foreach ($yourProductCollection as $product) {
$selectionData = array(
//'selection_id' => 'not set, so Magento will create a new one',
'option_id' => $option->getId(),
'product_id' => $product->getId(),
'delete' => '',
'selection_price_value' => '0.00',
'selection_price_type' => '0',
'selection_qty' => '1.0000',
'selection_can_change_qty' => '1',
'position' => '0',
);
// app/code/core/Mage/Bundle/Model/Product/Type.php:315
$selectionModel = Mage::getModel('bundle/selection')
->setData($selectionData)
->setOptionId($option->getId())
->setParentProductId($bundleProduct->getId());
$selectionModel->isDeleted((bool)$selectionData['delete']);
$selectionModel->save();
$selectionData['selection_id'] = $selectionModel->getSelectionId();
if ($selectionModel->getSelectionId()) {
$excludeSelectionIds[] = $selectionModel->getSelectionId();
$usedProductIds[] = $selectionModel->getProductId();
}
}
$resource->dropAllUnneededSelections($bundleProduct->getId(), $excludeSelectionIds);
$resource->saveProductRelations($bundleProduct->getId(), array_unique($usedProductIds));
}
}
Mage::unregister('product');
It is very possible to adapt this to add bundle options as well. I recommend taking a look in the files mentioned in the comments above.
Upvotes: 2