Import configurable Products

Import configurable Products

Unlikely the default Magento import module, this fully customizable bulk import module allows you to import configurable products from CSV feed
$99.00
SKU: import-configurable-products

This fully customizable Magento bulk import is your gateway to import products hassle free from your Magento compliant CSV feed.

Commercial Edition

This edition is a better choice for commercial usage given that it contains features that are not available in the FREE version.
It is fully supported by the developer ,no need to worry about updates, bug fixes as it comes with FREE and unlimited support.

Benefit summary

  • Get instant answers for all your questions
  • Import tier pricing
  • Import super attribute pricing (pricing for configurable products)
  • Import Products with Custom Options
  • Import Products with Multiple Images
  • Import Attribute Labels / Options
  • Import Images ALT Tags (Image labels)
  • Import categories
  • Get instant FREE and unlimited support if you need any assistance with the plugin
  • Get FREE updates

Free Edition (do it yourself)

Before you start using the this import script, prepare your csv to meet the following format:
$imagesFolder = Mage::getBaseDir ( 'media' ) . DS .  "import";
$importableCSV = Mage::getBaseDir (). DS. "var/import/productsFeed.csv" ; 

		if ( file_exists( $importableCSV) )
		unlink( $importableCSV);	

$fh = fopen($importableCSV, 'w') or die("can't open file ". $importableCSV);	
// config_attributes are attribute used to create the configurable product eg: "size,color"
// associated = all associated simple products skus separated with a comma  eg: "1452,526,5214"
$header = array();

$productAttributes = array( "store", "websites", "attribute_set", "status", "is_in_stock","tax_class_id","name", "type","color","size","weight","manufacturer","price","description","short_description","image","small_image","thumbnail","has_options","visibility","qty","associated","config_attributes");
foreach ($productAttributes as $value){
  $header [] = '"' . $value . '"' ;
}
$headerStr =  implode(",",$header);
fwrite($fh, $headerStr  . "\n" );

// use a for/while loop to write all your simple products rows 
$associated = array();
$simpleProductAttributes = array (
                                         "store" => '"' . "admin". '"' ,
		                         "websites" => '"' ."base" .'"' , 
		                         "attribute_set" => '"'  . "apparel" . '"',
		                         "status" => '"'  .  "Enabled" . '"',
		                 "is_in_stock" => '"'  . "1" . '"',
		                 "tax_class_id" => '"'  .  "Taxable Goods" . '"',
                                  "sku" => '"'  .  $sku. '"', 
                                "name" => '"'  .  $name . '"',
                                 "type" => '"'  .  "simple" . '"',
                                 "color" => '"'  . $color . '"',
                                 "size" => '"'  .  $size . '"',
                                 "weight" => '"'  .  $weight . '"',
                                 "manufacturer" => '"'  .  $manufacturer . '"',
                                  "description" => '"'  . $description . '"',
                                  "short_description" => '"'  .  $short_description . '"',
                                  "image" => '"'  . $image . '"',
                                  "small_image" => '"'  . $small_image. '"',   //  example:  "/image_name.jpg"  image_name.jpg must be uploaded to $imagesFolder
                                  "thumbnail" => '"'  . $thumbnail. '"',
                                  "has_options" => '"'  . $has_options. '"',   // $has_options = 1 or 0 
                                   "visibility" => '"'  . "Not Visible Individually" . '"',
                                   "qty" => '"'  . $qty. '"',
                                   "associated" => ,
                                   "config_attributes" => 
                         ); 

