programmatically update bundle product magento? - php

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.

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.

Related

Magento - Custom Options are added for each storeview

I have the following problem:
I want to add custom options to my magento product programmatically.
This works so far, BUT the options are added multiple times, more accurate one time for each store view I have, but they are all visible in each storeview.
I only need ONE option for the Default View. Here is the code I use:
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', 1234);
if(!$product) {
$product = Mage::getModel('catalog/product');
} else {
$product = Mage::getModel('catalog/product')->load($product->getId());
}
$customOpt = array(
'is_delete' => 0,
'is_require' => true,
'title' => 'ProcessingImport',
'type' => 'drop_down',
'price_type' => 'fixed',
'price' => 0,
'sort_order' => 0,
'values' => array(
array(
'is_delete' => 0,
'title' => 'Import ' . rand(10, 100),
'price_type' => 'fixed',
'price' => 0,
'sku' => 'SKUImportOne',
'option_type_id' => -1
),
array(
'is_delete' => 0,
'title' => 'Import ' . rand(10, 100),
'price_type' => 'fixed',
'price' => 0,
'sku' => 'SKUImportTwo',
'option_type_id' => -1
)
),
);
$product->setCanSaveCustomOptions(true);
$product->setProductOptions(array($customOpt));
$product->save();
Does someone have any idea why it is added multiple times for each view?
Here is an image where you can see my problem:
Thanks in advance!
I found the solution in my code.
After the code posted above I have a loop, where I set several prices for different stores. And magento is so "smart" that it saves all options again for each store.
I placed the code-snipped AFTER this loop and the option is only created once.

Import product with attributes magento

im using an import script that import's simple and configurable product to magento from xml.
The problem is that, imported simple products are i magento but they don't have attributes values assigned.
Import via APIv2 is working well bu it is to slow, that why i need to do this on model.
my question is:
Is This (code below) correct ? Meybe you have better, different metod to assigne attribute value to product :-)
$product->setData('rozmiar',$Products['sizeId']);
$product->setData('kolor',$Products['colorId']);
my code:
$productCheck = Mage::getModel('catalog/product')->loadByAttribute('sku', $products['sku']);
if ($productCheck) {
$productCheck->delete();
//print_r('true !');
}
$color = attributeValueExists1('kolor',$Products['color']);
$size = attributeValueExists1('rozmiar',$Products['size']);
$product = Mage::getModel('catalog/product');
$product->setCreatedAt(strtotime('now'));
$product->setTypeId($products['type']);
$product->setTaxClassId(0);
$product->setWebsiteIds(array(1));
$product->setAttributeSetId($products['attrset']);
$product->setSku($products['sku']);
$product->setName($products['name']);
$product->setDescription($products['description']);
$product->setInDepth('');
$product->setPrice($products['price']);
$product->setShortDescription($products['description']);
$product->setWeight(0);
$product->setStatus(1);
$product->setVisibility(1);
//$product->setMetaDescription($products['name']);
//$product->setMetaTitle($products['name']);
//$product->setMetaKeywords($products['name']);
$product->setCategoryIds($products['categories']);
$product->setKolor($color);
$product->setRozmiar($size);
//$product->setData('rozmiar',$Products['size']);
//$product->setData('kolor',$Products['color']);
$product->setStockData(array(
'use_config_manage_stock' => 0,
'manage_stock'=>1,
'min_sale_qty'=>1,
//'max_sale_qty'=>2,
'is_in_stock' => 1,
'qty' => $products['qty']
)
);
$product->save();
Importing products via Soap APIv2 im using
$result = $this->client2->catalogProductCreate($this->session, $type, /*$attributeSet['set_id']*/ '4', $kod, array(
'categories' => $kategorie, // array !!!!
'websites' => array(1),
'name' => $nazwa,
'description' => $opis,
'short_description' => $opis,
'weight' => '1',
'status' => '1',
'url_key' => $nazwa,
'url_path' => $nazwa,
'visibility' => '1',
'price' => $cena,
'tax_class_id' => 1,
'meta_title' => '',
'meta_keyword' => '',
'meta_description' => '',
'stock_data' => array( 'manage_stock' => '1',
'manage_stockSpecified' => False,
'is_in_stock' => '1',
'is_in_StockSpecified' => False,
'qty' => $ilosc
),
'additional_attributes' => $additionalattr
));
return $result;
Is additional_attributes different from $product->setData('rozmiar',$Products['sizeID']); ?
If it's not the same how can i add additional_attributes when importing products via catalog/product model ?
First you need to assign corresponding attributes to products. Then after you can use import script to save those attributes value to products.

