Programmatically create bundle products in Magento

bundle-featured

If this was a series of articles, this would be the third one. If you previously read my articles on simple and configurable product creation in Magento, you already know the basics.

In this article we’ll expand our knowledge and learn how to create a bundle of products programmatically in Magento.

A bundle of products would be something you’d want to sell in batch. It might be easier to understand what a bundle product is in Magneto from the picture. We can take an example from Magento’s sample products.

Camera Travel Set.
bundle-sample1

We can see that this products has options. Each custom option’s value corresponds to one simple product that’s associated with the bundle.

For example, we have Camera option and Madison LX2200 and Madison RX3400 as it’s values. Each one of those cameras is a simple product (called ‘selection‘ in admin).

Now that we have gone through the basics, we’ll create the code necessary to create a bundle product with two options – each one containing two values to represent simple products.

    $bundleProduct = Mage::getModel('catalog/product');
    $bundleProduct
    ->setStoreId(Mage_Core_Model_App::ADMIN_STORE_ID) //you can set data in store scope
        ->setWebsiteIds(array(1)) //website ID the product is assigned to, as an array
        ->setAttributeSetId(20) //ID of a attribute set named 'default'
        ->setTypeId('bundle') //product type
        ->setCreatedAt(strtotime('now')) //product creation time
//    ->setUpdatedAt(strtotime('now')) //product update time
        ->setSkuType(0) //SKU type (0 - dynamic, 1 - fixed)
        ->setSku('bundlexx1') //SKU
        ->setName('test bundle product96') //product name
        ->setWeightType(0) //weight type (0 - dynamic, 1 - fixed)
//        ->setWeight(4.0000)
        ->setShipmentType(0) //shipment type (0 - together, 1 - separately)
        ->setStatus(1) //product status (1 - enabled, 2 - disabled)
        ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) //catalog and search visibility
        ->setManufacturer(28) //manufacturer id
        ->setColor(24)
        ->setNewsFromDate('06/26/2014') //product set as new from
        ->setNewsToDate('06/30/2014') //product set as new to
        ->setCountryOfManufacture('AF') //country of manufacture (2-letter country code)
        ->setPriceType(0) //price type (0 - dynamic, 1 - fixed)
        ->setPriceView(0) //price view (0 - price range, 1 - as low as)
        ->setSpecialPrice(00.44) //special price in form 11.22
        ->setSpecialFromDate('06/1/2014') //special price from (MM-DD-YYYY)
        ->setSpecialToDate('06/30/2014') //special price to (MM-DD-YYYY)
        /*only available if price type is 'fixed'*/
//        ->setPrice(11.22) //price, works only if price type is fixed
//        ->setCost(22.33) //price in form 11.22
//        ->setMsrpEnabled(1) //enable MAP
//        ->setMsrpDisplayActualPriceType(1) //display actual price (1 - on gesture, 2 - in cart, 3 - before order confirmation, 4 - use config)
//        ->setMsrp(99.99) //Manufacturer's Suggested Retail Price
//        ->setTaxClassId(4) //tax class (0 - none, 1 - default, 2 - taxable, 4 - shipping)
        /*only available if price type is 'fixed'*/
        ->setMetaTitle('test meta title 2')
        ->setMetaKeyword('test meta keyword 2')
        ->setMetaDescription('test meta description 2')
        ->setDescription('This is a long description')
        ->setShortDescription('This is a short description')
        ->setMediaGallery(array('images' => array(), 'values' => array())) //media gallery initialization
        ->setStockData(array(
                'use_config_manage_stock' => 1, //'Use config settings' checkbox
                'manage_stock' => 1, //manage stock
                'is_in_stock' => 1, //Stock Availability
            )
        )
        ->setCategoryIds(array(4, 10)); //assign product to categories
 
    $bundleOptions = array();
    $bundleOptions = array(
        '0' => array( //option id (0, 1, 2, etc)
            'title' => 'item01', //option title
            'option_id' => '',
            'delete' => '',
            'type' => 'select', //option type
            'required' => '1', //is option required
            'position' => '1' //option position
        ),
        '1' => array(
            'title' => 'item02',
            'option_id' => '',
            'delete' => '',
            'type' => 'multi',
            'required' => '1',
            'position' => '1'
        )
    );
 
    $bundleSelections = array();
    $bundleSelections = array(
        '0' => array( //option ID
            '0' => array( //selection ID of the option (first product under this option (option ID) would have ID of 0, second an ID of 1, etc)
                'product_id' => '554', //if of a product in selection
                'delete' => '',
                'selection_price_value' => '10',
                'selection_price_type' => 0,
                'selection_qty' => 1,
                'selection_can_change_qty' => 0,
                'position' => 0,
                'is_default' => 1
            ),
 
            '1' => array(
                'product_id' => '553',
                'delete' => '',
                'selection_price_value' => '10',
                'selection_price_type' => 0,
                'selection_qty' => 1,
                'selection_can_change_qty' => 0,
                'position' => 0,
                'is_default' => 1
            )
        ),
        '1' => array( //option ID
            '0' => array(
                'product_id' => '552',
                'delete' => '',
                'selection_price_value' => '10',
                'selection_price_type' => 0,
                'selection_qty' => 1,
                'selection_can_change_qty' => 0,
                'position' => 0,
                'is_default' => 1
            ),
 
            '1' => array(
                'product_id' => '551',
                'delete' => '',
                'selection_price_value' => '10',
                'selection_price_type' => 0,
                'selection_qty' => 1,
                'selection_can_change_qty' => 0,
                'position' => 0,
                'is_default' => 1
            )
        )
    );
    //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);
 
    $bundleProduct->save();
    echo 'success';
} catch (Exception $e) {
    Mage::log($e->getMessage());
    echo $e->getMessage();
}