// Simple Product Row
$csvBlock = array();
foreach ($simpleProductAttributes as $value){
  $csvBlock [] = '"' . $value . '"' ;
}
$csvBlockStr =  implode(",",$csvBlock); 
fwrite($fh, $csvBlockStr. "\n" );
$associated [] = $sku ; 
// end for/while loop
$configurableProductAttributes = array (
                                "store" => '"' . "admin". '"' ,
		                 "websites" => '"' ."base" .'"' , 
		                 "attribute_set" => '"'  . "apparel" . '"',
		                 "status" => '"'  .  "Enabled" . '"',
		                 "is_in_stock" => '"'  . "1" . '"',
		                 "tax_class_id" => '"'  .  "Taxable Goods" . '"',
                                "name" => '"'  .  $name . '"',
                                 "type" => '"'  .  "configurable" . '"',
                                 "color" =>,
                                 "size" => ,
                                 "weight" => '"'  .  $weight . '"',
                                 "manufacturer" => '"'  .  $manufacturer . '"',
                                  "description" => '"'  . $description . '"',
                                  "short_description" => '"'  .  $short_description . '"',
                                  "image" => '"'  . $image . '"',
                                  "small_image" => '"'  . $small_image. '"',
                                  "thumbnail" => '"'  . $thumbnail. '"',
                                  "has_options" => '"'  . $has_options. '"',   // $has_options = 1 or 0 
                                   "visibility" => '"'  . "Catalog, Search" . '"',
                                   "qty" => '"'  . $qty. '"',
                                   "associated" =>  '"'  . implode(",",$associated) . '"',  // associated = all associates products skus separated with a comma  eg "1452,521,542"
                                   "config_attributes" => "color,size"
                         );
$csvBlock = array();
foreach ($configurableProductAttributes as $value){
  $csvBlock [] = '"' . $value . '"' ;
}
$csvBlockStr =  implode(",",$csvBlock); 
fwrite($fh, $csvBlockStr. "\n" );

fclose($fh);
  • Copy the file Productwithconfigurablesandcategories.php (see listing below) to the folder /app/code/core/Mage/Catalog/Model/Convert/Adapter/
  • Go to Admin->System->Advanced Profiles and create a new profile with the following information:
    - Profile Name * : Productwithconfigurablesandcategories
    - Actions XML * : Paste the XML code (check XML listing below)
    and click on Run profile to start importing your products
<?php


class Mage_Catalog_Model_Convert_Adapter_Productwithconfigurablesandcategories extends Mage_Catalog_Model_Convert_Adapter_Product {
	
