How to import product images from external url in magento

October 27, 2011  |  18 Comments  |  by Raj (MagePsycho)  |  Magento, PHP

Introduction

Generally, we import the product images by copying all the images to /media/import folder, adding image path relative to /media/import in csv corresponding to the product skus and running the import profile.

Sometimes you may need to import images from external url and this is the case when you are using third party web services or migrating non magento cart to magento.

Steps

Suppose say we have a csv with an extra field: external_image_url for product import.

1> Copy app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php to the local code pool so that new path looks like:
app/code/local/Mage/Catalog/Model/Convert/Adapter/Product.php

2> Open the Product.php from local code pool and search for the following code within saveRow() function:

foreach ($imageData as $file => $fields) {
	try {
		$product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . trim($file), $fields);
	}
	catch (Exception $e) {}
}

Add the following code just below it:

/** EXTERNAL IMAGE IMPORT - START **/
$image_url  = $importData['external_image_url']; //get external image url from csv
$image_type = substr(strrchr($image_url,"."),1); //find the image extension
$filename   = md5($image_url . $importData['sku']).'.'.$image_type; //give a new name, you can modify as per your requirement
$filepath   = Mage::getBaseDir('media') . DS . 'import'. DS . $filename; //path for temp storage folder: ./media/import/
file_put_contents($filepath, file_get_contents(trim($image_url))); //store the image from external url to the temp storage folder
$mediaAttribute = array (
		'thumbnail',
		'small_image',
		'image'
);
/**
 * Add image to media gallery
 *
 * @param string        $file              file path of image in file system
 * @param string|array  $mediaAttribute    code of attribute with type 'media_image',
 *                                         leave blank if image should be only in gallery
 * @param boolean       $move              if true, it will move source file
 * @param boolean       $exclude           mark image as disabled in product page view
 */
$product->addImageToMediaGallery($filepath, $mediaAttribute, false, false);
/** EXTERNAL IMAGE IMPORT - END **/

3> That’s all. Now you can proceed with normal dataflow import profile.

From above code it is clear that we have used the php functions: file_get_contents() & file_put_conents() for the purpose.
Be sure to check if the fopen wrappers have been enabled or not in order to use url as parameter for file_get_contents(). Refer the configuration directive: allow-url-fopen for more info.

Let me know your feedback regarding this article.

Thanks for reading.

EDIT: FYI, this code was tested in Magento 1.5.x version.

Posted in Magento, PHP and tagged . Bookmark the permalink.

About Raj (MagePsycho)