Unable to create configurable product in Magento

I am struggling to create Configurable product using simple PHP script, I would appreciate if you can help me out,
$sku_array = array(substr(sha1(mt_rand()), 0, 5),
substr(sha1(mt_rand()), 0, 5),
substr(sha1(mt_rand()), 0, 5),
substr(sha1(mt_rand()), 0, 5),
substr(sha1(mt_rand()), 0, 5),
substr(sha1(mt_rand()), 0, 5));
$color_array = array('Black','Blue','Green','Maroon','Navy','Red','White');
$size_array = array('S','M','L','XL','2XL');
$style_array = array('Men','Unisex','Women');
$price_array = array('8.90','9.00','12.30','14.25','15.99','11.30','4.45');
$associated_skus = array();
for($i=0; $i < 4; $i++) {
$productData = array(
'categories'=> array(3),
'name' => 'Name of product #' . ($i+1),
'description' => 'Description of product #' . ($i+1),
'short_description' => 'Short description of product #' . ($i+1),
'websites' => array(1), // Id or code of website
'status' => 1, // 1 = Enabled, 2 = Disabled
'visibility' => 1, // 1 = Not visible, 2 = Catalog, 3 = Search, 4 = Catalog/Search
'tax_class_id' => 0, // 0 None; 2: Taxable Good; 4: Shipping
'weight' => 0,
'stock_data' => array(
'use_config_manage_stock' => 0,
'manage_stock' => 0, // We do not manage stock, for example
'qty' => '100',
'is_in_stock' => 1
),
'price' => array_rand(array_flip($price_array),1), // Same price than configurable product, no price change
'additional_attributes' => array(
'single_data' => array(
array(
'key' => 'style',
'value' => array_rand(array_flip($style_array),1), // Id or label of style, attribute that will be used to configure product (Men,Unisex,Women)
),
array(
'key' => 'color',
'value' => array_rand(array_flip($color_array),1), // Id or label of color, attribute that will be used to configure product
),
array(
'key' => 'size',
'value' => array_rand(array_flip($size_array),1), // Id or label of size, attribute that will be used to configure product
),
),
),
);
// Creation of simple products
$proxy->catalogProductCreate($sessionId, 'simple', '9', 'SKU-' . $sku_array[$i], $productData);
$associated_skus[] = 'SKU-' . $sku_array[$i];
}
echo "<pre>";
echo "Ass Products";
print_r($associated_skus);
echo "<br />";
/**
* Configurable product
*/
$productData = array(
'categories'=> array(3),
'name' => 'Configurable product',
'description' => 'Description of configurable product',
'short_description' => 'Short description of configurable product',
'websites' => array(1), // Id or code of website
'status' => 1, // 1 = Enabled, 2 = Disabled
'visibility' => 4, // 1 = Not visible, 2 = Catalog, 3 = Search, 4 = Catalog/Search
'tax_class_id' => 2, // Default VAT
'weight' => 0,
'stock_data' => array(
'use_config_manage_stock' => 0,
'manage_stock' => 0, // We do not manage stock, for example
),
'price' => 9.90,
'associated_skus' => array($associated_skus), // Simple products to associate
'price_changes' => array(),
);
$result = $proxy->catalogProductCreate($sessionId, 'configurable', '9', 'SKU-' . $sku_array[5], $productData);
echo "<pre>";
print_r($result);
Basically; simple products including configurable product is visible in admin backend but on the front side it does not display the product, and when tried to edit Configurable product skus of associated product also missing.
Default Magento API does not allow to associate products to configurable products. You can customize the API to achieve this. Follow this blog - http://www.bubblecode.net/en/2012/04/20/magento-api-associate-simple-products-to-configurable-or-grouped-product/
If you do not wish to download the plugin, then simply refer the code from below files and update your API accordingly.
associateProducts() - https://github.com/jreinke/magento-improve-api/blob/master/app/code/community/Bubble/Api/Helper/Catalog/Product.php
_prepareDataForSave() - https:// github.com/jreinke/magento-improve-api/blob/master/app/code/community/Bubble/Api/Model/Catalog/Product/Api.php
Hope this helps.