	/**
	 * Save product (import)
	 *
	 * @param array $importData
	 * @throws Mage_Core_Exception
	 * @return bool
	 */
	public function saveRow(array $importData) {
		$product = $this->getProductModel ();
		$product->setData ( array () );
		if ($stockItem = $product->getStockItem ()) {
			$stockItem->setData ( array () );
		}
		
		if (empty ( $importData ['store'] )) {
			if (! is_null ( $this->getBatchParams ( 'store' ) )) {
				$store = $this->getStoreById ( $this->getBatchParams ( 'store' ) );
			} else {
				$message = Mage::helper ( 'catalog' )->__ ( 'Skip import row, required field "%s" not defined', 'store' );
				Mage::throwException ( $message );
			}
		} else {
			$store = $this->getStoreByCode ( $importData ['store'] );
		}
		
		if ($store === false) {
			$message = Mage::helper ( 'catalog' )->__ ( 'Skip import row, store "%s" field not exists', $importData ['store'] );
			Mage::throwException ( $message );
		}
		if (empty ( $importData ['sku'] )) {
			$message = Mage::helper ( 'catalog' )->__ ( 'Skip import row, required field "%s" not defined', 'sku' );
			Mage::throwException ( $message );
		}
		$product->setStoreId ( $store->getId () );
		$productId = $product->getIdBySku ( $importData ['sku'] );
		$new = true; // fix for duplicating attributes error
		if ($productId) {
			$product->load ( $productId );
			$new = false; // fix for duplicating attributes error
		}
		$productTypes = $this->getProductTypes ();
		$productAttributeSets = $this->getProductAttributeSets ();
		
		/**
		 * Check product define type
		 */
		
		if (empty ( $importData ['type'] ) || ! isset ( $productTypes [strtolower ( $importData ['type'] )] )) {
			$value = isset ( $importData ['type'] ) ? $importData ['type'] : '';
			echo $value;
			$message = Mage::helper ( 'catalog' )->__ ( 'Skip import row, is not valid value "%s" for field "%s"', $value, 'type' );
			Mage::throwException ( $message );
		}
		$product->setTypeId ( $productTypes [strtolower ( $importData ['type'] )] );
		/**
		 * Check product define attribute set
		 */
		if (empty ( $importData ['attribute_set'] ) || ! isset ( $productAttributeSets [$importData ['attribute_set']] )) {
			$value = isset ( $importData ['attribute_set'] ) ? $importData ['attribute_set'] : '';
			$message = Mage::helper ( 'catalog' )->__ ( 'Skip import row, is not valid value "%s" for field "%s"', $value, 'attribute_set' );
			Mage::throwException ( $message );
		}
		$product->setAttributeSetId ( $productAttributeSets [$importData ['attribute_set']] );
		
		foreach ( $this->_requiredFields as $field ) {
			$attribute = $this->getAttribute ( $field );
			if (! isset ( $importData [$field] ) && $attribute && $attribute->getIsRequired ()) {
				$message = Mage::helper ( 'catalog' )->__ ( 'Skip import row, required field "%s" for new products not defined', $field );
				Mage::throwException ( $message );
			}
		}
		
		//================================================
		// this part handles configurable products and links 
		//================================================
		

		if ($importData ['type'] == 'configurable') {
			$product->setCanSaveConfigurableAttributes ( true );
			$configAttributeCodes = $this->userCSVDataAsArray ( $importData ['config_attributes'] );
			$usingAttributeIds = array ();
			foreach ( $configAttributeCodes as $attributeCode ) {
				$attribute = $product->getResource ()->getAttribute ( $attributeCode );
				if ($product->getTypeInstance ()->canUseAttribute ( $attribute )) {
					if ($new) { // fix for duplicating attributes error
						$usingAttributeIds [] = $attribute->getAttributeId ();
					}
				}
			}
			if (! empty ( $usingAttributeIds )) {
				$product->getTypeInstance ()->setUsedProductAttributeIds ( $usingAttributeIds );
				$product->setConfigurableAttributesData ( $product->getTypeInstance ()->getConfigurableAttributesAsArray () );
				$product->setCanSaveConfigurableAttributes ( true );
				$product->setCanSaveCustomOptions ( true );
			}
			if (isset ( $importData ['associated'] )) {
				$product->setConfigurableProductsData ( $this->skusToIds ( $importData ['associated'], $product ) );
			}
		}
		
		/**
		 * Init product links data (related, upsell, crosssell, grouped)
		 */
		if (isset ( $importData ['related'] )) {
			$linkIds = $this->skusToIds ( $importData ['related'], $product );
			if (! empty ( $linkIds )) {
				$product->setRelatedLinkData ( $linkIds );
			}
		}
		if (isset ( $importData ['upsell'] )) {
			$linkIds = $this->skusToIds ( $importData ['upsell'], $product );
			if (! empty ( $linkIds )) {
				$product->setUpSellLinkData ( $linkIds );
			}
		}
		if (isset ( $importData ['crosssell'] )) {
			$linkIds = $this->skusToIds ( $importData ['crosssell'], $product );
			if (! empty ( $linkIds )) {
				$product->setCrossSellLinkData ( $linkIds );
			}
		}
		if (isset ( $importData ['grouped'] )) {
			$linkIds = $this->skusToIds ( $importData ['grouped'], $product );
			if (! empty ( $linkIds )) {
				$product->setGroupedLinkData ( $linkIds );
			}
		}
		
		//================================================
		

		if (isset ( $importData ['category_ids'] )) {
			$product->setCategoryIds ( $importData ['category_ids'] );
		}
		//// Para importar categorias
		if (isset ( $importData ['categories'] )) {
			$categoryIds = $this->_addCategories ( $importData ['categories'], $store );
			if ($categoryIds) {
				$product->setCategoryIds ( $categoryIds );
			}
		}
		////
		foreach ( $this->_ignoreFields as $field ) {
			if (isset ( $importData [$field] )) {
				unset ( $importData [$field] );
			}
		}
		
		if ($store->getId () != 0) {
			$websiteIds = $product->getWebsiteIds ();
			if (! is_array ( $websiteIds )) {
				$websiteIds = array ();
			}
			if (! in_array ( $store->getWebsiteId (), $websiteIds )) {
				$websiteIds [] = $store->getWebsiteId ();
			}
			$product->setWebsiteIds ( $websiteIds );
		}
		
		if (isset ( $importData ['websites'] )) {
			$websiteIds = $product->getWebsiteIds ();
			if (! is_array ( $websiteIds )) {
				$websiteIds = array ();
			}
			$websiteCodes = split ( ',', $importData ['websites'] );
			foreach ( $websiteCodes as $websiteCode ) {
				try {
					$website = Mage::app ()->getWebsite ( trim ( $websiteCode ) );
					if (! in_array ( $website->getId (), $websiteIds )) {
						$websiteIds [] = $website->getId ();
					}
				} catch ( Exception $e ) {
				}
			}
			$product->setWebsiteIds ( $websiteIds );
			unset ( $websiteIds );
		}
		
		foreach ( $importData as $field => $value ) {
			// if (in_array($field, $this->_inventorySimpleFields)) {works only for old version )
			if (in_array ( $field, $this->_inventoryFields )) {
				continue;
			}
			if (in_array ( $field, $this->_imageFields )) {
				continue;
			}
			
			$attribute = $this->getAttribute ( $field );
			if (! $attribute) {
				continue;
			}
			
			$isArray = false;
			$setValue = $value;
			
			if ($attribute->getFrontendInput () == 'multiselect') {
				$value = split ( self::MULTI_DELIMITER, $value );
				$isArray = true;
				$setValue = array ();
			}
			
			if ($value && $attribute->getBackendType () == 'decimal') {
				$setValue = $this->getNumber ( $value );
			}
			
			if ($value && $attribute->getBackendType () == 'datetime') {
			    $setValue= date('Y-m-j', strtotime($value));
			}
			
			
			if ($attribute->usesSource ()) {
				$options = $attribute->getSource ()->getAllOptions ( false );
				
				if ($isArray) {
					foreach ( $options as $item ) {
						if (in_array ( $item ['label'], $value )) {
							$setValue [] = $item ['value'];
						}
					}
				} else {
					$setValue = null;
					foreach ( $options as $item ) {
						if ($item ['label'] == $value) {
							$setValue = $item ['value'];
						}
					}
				}
			}
			$product->setData ( $field, $setValue );
		}
		if (! $product->getVisibility ()) {
			$product->setVisibility ( Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE );
		}
		
		$stockData = array ();
		//$inventoryFields = $product->getTypeId() == 'simple' ? $this->_inventorySimpleFields : $this->_inventoryOtherFields;
		$inventoryFields = isset ( $this->_inventoryFieldsProductTypes [$product->getTypeId ()] ) ? $this->_inventoryFieldsProductTypes [$product->getTypeId ()] : array ();
		foreach ( $inventoryFields as $field ) {
			if (isset ( $importData [$field] )) {
				if (in_array ( $field, $this->_toNumber )) {
					$stockData [$field] = $this->getNumber ( $importData [$field] );
				} else {
					$stockData [$field] = $importData [$field];
				}
			}
		}
		$product->setStockData ( $stockData );
		# import gallery images
      if (! empty ( $importData ['gallery'] )) {
		 
		$galleryData = explode(',',$importData["gallery"]);
		$counter = 0;
		foreach($galleryData as $gallery_img)
		{
                if($counter == 0){
                 /**
				 * BEGIN REMOVE EXISTING MEDIA GALLERY
				 */
				$attributes = $product->getTypeInstance ()->getSetAttributes ();
				if (isset ( $attributes ['media_gallery'] )) {
					$gallery = $attributes ['media_gallery'];
					//Get the images
					$galleryData = $product->getMediaGallery ();
					foreach ( $galleryData ['images'] as $image ) {
						//If image exists
						if ($gallery->getBackend ()->getImage ( $product, $image ['file'] )) {
							$gallery->getBackend ()->removeImage ( $product, $image ['file'] );
						}
					}
					
				}
				/**
				 * END REMOVE EXISTING MEDIA GALLERY
				 */
                }
               
                $product->addImageToMediaGallery ( Mage::getBaseDir ( 'media' ) . DS . 'import' . DS. $gallery_img,  array ("thumbnail", "small_image", "image" ), false, false );
               
		     $counter++;
		}
                	
		}
		$imageData = array ();
		foreach ( $this->_imageFields as $field ) {
			if (! empty ( $importData [$field] ) && $importData [$field] != 'no_selection') {
				if (! isset ( $imageData [$importData [$field]] )) {
					$imageData [$importData [$field]] = array ();
				}
				$imageData [$importData [$field]] [] = $field;
			}
		}
		
		foreach ( $imageData as $file => $fields ) {
			try {
				$product->addImageToMediaGallery ( Mage::getBaseDir ( 'media' ) . DS . 'import' . $file, $fields );
			} catch ( Exception $e ) {
			}
		}
		
		$product->setIsMassupdate ( true );
		$product->setExcludeUrlRewrite ( true );
		
		$product->save ();
		
		return true;
	}
	
	protected function userCSVDataAsArray($data) {
		return explode ( ',', str_replace ( " ", "", $data ) );
	}
	
	protected function skusToIds($userData, $product) {
		$productIds = array ();
		foreach ( $this->userCSVDataAsArray ( $userData ) as $oneSku ) {
			if (($a_sku = ( int ) $product->getIdBySku ( $oneSku )) > 0) {
				parse_str ( "position=", $productIds [$a_sku] );
			}
		}
		return $productIds;
	}
	
	//// Para importar categorias
	protected $_categoryCache = array ();
	protected function _addCategories($categories, $store) {
		$rootId = $store->getRootCategoryId ();
		if (! $rootId) {
			return array ();
		}
		$rootPath = '1/' . $rootId;
		if (empty ( $this->_categoryCache [$store->getId ()] )) {
			$collection = Mage::getModel ( 'catalog/category' )->getCollection ()->setStore ( $store )->addAttributeToSelect ( 'name' );
			$collection->getSelect ()->where ( "path like '" . $rootPath . "/%'" );
			
			foreach ( $collection as $cat ) {
				$pathArr = explode ( '/', $cat->getPath () );
				$namePath = '';
				for($i = 2, $l = sizeof ( $pathArr ); $i < $l; $i ++) {
					$name = $collection->getItemById ( $pathArr [$i] )->getName ();
					$namePath .= (empty ( $namePath ) ? '' : '/') . trim ( $name );
				}
				$cat->setNamePath ( $namePath );
			}
			
			$cache = array ();
			foreach ( $collection as $cat ) {
				$cache [strtolower ( $cat->getNamePath () )] = $cat;
				$cat->unsNamePath ();
			}
			$this->_categoryCache [$store->getId ()] = $cache;
		}
		$cache = & $this->_categoryCache [$store->getId ()];
		
		$catIds = array ();
		foreach ( explode ( ',', $categories ) as $categoryPathStr ) {
			$categoryPathStr = preg_replace ( '#s*/s*#', '/', trim ( $categoryPathStr ) );
			if (! empty ( $cache [$categoryPathStr] )) {
				$catIds [] = $cache [$categoryPathStr]->getId ();
				continue;
			}
			$path = $rootPath;
			$namePath = '';
			foreach ( explode ( '/', $categoryPathStr ) as $catName ) {
				$namePath .= (empty ( $namePath ) ? '' : '/') . strtolower ( $catName );
				if (empty ( $cache [$namePath] )) {
					$cat = Mage::getModel ( 'catalog/category' )->setStoreId ( $store->getId () )->setPath ( $path )->setName ( $catName )->// comment out the following line if new categories should stay inactive
					setIsActive ( 1 )->save ();
					$cache [$namePath] = $cat;
				}
				$catId = $cache [$namePath]->getId ();
				$path .= '/' . $catId;
			}
			if ($catId) {
				$catIds [] = $catId;
			}
		}
		return join ( ',', $catIds );
	}
	////


}

<action type="dataflow/convert_adapter_io" method="load"> 
    <var name="type">file</var> 
    <var name="path">var/import</var> 
    <var name="filename"></var> 
    <var name="format"></var> 
</action> 
 
<action type="dataflow/convert_parser_csv" method="parse"> 
    <var name="delimiter"></var> 
    <var name="enclose"></var> 
    <var name="fieldnames">true</var> 
    <var name="store"></var> 
    <var name="number_of_records">1</var> 
    <var name="decimal_separator"></var> 
    <var name="adapter">catalog/convert_adapter_Productwithconfigurablesandcategories</var> 
    <var name="method">parse</var> 
</action>