Raj, the guy behind MagePsycho is a Zend PHP5 Certified Engineer, Magento Certified Developer, Magento Moderator / Freelancer with specialization in web applications (CMS, E-Commerce, ERP etc.). Catch him on: Twitter: @magepsycho Skype: magentopycho
  • http://www.hdmiwebshop.nl Koen

    Hi,

    Thanks for sharing! This looks very promising. However, I can’t find the foreach ($imageData as $file => $fields) {
    try {
    $product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . trim($file), $fields);
    }
    catch (Exception $e) {}
    }
    function in the Product.php your talking about. I’m using Magento 1.6.0.0. Thanks in advance

    Koen

    • RvSomani

      What changes should be made if we don’t want to import the products images on our server but want to load the image from the main/original server.

      Please guide us with complete steps as you have mentioned above as to how we can show up the images on our magento from external server

      Thanks and Regards

  • Perry

    Same issue. Placement in product.php is unclear since the code you cite cannot be found.

  • Lubos

    Hi, cannot find:

    foreach ($imageData as $file => $fields) {
    try {
    $product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . trim($file), $fields);
    }
    catch (Exception $e) {}
    }

    using Magento 1.6.1.

    Please help.

    Thank you.

  • Rodney

    This is great. How different is this for 1.6.1?

  • Z

    got this working for 1.6.1 Here’s the code I ended up with

    foreach ($product->getMediaAttributes() as $mediaAttributeCode => $mediaAttribute) {
    	if (isset($importData[$mediaAttributeCode])) {
                    $file = trim($importData[$mediaAttributeCode]);
                    if (!empty($file) && !$mediaGalleryBackendModel->getImage($product, $file)) {
                        // Start Of Code To Import Images From Urls
                        if (preg_match('%https?://[a-z0-9\-./]+\.(?:jpe?g|png|gif)%i', $file)) {
                            $path_parts = pathinfo($file);
                            $html_filename = DS . $path_parts['basename'];
                            $fullpath = Mage::getBaseDir('media') . DS . 'import' . $html_filename;
                            if(!file_exists($fullpath)) {
                                file_put_contents($fullpath, file_get_contents($file));}
                            $arrayToMassAdd[] = array('file' => trim($html_filename), 'mediaAttribute' => $mediaAttributeCode);
                        }
                        else
                        {
                            $arrayToMassAdd[] = array('file' => trim($file), 'mediaAttribute' => $mediaAttributeCode);
                        }
                        // End Of Code To Import Images From URLs
                    }
    	}
    }
  • Cassandra

    Great! Thanks MagePsycho!
    But I am using 1.6.2.0. and ofcourse I can’t find the code. Could you or someone else help me??

    Thanks.

  • Gildo

    Which is The code for 1.7 version?
    Thanks in advance, Gildo

    • http://www.thevintagesignstore.com Pete Evans

      Did we ever get a code for 7.1?

      Thanks
      Pete

  • http://forge-of-the-ancients.com The Forge

    Hello, nice article I have been searching for a while now for something like this. I just created my first store using 1.7 and needed to find out how to implement this code into a community edition 1.7. Thank you.

  • http://forge-of-the-ancients.com Dave

    Hello, I had the code working in 1.6 and updated to 1.7 and now I am unable to use the URL for my images. Is there a fix for 1.7 that I can use in order to get the URL images to work? Thank you.

    • http://www.blairgeddes.co.uk Blair Geddes

      Hi Dave, did you or anyone else get any luck making this code work for 1.7 version or newer?

  • jaro

    I’m using magento 1.7.0.2 and code for it is instead of this one:
    foreach ($product->getMediaAttributes() as $mediaAttributeCode => $mediaAttribute) {
    if (isset($importData[$mediaAttributeCode])) {
    $file = trim($importData[$mediaAttributeCode]);
    if (!empty($file) && !$mediaGalleryBackendModel->getImage($product, $file)) {
    $arrayToMassAdd[] = array(‘file’ => trim($file), ‘mediaAttribute’ => $mediaAttributeCode);
    }
    }
    }

    put this one:
    foreach ($product->getMediaAttributes() as $mediaAttributeCode => $mediaAttribute) {
    if (isset($importData[$mediaAttributeCode])) {
    $file = trim($importData[$mediaAttributeCode]);
    if (!empty($file) && !$mediaGalleryBackendModel->getImage($product, $file)) {
    // Start Of Code To Import Images From Urls
    if (preg_match(‘%https?://[a-z0-9\-./]+\.(?:jpe?g|png|gif)%i’, $file)) {
    $path_parts = pathinfo($file);
    $html_filename = DS . $path_parts['basename'];
    $fullpath = Mage::getBaseDir(‘media’) . DS . ‘import’ . $html_filename;
    if(!file_exists($fullpath)) {
    $ch = curl_init ($file);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
    $rawdata=curl_exec($ch);
    curl_close ($ch);
    if(file_exists($fullpath)) {
    unlink($fullpath);
    }
    $fp = fopen($fullpath,’x');
    fwrite($fp, $rawdata);
    fclose($fp);
    }
    $arrayToMassAdd[] = array(‘file’ => trim($html_filename), ‘mediaAttribute’ => $mediaAttributeCode);
    }
    else
    {
    $arrayToMassAdd[] = array(‘file’ => trim($file), ‘mediaAttribute’ => $mediaAttributeCode);
    }
    }
    }
    }

  • http://www.blairgeddes.co.uk Blair Geddes

    Hi Jaro,

    This last entry you’ve made doesn’t quite work in 1.7.01.

    Looks like mistype of character behind the x on this line:

    $fp = fopen($fullpath,’x’);

    Have changed around for other characters, but still can’t get to work perfectly.

    Has anyone got this new code to work in versions after 1.7?

    I’ve tried calling the url string both image and external_image_url for example in the csv file being imported in. Thanks.

  • Yasin

    Jaro’s code seems to be working but you need to replace all \’ to ‘ and \” to “

  • goo

    I did it but it gives me this error Parse error: syntax error, unexpected ‘;’ in /home/content/10/10030910/html/app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php on line 770

  • RvSomani

    In Regards to the above Post I would like to thank you for sharing a worthy thing to all . .

    What changes should be made if we don’t want to import the products
    images on our server but want to load the image from the main/original
    server.

    Please guide us with complete steps as you have mentioned
    above as to how we can show up the images on our magento from external
    server

  • Dev IQ

    is it work for Magento 1.8.1????