Bigcommmere Api create product with images link

I want to create product in bigcommerce store using bigcommerce Api. Following code works fine to create product in Bc store
$product = array('name' => 'ABC Blocks', 'type' => 'physical', 'price' => '19.99', 'weight' => 2.3, 'categories' => array(26), 'availability' => 'available', 'is_visible' => true));
Bigcommerce_Api::createProduct($product);
How can I pass images url ? I am trying following codes but unable to create
$image = array('image_file'=>'https://developer.bigcommerce.com/assets/hero-image.png','is_thumbnail'=>false,'sort_order'=>1,'description'=>'');
$product = array('name' => 'ABC Blocks', 'type' => 'physical', 'price' => '19.99', 'weight' => 2.3, 'categories' => array(26), 'availability' => 'available', 'is_visible' => true,'images' => array('image_file' => $image));
Bigcommerce_Api::createProduct($product);
Any help will be greatly appreciated!!thanks
Here's an example structure from the api about how primary image data should look.
"primary_image": {
"id": 247,
"zoom_url": "https://cdn.url.path/bcapp/et7xe3pz/products/32/images/247/in_123__14581.1393831046.1280.1280.jpg?c=1",
"thumbnail_url": "https://cdn.url.path/bcapp/et7xe3pz/products/32/images/247/in_123__14581.1393831046.220.290.jpg?c=1",
"standard_url": "https://cdn.url.path/bcapp/et7xe3pz/products/32/images/247/in_123__14581.1393831046.386.513.jpg?c=1",
"tiny_url": "https://cdn.url.path/bcapp/et7xe3pz/products/32/images/247/in_123__14581.1393831046.44.58.jpg?c=1"
}
Use this to figure out your array structure.

Programatically added bundle product isn't showing up in frontend