You can find comments next to each line of code below. I tried to comment as much of the code as possible, so you have some helpful hints as to what each of the lines represents.

The end result

bundle-example-2
bundle-example

It’s important to master the concept of a bundle product before running the code above, otherwise, you’ll probably end up setting values the wrong way.

I assume you already know how to figure out which data you can set for a bundle product. (Hint: read the articles in the links above).

As always, I’m here for any questions you might have.


3 comments

    1. Through data installs, in an observer or just create a php file in the root of your install. There are many ways to execute this code.

  1. I am trying to update my bundle product with bundle items, and here is my code

    ini_set(‘auto_detect_line_endings’, TRUE);
    $magentoPath = getcwd();
    require_once ($magentoPath . ‘/includes/config.php’);
    require_once ($magentoPath . ‘/app/Mage.php’);
    Mage::app();

    //read the csv
    $bundleCsv = Mage::getBaseDir(‘var’).’/import/bundleImport.csv’;
    $rows = array_map(‘str_getcsv’, file($bundleCsv));
    $header = array_shift($rows);
    $csv = array();

    foreach ($rows as $row) {
    $csv[] = array_combine($header, $row);
    }

    Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

    echo Mage::app()->getStore()->getId(); exit;

    foreach( $csv as $key => $val ){
    if( !isset($val[‘sku’]) || empty($val[‘sku’]) || $val[‘sku’] == ” ){
    echo ‘Not Valid Sku’;
    continue;
    }

    $_product = Mage::getModel(‘catalog/product’)->loadByAttribute(‘sku’,$val[‘sku’]);

    $opt = $val[‘bundle_options’];
    $optArr = explode(‘:’, $opt);

    $bundleOptions = array();
    $bundleSelections = array();
    foreach ( $optArr as $key1 => $val1 ) {
    $valTemp = explode( ‘(‘, $val1 );
    $title = trim($valTemp[0]);
    $bundleSub[$key1] = array(
    ‘title’ => $title, // option title
    ‘option_id’ => $key1,
    ‘delete’ => ”,
    ‘type’ => ‘select’, // option type
    ‘required’ => ‘1’, // is option required
    ‘position’ => ‘1’ // option position
    );

    $skuStr = trim($valTemp[1]);
    $skuStrTemp = explode( ‘)’, $skuStr );
    $skuStr = trim($skuStrTemp[0]);

    $skuTemp = explode( ‘+’, $skuStr );

    foreach( $skuTemp as $key2 => $val2 ){
    $product = Mage::getModel(‘catalog/product’);
    $id = Mage::getModel(‘catalog/product’)->getResource()->getIdBySku($val2);

    if( $id ){
    $bundleSelectionsSub[$key2] = array ( // selection ID of the option (first product under this option (option ID) would have ID of 0, second an ID of 1, etc)
    ‘product_id’ => $id, // if of a product in selection
    ‘delete’ => ”,
    ‘selection_price_value’ => ’10’,
    ‘selection_price_type’ => 0,
    ‘selection_qty’ => 1,
    ‘selection_can_change_qty’ => 0,
    ‘position’ => 0,
    ‘is_default’ => 1
    );
    $product = null;
    }else{
    continue;
    }
    }
    $bundleSelections[$key1] = $bundleSelectionsSub;
    }

    $bundleOptions = $bundleSub;
    //echo ‘

    '; print_r($bundleOptions); exit;
        try{
    
            $_product->setCanSaveCustomOptions ( true );
            $_product->setCanSaveBundleSelections ( true );
            $_product->setAffectBundleProductSelections ( true );
    
            $_product->setBundleOptionsData ( $bundleOptions );
            $_product->setBundleSelectionsData ( $bundleSelections );
    
            $_product->save();
        }catch ( Exception $e ) {
            Mage::log ( $e->getMessage () );
            echo $e->getMessage ();
        }
    
        echo 1; exit;
        $_product = null;
    but I am getting error as 
    SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`aero_dev`.`catalog_product_bundle_option_value`, CONSTRAINT `FK_CAT_PRD_BNDL_OPT_VAL_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID` FOREIGN KEY (`option_id`) REFERENCES `catalog_product_bundle_option` (`opt), query was: INSERT INTO `catalog_product_bundle_option_value` (`option_id`, `store_id`, `title`) VALUES (?, ?, ?)
    
    can u help me to resolve this ?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.