Skip to content


Adding Configurable Products to Magento with Core API

Overview

The documentation regarding Magento’s Core API is vague at best. They fail to include any relevant required attributes for each of the tasks you may find yourself needing to accomplish. For the novice developer this can be quite cumbersome.

The Problem

Recently I found myself tasked with porting 100,000 products out of a custom ecommerce solution into Magento. The products in question contain a multitude of different configurations spanning most of Magento’s product feature set. As I began the process of writing up a solution via the API I quickly discovered the lack of support for configurable products. Configurable products allow you to group like products, by certain attributes such as Color, Size etc., on a single product page.

I hope that through my experience I am able to help those of you searching for how to add configurable products to Magento using their core API.

The Solution

Step 1 – Patch Core API

Getting the Magento Core API will require a few modifications to the Mage/Catalog/Model/Product/Api.php file.

Find the method in that class called _prepareDataForSave and add the following code to the bottom of that method.

/*
 * Check for configurable products array passed through API Call
 */
if(isset($productData['configurable_products_data']) && is_array($productData['configurable_products_data'])) {
	$product->setConfigurableProductsData($productData['configurable_products_data']);        	
}
 
if(isset($productData['configurable_attributes_data']) && is_array($productData['configurable_attributes_data'])) {
	foreach($productData['configurable_attributes_data'] as $key => $data) {
		//Check to see if these values exist, otherwise try and populate from existing values
		$data['label'] 			=	(!empty($data['label'])) 			? $data['label'] 			: $product->getResource()->getAttribute($data['attribute_code'])->getStoreLabel();
		$data['frontend_label'] =	(!empty($data['frontend_label'])) 	? $data['frontend_label'] 	: $product->getResource()->getAttribute($data['attribute_code'])->getFrontendLabel();
		$productData['configurable_attributes_data'][$key] = $data;
	}
	$product->setConfigurableAttributesData($productData['configurable_attributes_data']);
	$product->setCanSaveConfigurableAttributes(1);
}

You will notice that in the ‘configurable_attributes_data’ block that there is a check to see if ‘label’ and ‘frontend_label’ is passed with the API call. Some of you may know this label, and some may not. At the time of this writing, Magento does not pass the Labels with an Attribute API call, thus we will add those required values in programmatically here if they do not exist.

You have now completed patching the API to accept configurable product requests, let’s move on to usage.

Step 2 – Creating the API Call

In order to create a configurable product, we first need to create the simple products. I

$newProductData = array(
    'name'             		=> 'Product Name 1',
    'websites'          		=> array(1),
    'description'       		=> '',		
    'price'             		=> 9.99,
    'category_ids'		=> '',
    'visibility'			=> 4,
    'status'				=> 1,
    'weight'				=> 1,
    'tax_class_id'			=> 2,
);
$productOne = $this->doProductMigration('simple', 1, 'SKU_VALUE1', $newProductData);
$newProductData = array(
    'name'             		=> 'Product Name 2',
    'websites'          		=> array(1),
    'description'       		=> '',		
    'price'             		=> 9.99,
    'category_ids'		=> '',
    'visibility'			=> 4,
    'status'				=> 1,
    'weight'				=> 1,
    'tax_class_id'			=> 2,
);
$productTwo = $this->doProductMigration('simple', 1, 'SKU_VALUE2', $newProductData);
 
//Create the configurable products data
$$configurableProductsData = array(
	$productOne['product_id'] => array(
		'attribute_id'		=> 10, //The attribute id
		'label'				=> 'Red',
		'value_index'		=> 100, //The option id
		'is_percent'		=> 0,
		'pricing_value'		=> ''
	),
	$productTwo['product_id'] => array(
		'attribute_id'		=> 10, //The attribute id
		'label'				=> 'Blue',
		'value_index'		=> 101, //The option id 	
		'is_percent'		=> 0,
		'pricing_value'		=> ''	
	)
);
 
//Create the configurable attributes data
$configurableAttributesData = array(
	'0'	=> array(
		'id' 				=> NULL,
		'label'			=> '', //optional, will be replaced by the modified api.php
		'position'			=> NULL,
		'values'			=> array(
			0 => array(
				'attribute_id'		=> 10, //The attribute id
				'label'				=> 'Red',
				'value_index'		=> 100, //The option id
				'is_percent'		=> 0,
				'pricing_value'		=> ''				
			),
			1 => array(
				'attribute_id'		=> 10, //The attribute id
				'label'				=> 'Blue',
				'value_index'		=> 101, //The option id 	
				'is_percent'		=> 0,
				'pricing_value'		=> ''							
			)
		),
		'attribute_id' 		=> 10, //get this value from attributes api call
		'attribute_code'	        => 'color', //get this value from attributes api call
		'frontend_label'	        => '', //optional, will be replaced by the modifed api.php
		'html_id'			=> 'config_super_product__attribute_0'
	)
);
 