I am trying to insert bundled products to the Magento database from a PHP script. The version in question is Community 1.5.1.0.
I tried the method described in the question "Programmatically add Bundle Products in Magento, using the SKU / ID of Simple Items". The inserted products show up nicely in the administration section -- I can edit them, add new options and selections etc. However, they are not showing up at all in the Magento frontend no matter what I try - e.g. rebuilding indexes or re-saving them from the back-end. Adding bundles through the administration interface works fine.
After some digging through the database, I noticed there are no necessary entries in the catalog_product_index_price and catalog_product_index_price_bundle_idx tables when using my script, while adding the bundle through the back-end updates the indexes normally. Re-indexing simply ignores the added bundle product as far as those tables are concerned.
I dug through the Magento source files and can't find any hints on what I'm doing wrong. All caches are disabled, selections are in stock, and I tried to include all data I dug up while studying the POST request Magento sends while inserting the product in the back-end.
Here's the complete script I use for testing, along with some desperate attempts commented out at the bottom:
$magentoPath = '/home/nikola/bin/magento-1.5/';
require_once($magentoPath . 'includes/config.php');
require_once($magentoPath . 'app/Mage.php');
$storeID = 1;
$websiteIDs = array(1);
$mageObj = Mage::app()->setCurrentStore($storeID);
$product = Mage::getModel('catalog/product');
$cats = array("210");
$p = array(
'sku_type' => 0,
'sku' => 687,
'name' => "BarProduct",
'description' => 'Foo',
'short_description' => 'Bar',
'type_id' => 'bundle',
'attribute_set_id' => 4,
'weight_type' => 0,
'visibility' => 4,
'price_type' => 0,
'price_view' => 0,
'status' => 1,
'created_at' => strtotime('now'),
'category_ids' => $cats,
'store_id' => $storeID,
'website_ids' => $websiteIDs
);
$product->setData($p);
$product->setCanSaveBundleSelections(true);
$product->setCanSaveCustomOptions(true);
Mage::register('product', $product);
Mage::register('current_product', $product);
$optionRawData = array();
$selectionRawData = array();
$optionRawData[0] = array(
'required' => 1,
'option_id' => '',
'position' => 0,
'type' => 'select',
'title' => 'FooOption',
'default_title' => 'FooOption',
'delete' => ''
);
$selectionRawData[0] = array();
$selectionRawData[0][] = array(
'product_id' => 1810,
'position' => 0,
'is_default' => true,
'selection_id' => '',
'option_id' => '',
'selection_price_type' => 0,
'selection_price_value' => 0.0,
'selection_qty' => 1,
'selection_can_change_qty' => 1,
'delete' => ''
);
$product->setBundleOptionsData($optionRawData);
$product->setBundleSelectionsData($selectionRawData);
$product->save();
/*
$stockItem = Mage::getModel('cataloginventory/stock_item');
$stockItem->loadByProduct($product->getId());
if (!$stockItem->getId()) {
$stockItem->setProductId($product->getId())->setStockId(1);
}
$stockItem->setData('is_in_stock', 1);
$stockItem->save();
$pi = Mage::getSingleton('bundle/price_index');
$pi->addPriceIndexToProduct($product);
$pi->save();
*/
?>
Please try using the following code & see what happens:-
<?php
$magentoPath = '/home/nikola/bin/magento-1.5/';
require_once($magentoPath . 'includes/config.php');
require_once($magentoPath . 'app/Mage.php');
$storeID = 1;
$websiteIDs = array(1);
$cats = array("210");
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product = Mage::getModel('catalog/product');
$p = array(
'sku_type' => 0,
'sku' => '687',
'name' => "BarProduct",
'description' => 'Foo',
'short_description' => 'Bar',
'type_id' => 'bundle',
'attribute_set_id' => 4,
'weight_type' => 0,
'visibility' => 4,
'price_type' => 0,
'price_view' => 0,
'status' => 1,
'created_at' => strtotime('now'),
'category_ids' => $cats,
'store_id' => $storeID,
'website_ids' => $websiteIDs
);
$product->setData($p);
Mage::register('product', $product);
Mage::register('current_product', $product);
/**
* Section of Bundle Options
*
* Required Properties of Bundle Options are:-
* 1. title
* 2. option_id
* 3. delete
* 4. type
* 5. required
* 6. position
* 7. default_title
*/
$optionRawData = array();
$optionRawData[0] = array(
'required' => 1,
'option_id' => '',
'position' => 0,
'type' => 'select',
'title' => 'FooOption',
'default_title' => 'FooOption',
'delete' => '',
);
/**
* Section of Bundle Selections
*
* Required Properties of Bundle Selections
* 1. selection_id
* 2. option_id
* 3. product_id
* 4. delete
* 5. selection_price_value
* 6. selection_price_type
* 7. selection_qty
* 8. selection_can_change_qty
* 9. position
* 10. is_default
*/
$selectionRawData = array();
$selectionRawData[0] = array();
$selectionRawData[0][] = array(
'product_id' => 1810,
'selection_qty' => 1,
'selection_can_change_qty' => 1,
'position' => 0,
'is_default' => 1,
'selection_id' => '',
'selection_price_type' => 0,
'selection_price_value' => 0.0,
'option_id' => '',
'delete' => ''
);
$product->setCanSaveConfigurableAttributes(false);
$product->setCanSaveCustomOptions(true);
// Set the Bundle Options & Selection Data
$product->setBundleOptionsData($optionRawData);
$product->setBundleSelectionsData($selectionRawData);
$product->setCanSaveBundleSelections(true);
$product->setAffectBundleProductSelections(true);
$product->save();
?>
Hope it helps.
I have tried using your code, but it did not seem to work in Magento 1.7.0.2. Apparently the product could not be saved.
What I did was added the following lines:
Mage::register('product', $product);
Mage::register('current_product', $product);
$product->setCanSaveConfigurableAttributes(false);
$product->setCanSaveCustomOptions(true);
Just before the lines:
// Set the Bundle Options & Selection Data
$product->setBundleOptionsData($optionRawData);
$product->setBundleSelectionsData($selectionRawData);
$product->setCanSaveBundleSelections(true);
$product->setAffectBundleProductSelections(true);
$product->save();
This seemed to fix the issue of not being able to save the file.

Categories