7

The problem

Current Situation

I'm having a problem with a third-party ioncube loader encoded feedloader plugin which is no longer supported by the original author (since they went tits-up) and instead of putting in two weeks to completely write it from scratch, I've decided to fix the problems it has after the import has run.

Compatibility

The only problem is: I want to write this using functions in the Mage library, not rely on a few custom queries that might break in the next update of Magento or whenever I change something in the database (I just want to get to know Magento's core functions better I guess)

Problem Diagnosis

The import does nearly everything correct, except from setting the base image (the small and thumbnail image are set correctly), as you can see in the screenshot below:

The first and only image has not been selected as default Base Image

The actual record in the database is missing for that image.. (so tempted to fix it with a query, but I won't.. I'm going to keep looking for an elegant solution)

Also, the function $product->getMediaGalleryImages() doesn't return any images, so I can't use the solution as suggested by @SKV over at Set Base Image Programmatically .. unless I am doing something wrong.

Community
  • 1
  • 1
Henry van Megen
  • 2,159
  • 2
  • 23
  • 35
  • 1
    use `getMediaGallery` instead of `getMediaGalleryImages`. See my answer. I've tested and it works. – Marius Oct 03 '13 at 08:24

3 Answers3

25
$productId = 1;
//load the product
$product = Mage::getModel('catalog/product')->load($productId);
//get all images
$mediaGallery = $product->getMediaGallery();
//if there are images
if (isset($mediaGallery['images'])){
    //loop through the images
    foreach ($mediaGallery['images'] as $image){
        //set the first image as the base image
        Mage::getSingleton('catalog/product_action')->updateAttributes(array($product->getId()), array('image'=>$image['file']), 0);
        //stop
        break;
    }
}
Marius
  • 15,148
  • 9
  • 56
  • 76
  • I have to try this myself, unfortunately some high-prio fixes have come up for another project.. I will try to do this later today. As soon as I have confirmed this I will mark this as the correct solution. Thank you!! – Henry van Megen Oct 03 '13 at 10:01
  • might be years old but this was very useful to me today – iphigenie Jul 18 '17 at 20:42
  • Base image working, May i know of small image and thumbnail image? – Gem Feb 06 '18 at 04:45
  • @Rathinam replace `image` with `small_image` or `thumbnail` in the `updateAttribtues` call. – Marius Feb 06 '18 at 07:22
  • @Marius $productId = 1; How can i add multiple product ids, If i try this $productId = array(3, 21, 24, 42, 74); its not working. error : https://snag.gy/F19p8v.jpg – Gem Feb 06 '18 at 11:28
6

This is the solution I eventually used in 'shell/fix_images.php':

<?php
ini_set('display_errors','On');
ini_set('memory_limit','512M');
error_reporting(E_ALL);
require_once('abstract.php');

class Mage_Shell_Updater extends Mage_Shell_Abstract
{
    public function run()
    {
        $products = Mage::getResourceModel('catalog/product_collection')
                ->addAttributeToFilter('is_imported', 1); // attribute added by importer
        $c=0;
        foreach($products as $p) {
            $pid = $p->getId();
            $product = Mage::getModel('catalog/product')->load($pid);
            $mediaGallery = $product->getMediaGallery();
            if (isset($mediaGallery['images'])){
                foreach ($mediaGallery['images'] as $image){
                    Mage::getSingleton('catalog/product_action')
                    ->updateAttributes(array($pid), array('image'=>$image['file']), 0);
                    $c++;
                    break;
                }
            }
        }
        echo($c . " product(s) updated.");
    }

}

$shell = new Mage_Shell_Updater();
$shell->run();

If anyone should use this, be sure to remove the 'addAttributeToFilter' from your own Mage method chain.. If you are going to run this as a standalone script (without disabling the realtime indexing first), add this code at the beginning of run():

    $pCollection = Mage::getSingleton('index/indexer')->getProcessesCollection(); 
    foreach ($pCollection as $process) {
        $process->setMode(Mage_Index_Model_Process::MODE_MANUAL)->save();
    }

at the end of run():

    foreach ($pCollection as $process) {
        $process->setMode(Mage_Index_Model_Process::MODE_REAL_TIME)->save();
    }

Also, the abstract.php is from Mage_Shell, usually located in the /shell/ directory in the root of your Magento installation.

Henry van Megen
  • 2,159
  • 2
  • 23
  • 35
  • What would I change to set all the images? Hundreds of my imported images are being set correctly. – Brad Oct 17 '14 at 02:18
0

In my problem i have set the images for the enabled grouped product. I have set the last image as the base,small and thumbnail image.

$collection = Mage::getModel('catalog/product')
                  ->getCollection()
                  ->addAttributeToFilter("type_id",array("eq","grouped"))
                  ->addAttributeToFilter("status",array("eq","1"));
foreach($collection as $tmpProduct) {
  $sku = $tmpProduct->getSku();
  $product = Mage::getModel('catalog/product')
                 ->loadByAttribute("sku",$sku);
  $_images = Mage::getModel('catalog/product')
                 ->load($product->getId())
                 ->getMediaGalleryImages();
  $checkImage =  Mage::getBaseDir('media').DS.'catalog'.DS.'product'.DS.$product->getImage();

  if( $product->getImage()!=''  && is_file($checkImage)) {
    continue; // do nothing
  } else {
    if($_images) {
      $baseImage = '';
      foreach($_images as $_image) {
        $baseImage = $_image->getFile();
      }
      $groupedImagePath = Mage::getBaseDir('media').DS.'catalog'.DS.'product'.DS.$baseImage;
      $product->setMediaGallery(
                  array('images'=>array (),
                        'values'=>array ()));
      $product->addImageToMediaGallery(
                  $groupedImagePath,
                  array('image', 'thumbnail', 'small_image'),
                  false,
                  false);   
      Mage::getModel('catalog/product_attribute_media_api')
          ->remove($product->getId(),$baseImage);
      $product->save();  
      echo "<br>$sku has selected image <br>";
} } }
thecoshman
  • 8,394
  • 8
  • 55
  • 77
  • You appear to be setting the media gallery to empty arrays and then adding the image. If there are multiple images saved with a product, will this remove all but the last one? – Steven Jeffries Jul 08 '16 at 21:47