Magento remove images of deleted products

Clean up not used Magento images

Magento unfortunately does not remove images of a product unfortunately if the product is removed. The following script checks all the images and checks if it’s still present in the database of Magento. If not, it deletes the image. Use the following code:

<?php

$mageFilename = 'app/Mage.php';
require_once $mageFilename;

Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
umask(0);

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

set_time_limit(0);
ini_set('memory_limit','1024M');

$media = Mage::getBaseDir('media').'/catalog/product';

echo "Query database for images …\n";
$query = "SELECT value FROM catalog_product_entity_media_gallery";
$data = Mage::getSingleton('core/resource')->getConnection('core_read')->fetchAll($query);

$dbData=array();
foreach($data as $item){
  $dbData[$item['value']]=$item['value'];
}

echo "Images found in database:".count($dbData)."\n";

echo "Search images in media directory …\n";
$images = findFiles($media, array('jpg'));
echo "Images found under directory ($media):".count($images['jpg'])."\n";

echo "Start removing images …\n";
$removedCount=0;
$skippedCount=0;
foreach($images['jpg'] as $image) {
  if(strpos($image,'cache')!==false)
  {
    //echo "Skip cached image : $image\n";
    continue;
  }

  $imageCleanup = str_replace($media,"",$image);
  if(isset($dbData[$imageCleanup]))
  {
    echo "Skip image is in database : $image\n";
    $skippedCount++;
    continue;
  }
  else
  {
    echo "Remove image : $image\n";
    //if($testrun==false) unlink($image);
    $removedCount++;
  }
}

echo "Done, removed $removedCount images and skipped $skippedCount images.\n";

function findFiles($directory, $extensions = array()) {
  function glob_recursive($directory, &$directories = array()) {
    foreach(glob($directory, GLOB_ONLYDIR | GLOB_NOSORT) as $folder) {
      $directories[] = $folder;
      glob_recursive("{$folder}/*", $directories);
    }
  }
  glob_recursive($directory, $directories);
  $files = array ();
  foreach($directories as $directory) {
  foreach($extensions as $extension) {
  foreach(glob("{$directory}/*.{$extension}") as $file) {
  $files[$extension][] = $file;
}
}
}
return $files;
}

?>

Clean up Magento space: could save a lot of GBs

In my case, I tried the script for a store with 40K images of which 10K were not used. This is a disk space reduction of a few Gigabytes.

Final word

This script is thanks to a comment on RapidCommerce. If you use the script, that’s on your own responsibility. Try it out on a staging server and make a backup in advance. Cheers!



Load normal product price instead of indexed product price

Would you like to ignore the indexed product price in the templates (for example in catalog/product/list.phtml where the indexed price is used)?

Then go to: catalog/product/list.phtml

Change:

<?php echo $this->getPriceHtml($product) ?>

With:

<?php $product = Mage::getModel( 'catalog/product' )->load($_product->getId()); ?>
<?php echo $this->getPriceHtml($product) ?>

There are two occurrences in list.phtml, so don’t forget to replace it twice. Only do this when it’s the only solution of displaying right prices, since loading the product takes extra time, compared to loading the indexed product price.