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!

5 thoughts on “Magento remove images of deleted products”

  1. Hello, I use the script with delete.php name at the root, to run with the browser, it is shown that the files were excluded, but they are still in it!

    1. Change

      else
      {
      echo “Remove image : $image\n”;
      //if($testrun==false) unlink($image);
      $removedCount++;
      }

      to

      else
      {
      echo “Remove image : $image\n”;
      unlink($image);
      $removedCount++;
      }

  2. hello , i get this error

    Query database for images …
    Fatal error: Uncaught exception ‘PDOException’ with message ‘SQLSTATE[42S02]: Base table or view not found: 1146 Table ‘muslimas_mage958.catalog_product_entity_media_gallery’ doesn’t exist’ in /home/muslimas/public_html/lib/Zend/Db/Statement/Pdo.php:228 Stack trace: #0 /home/muslimas/public_html/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array) #1 /home/muslimas/public_html/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array) #2 /home/muslimas/public_html/app/code/core/Zend/Db/Statement.php(291): Varien_Db_Statement_Pdo_Mysql->_execute(Array) #3 /home/muslimas/public_html/lib/Zend/Db/Adapter/Abstract.php(480): Zend_Db_Statement->execute(Array) #4 /home/muslimas/public_html/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query(‘SELECT value FR…’, Array) #5 /home/muslimas/public_html/lib/Varien/Db/Adapter/Pdo/Mysql.php(504): Zend_Db_Adapter_Pdo_Abstract->query(‘SELECT value FR…’, Array) #6 /home/muslimas/public_html/lib/Zend/Db/Adapter/Abstract.php(737): in /home/muslimas/public_html/lib/Zend/Db/Statement/Pdo.php on line 235

    1. You might have a database tablename prefix. The script is not using the built-in function to get the table name, so there is no prefix. Try replacing the table name with Mage::getSingleton(‘core/resource’)->getTableName(‘catalog_product_entity_media_gallery’)

Leave a Reply

Your email address will not be published. Required fields are marked *