//add configurable product
$newProductData = array(
    'name'              			        => 'Product Group Name',
    'websites'          			        => array(1), 
    'description'       			        => 'Group description',		
	'category_ids'				=> array(1),
	'visibility'					=> 4,
	'status'					=> 1,
	'weight'					=> 0,
	'price'             			        => 9.99,				
	'tax_class_id'				=> 2,
	'weight'					=> 0,
	'configurable_products_data' 	=> $configurableProductsData,
	'configurable_attributes_data' 	=> $configurableAttributesData		
);	
$result = $this->doProductMigration('configurable', 1, "GROUP-SKU", $newProductData);
 
[Edited Added doProductMigration method example]
//Example of the doProductMigration method.  It's simply a an API call
protected function doProductMigration($productType, $setId, $sku, $productData)
{
	$result = array();
	try {
		$this->_soapClient->call($this->_soapSessionId, 'product.create', array($productType, $setId, $sku, $productData));
		$result = $this->_soapClient->call($this->_soapSessionId, 'product.info', $sku); 
	} catch(Exception $e) {
		$this->_logError($e);
                $result = false;
	}		
	return $result; 
}
 
//Now do other useful tasks.. such as Add Images

Conclusion

Although the array structures are somewhat involved, I have had great success utilizing this method in order to get these products into the Magento.

I would normally disagree with modifying core code in order to add functionality, a nice todo would be to extend the API class to include the necessary functionality. Due to time constraints that was not a route I decided to take.

Happy Coding!

Posted in Magento.

10 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Hi,

    Thanks for the help, we had a similar problem here, we are creating a conection between our ERP and Magento, your post will be very useful. I have a question, that method doProductMigration isnt from the API, what you do there? A normal api create produt call ?

    Best Reguards
    S R Neto

  2. Carson said

    Hi, it seems that the function doProductMigration() is not defined. Any clues on it?

    Thanks

  3. A question or two if you don’t mind – in the API wouldn’t you have to put in the configurable attributes before you set the configurable product data? (Switch the order of the two API methods?)

    Also, does this work with multi-configurable products? While I have gotten the first part to work properly – that is, selecting 3 attributes to be configurable on the parent product, it seems the configurable_products_data dictionary/arrays only allow for a single data point for each product, instead of multiples.

    Thanks!

    Dave

  4. Steve Rhoades said

    The doProductMigration function is where you could handle your API call, for brevity I included examples of what variables you might pass to such a call not the actual implementation. I am more than happy to put it in there if its helpful.

    Cheers!

  5. Sebastiao Rocha said

    Thank you for the answer. I got my code working for new inserts but now a have a problem updating the configurable product. Im having a error about integrity violation even passing the product_id in the array data:

    Uncaught SoapFault exception: [1] SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`magento`.`catalog_product_super_link`, CONSTRAINT `catalog_product_super_link_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE )

    It works fine for the simple product though. Is there any change i have to do on the update part for get that working?

  6. Sebastiao Rocha said

    Sry to botter you.

    Fixed it. I was assuming that the call of product.update returns the product_id as it does with product.create. This wrong assumption broked the method i use to create the configurableProductData array; that was the problem.

    Working fine now.

    Thank you for the big help your article give us.

  7. You may also use our CoreAPI Extension, which adds many missing functions to Magento Core API, including the support for adding configurable products using the API.
    It is fully supported by our team and will be adjusted quickly to future versions.
    Using our Extension you don’t have to waste your time on creating your own API functions and fixing bugs.

    Just look at http://www.netzkollektiv.com/configurable-products-mit-der-netzkollektiv-coreapi-extension-fur-magento/ how easy it is to add configurable products.

  8. zafer said

    thi sis great post but not working stable version 1.6.2.0

  9. Here is an extension that allow you to simply specify skus of simple products to the configurable product: http://www.johannreinke.com/en/2012/04/20/magento-api-associate-simple-products-to-configurable-or-grouped-product/

Continuing the Discussion

  1. Magento ou la face cachée de l’API Product: comment créer des produits configurables en masse « Le blog de E-nova Technologies, Agence web Offshore Inde linked to this post on November 21, 2010

    [...] Dieu merci, Google est le meilleur ami du geek! Mais une fois de plus, à notre grande surprise, après avoir écumé moultes forums à la recherche d’une solution providentielle, nous nous sommes aperçus combien il était difficile de dénicher sur le net une information pertinente et exploitable… jusqu’à tomber sur ce blog:  http://www.stephenrhoades.com/?p=338 [...]

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.