Creating Magento simple and configurable products programmatically

Basically, products are the cornerstone of any catalog and e-commerce shop. And Magento has great features for creating them from backend, but there are cases when we need to create products programmatically, or manually. For example, you may need it if you import products in a certain text format, or if you need to create plenty of products to test a shop’s performance, or you are suggesting an alternative product creation interface.

How to create Magento simple products programmatically (manually)

To create a product in a shop’s database, we can:

  1. Make use of API (read more about it here)
  2. Perform a raw database request
  3. Create an object of Mage_Catalog_Model_Product type, initialize it and call the saving method.

We’ll talk about API in one of our upcoming articles later, it’s great for cases when integration of various systems takes place, but it’s not wise to use it within the scope of one system.
A query like INSERT INTO product_tablename … seems to be the easiest way of creating a Magento product at first sight, but only if you’re not familiar with EAV (entity attribute value) Magento storage architecture.

We’ll tell you more about EAV in the upcoming articles, and now I just want to point out that we’ll need to update more than 15 tables simultaneously to create a simple product. Here are the main ones (click to enlarge):

Magento database

To the full version of Magento database system, click to open the PDF. The table is a bit outdated, but it’ll do for our purpose here – we need to understand the process of creating a simple product.

We can see that the values are stored in several tables depending on their type. Moreover, dropdown attributes, such as color and manufacturer, have an additional table for options. Price and pictures are also stored separately.

Some good news: there is a Mage_Catalog_Model_Product class that takes care of integrity and correct data storage, and I am going to show you how to use it.
First things first, we are going to set some mandatory attributes:

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); //
	    $product = Mage::getModel('catalog/product');
		$rand = rand(1, 9999);
		$product
		->setTypeId($type)
		->setAttributeSetId(4) // default attribute set
		->setSku('example_sku' . $rand) // generate a random SKU
		->setWebsiteIDs(array(1))
		;

Now, time to make the product visible in the catalog:

	$product
			->setCategoryIds(array(2,3))
			->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
			->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) // visible in catalog and search
		;

Configuring stock:

$product->setStockData(array(
			'use_config_manage_stock' => 0, // use global config?
			'manage_stock'            => 1, // should we manage stock or not?
			'is_in_stock'             => 1,
			'qty'                     => 5,
        ));

Specifying mandatory attributes, such as name and price:

$product
			->setName('Test Product #' . $rand) // add string attribute
			->setShortDescription('Description') // add text attribute

			// set up prices
			->setPrice(24.50)
			->setSpecialPrice(19.99)
			->setTaxClassId(2)    // Taxable Goods by default
			->setWeight(87)
		;

Specifying dropdown-type attributes, such as color, size, brand:

	$optionId = $this->_getOptionIDByCode('color', 'Black');
	$product->setColor($optionId);
	$optionId = $this->_getOptionIDByCode('size', 'M');
	$product->setSize($optionId);

All the magic happens in $product->save();
Also, we can add some pictures to our newly created Magento simple product. Put files to the /media/example/amasty/ folder:

			$images = array(
				'thumbnail'   => 'image.jpg',
				'small_image' => 'image.jpg',
				'image'       => 'image.jpg',
			);

			$dir = Mage::getBaseDir('media') . DS . 'example/amasty/';

			foreach ($images as $imageType => $imageFileName) {
				$path = $dir . $imageFileName;
				if (file_exists($path)) {
					try {
						$product->addImageToMediaGallery($path, $imageType, false);
					} catch (Exception $e) {
						echo $e->getMessage();
					}
				} else {
					echo "Can not find image by path: `{$path}`<br/>";
				}
			}

Done! We have a simple product created. If you still can’t see it on the frontend, reindex and clear your cache. We always tell you to do this because it’s rather an important step than a simple recommendation.

Magento simple product created programmatically (manually)

Can we make this code better? Of course we can; never forget about performance optimization. If we create several products in a cycle, we need to tell the Magento core that the index tables needn’t be updated after each product creation; it’s better to do it at the end of the whole task.

		$product->setIsMassupdate(true)->setExcludeUrlRewrite(true);

So, we learned how to create Magento simple products manually. But, as we know, Magento has complex product types, such as:

  • Configurable
  • Grouped
  • Bundle ones.

How to create Magento configurable products programmatically (manually)

Now, we’ll step forward to create a configurable product. Say, we’ll make just one configuration options – color. In any way, we need at least two products: one parent configurable product and one child simple product.

$simpleProduct = $this->_createProduct(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE); // create simple product
$confProduct   = $this->_createProduct(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE, false); // create conf product but do not save

Then associate simple (child) product with the configurable (parent) product. There are several options of doing it, but not all of them work well with recent CE 1.9+ Magento versions. We will show you the easiest one. Just follow these 4 steps:

1. Select configurable attributes:

		$colorAttributeId = Mage::getModel('eav/entity_attribute')->getIdByCode('catalog_product', 'color');
		$confProduct->getTypeInstance()->setUsedProductAttributeIds(array($colorAttributeId));

2. Prepare information for each of the simple products:

		$configurableProductsData = array();
		$configurableAttributesData = $confProduct->getTypeInstance()->getConfigurableAttributesAsArray();

		$simpleProductsData = array(
			'label'         => $simpleProduct->getAttributeText('color'),
			'attribute_id'  => $colorAttributeId,
			'value_index'   => (int) $simpleProduct->getColor(),
			'is_percent'    => 0,
			'pricing_value' => $simpleProduct->getPrice(),
		);

		$configurableProductsData[$simpleProduct->getId()] = $simpleProductsData;
		$configurableAttributesData[0]['values'][] = $simpleProductsData;

3. Set data in 2 required formats:

		$confProduct->setConfigurableProductsData($configurableProductsData);
		$confProduct->setConfigurableAttributesData($configurableAttributesData);

4. Save product with a special flag:

		$confProduct->setCanSaveConfigurableAttributes(true);
		$confProduct->save();

N.B. We need to have the same attribute set in the configurable product and its associated product both.
Voila, we created a configurable Magento product manually. But today I have something more in the pocket.

 A free extension to create simple and configurable products

To improve the testing workflow, we created a Magento extension called Example, which demonstrates how to create Magento simple and configurable products fast and easy.

How to use the Example extension:

  1. Download the code.
  2. Install the extension as usual.
  3. Open http://your-site.com/example/amasty/ where your-site.com should be your website URL.
  4. Create as many products as you need.

We’d love to make Example better. Do you need more features here? Please share your opinion in comments.