Skip to content

Instantly share code, notes, and snippets.

@ljay79
Forked from aleron75/shell_delete_unused_images
Last active January 18, 2019 09:38
Show Gist options
  • Save ljay79/52ca1202cc84303d5de38048526ed9ea to your computer and use it in GitHub Desktop.
Save ljay79/52ca1202cc84303d5de38048526ed9ea to your computer and use it in GitHub Desktop.
Delete no more used Product Images on Magento 1.x - tested on Magento CE v1.9.3.10
<?php
require_once 'abstract.php';
class Mage_Shell_CheckImages extends Mage_Shell_Abstract
{
const CATALOG_PRODUCT = '/catalog/product';
const CACHE = '/cache/';
const PLACEHOLDER = '/placeholder/';
protected function _glob_recursive($pattern, $flags = 0)
{
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
$files = array_merge($files, $this->_glob_recursive($dir . '/' . basename($pattern), $flags));
}
return $files;
}
public function run()
{
if ($this->getArg('help')) {
echo $this->usageHelp();
return;
}
$media = Mage::getBaseDir('media');
$debug = $this->getArg('debug');
$dryrun = $this->getArg('dry') ? true : false ;
$includeCache = $this->getArg('cache');
$imagesOnDb = array();
$imagesOnDisk = array();
$setup = new Mage_Core_Model_Resource_Setup('core_setup');
/** @var Varien_Db_Adapter_Pdo_Mysql $connection */
$connection = $setup->getConnection();
$entityTypeIdSql = sprintf(
"SELECT `entity_type_id` FROM `%s` WHERE `entity_type_code` = :entity_type_code;",
$setup->getTable('eav/entity_type')
);
$entityTypeId = (int)$connection->fetchOne($entityTypeIdSql, array('entity_type_code' => Mage_Catalog_Model_Product::ENTITY));
if (!$entityTypeId) {
throw new RuntimeException(sprintf(
"Could not find entity type code for entity %s",
Mage_Catalog_Model_Product::ENTITY
));
}
$sql = "SELECT DISTINCT value
FROM (
SELECT value
FROM `{$setup->getTable('catalog_product_entity_media_gallery')}`
WHERE attribute_id
IN (SELECT attribute_id FROM `{$setup->getTable('eav_attribute')}` WHERE `attribute_code` in ('media_gallery') AND entity_type_id = :entity_type_id)
UNION
SELECT value
FROM `{$setup->getTable('catalog_product_entity_varchar')}`
WHERE attribute_id
IN (SELECT attribute_id FROM `{$setup->getTable('eav_attribute')}` WHERE `attribute_code` in ('image','small_image','thumbnail') AND entity_type_id = :entity_type_id)
) AS T";
$result = $connection->query($sql, array('entity_type_id' => $entityTypeId));
foreach ($result->fetchAll() as $rec) {
$imagesOnDb[$rec['value']] = 1;
}
$imagesOnDb = array_keys($imagesOnDb);
if ($debug) print_r(array_slice($imagesOnDb, 0, 100));
if ($debug) echo $media . "/*\n";
$skip = strlen($media . self::CATALOG_PRODUCT);
foreach ($this->_glob_recursive($media . self::CATALOG_PRODUCT . '/*', GLOB_MARK) as $img) {
if (substr($img, -1) != '/') {
if ((substr($img, $skip, 13) != self::PLACEHOLDER) && ($includeCache || (substr($img, $skip, 7) != self::CACHE))) {
$imagesOnDisk[] = substr($img, $skip);
}
}
}
if ($debug) print_r(array_slice($imagesOnDisk, 0, 100));
$imagesToDelete = array_diff($imagesOnDisk, $imagesOnDb);
if ($debug) {
print_r($imagesToDelete);
echo count($imagesOnDisk)." images on Disk\n";
echo count($imagesOnDb)." images on DB\n";
echo count($imagesToDelete)." images to delete\n";
} else {
foreach ($imagesToDelete as $x) {
if ($dryrun) {
echo 'rm '.$media . self::CATALOG_PRODUCT . $x.PHP_EOL;
} else {
@unlink($media . self::CATALOG_PRODUCT . $x);
}
}
}
if ($debug) {
echo "\r\n";
}
}
public function usageHelp()
{
return <<<USAGE
Usage: php -f delete_unused_images.php
debug debug mode
cache remove cache images too
dry dryrun
USAGE;
}
}
$shell = new Mage_Shell_CheckImages();
$shell->run();
@ljay79
Copy link
Author

ljay79 commented Jan 18, 2019

Thanks to @aleron75 for this nice script.
Incorporated the dynamic use of the entity_type_id and persisting any placeholders as revised by @dajve (https://gist.github.com/aleron75/07ab2a950b2e3429a820#gistcomment-2205043).

@ljay79
Copy link
Author

ljay79 commented Jan 18, 2019

Usage

Note: All is executen in your Magento base directory: /path/to/magento/

  1. Check directory size before execution
du -sh
  1. Create a backup of your ./media folder; ie:
sudo cp -rp ./media/ ./media_backup
  1. Create a file and copy the code in:
    ./shell/delete_unused_images.php

  2. Execute file in dry run first (for verifying) or in debug; with argument dry or debug

php ./shell/delete_unused_images.php dry
  1. Now run the script - this will actually delete images on your system!
    Check directory size after execution
php ./shell/delete_unused_images.php

du -sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment