Magento: How to import additional images for products

Featured Image

We did a migration from CRE LOADED (osCommerce clone) to Magento and we had to import all products with additional images. Every products had from 4 to 6 images which was a problem because Magento doesn’t have built-in ability to upload multiple images for products.


Our solution:

Step 1.
Save this in the file “/app/etc/modules/Inchoo_Import.xml”

< ?xml version="1.0"?>
<config>
     <modules>
          <inchoo_import>
               <active>true</active>
               <codepool>local</codepool>
          </inchoo_import>
    </modules>
</config>

Step 2.
Save this in the file: /app/code/local/Inchoo/Import/etc/config.xml

< ?xml version="1.0"?>
<config>
     <modules>
     <inchoo_import>
          <version>0.1.0</version>
     </inchoo_import>
     </modules>
<global>
     <models>
          <catalog>
               <rewrite>
                    <convert_adapter_product>Inchoo_Import_Model_Gallery</convert_adapter_product>
               </rewrite>
          </catalog>
    </models>
</global>
 
</config>

Step 3.
We create model (rewrite of existed)

< ?php
$import_gallery=Mage::getModel('catalog/convert_adapter_product');
echo get_class($import_gallery):
// you will get Inchoo_Import_Model_Gallery
[/sourcecode]
 
and also save this in /app/code/local/Inchoo/Import/Model/Gallery.php
 
[sourcecode='php']
< ?php
class Inchoo_Import_Model_Gallery extends Mage_Catalog_Model_Convert_Adapter_Product
{
public function saveRow(array $importData)
{
$product = $this->getProductModel()
->reset();
 
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']);
 
// if product exist do not update
if ($productId) {
return true;
$product->load($productId);
}
else {
$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'] : '';
$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]) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; $attribute &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; $attribute->getIsRequired()) {
$message = Mage::helper('catalog')->__('Skip import row, required field "%s" for new products not defined', $field);
Mage::throwException($message);
}
}
}
 
$this->setProductTypeInstance($product);
 
if (isset($importData['category_ids'])) {
$product->setCategoryIds($importData['category_ids']);
}
 
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->_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 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; $attribute->getBackendType() == 'decimal') {
$setValue = $this->getNumber($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 = 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);
 
$imageData = array();
foreach ($this->_imageFields as $field) {
if (!empty($importData[$field]) &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; $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, false, false);
}
catch (Exception $e) {}
}
/***************************start of modification**************************/
try {
$addimagesData = explode(';',$importData["addimages"]);
foreach($addimagesData as $addimages_img)
{
$product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . $addimages_img, null, false, false);
}
}
catch (Exception $e) {}
 
/***************************end of modification****************************/
 
$product->setIsMassupdate(true);
$product->setExcludeUrlRewrite(true);
 
//save product!!!
$product->save();
return true;
}
}

4. Step
We import products with csv file and example of csv:

"store","websites","attribute_set","type"......"addimages"
"admin","base","Default","simple"......"/girls/tees/nautical_girls650.jpg;/girls/tees/nautical_girls750.jpg;"

You can see, we added a column”addimages”
and pictures are separated with “;”

All pictures must be uploaded in folder: “/media/import” and you can go to: (Admin > System > Import/Export > Profiles >> Import All Products) and import can begin…


About Domagoj Potkoc

Backend Developer

Domagoj is Magento Certified Developer who enjoys playing tennis after long hours in front of computer screen.

Read more posts by Domagoj / Visit Domagoj's profile

8 comments

  1. STEP 3: PLEASE IS I CONFUSED PLEASE TELL ME WHERE TO I SAVE

    AFTER COMPLETE THIS WHERE WHICH FILE WHERE I EXECUTE

  2. can we import images with image sort order?it’s very important for me.

    Is there any way we can achieved this goal….?

  3. Hi,

    I have a problem that after import, images are saved into their respective location and record is also saved to database (image gallery). But those i mages are not visible into admin-> manage product detail…

    Can you suggest me what should i do

  4. By the way, I did eventually get this working, but by a manual work-around. For some reason the Inchoo_Import product adapter (and also the Mage_Core) doesn’t recognize any non-standard image fields (other than base, thumb, small) and add them into $this->_imageFields.

    So it imports the text of the image path into the cat_prod_entity_varchar tables with the correct EAV attributes, but (a) doesn’t copy the images files into /media/catalog/product and (b) doesn’t set the images in the Gallery.

    The work-arounds were to add an entry into cat_prod_entity_media_gallery for each image with an attribute_id = 73 (“media_gallery”) and the relevant entity_id. Then manually copy the image files into /media/catalog/product/X/Y where X and Y are the first two letters of the file name.

    This was really important for me as the site has an image-based nav (don’t ask – designers!!!) so now the content admins can upload new nav images without needing developer.

    Hope this helps someone!

  5. Thanks for this. I’m trying to do an import for images that have a specific attribute (ie I want image attributes in addition to base, thumb and small). I’ve added the new Media Image attribute and saved it in the default attribute set. The new attribute appears in the admin interface and I can manually upload images and select the radio button for my new attribute.

    When I run an import, it correctly updates the eav model with the path to the file, but it doesn’t appear in the Image Gallery on the product’s admin view, and using the $product->getDefaultNavImage() (the correct getter) doesn’t work. Does that make sense? Any ideas on how to fix?

    Thanks,
    Jonathan

  6. Looks like this has already been posted here: http://devzone.pratthost.com/2009/10/09/magento-import-multiple-images-for-products-module/

    Apart from that, Magento supports an already-built feature for importing product images. There’s a field named “gallery”, which accepts image names separated with commas, and can be used with the import process.
    All that is required is adding the last few lines that appear in this post, so that it pull the images gallery information from this pre-built column.

    The “gallery” column appears to be a Magento DataFlow feature which was already coded, but not completed (open source, go figure).

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>.