How OpenMage Image Cleaner Detects Orphan Category Images vs. Product Images

OpenMage Image Cleaner identifies orphaned images by comparing physical files in the media directory against database references, using distinct EAV queries for categories (checking only varchar attributes) versus products (checking varchar attributes, media gallery tables, and configurable placeholder images).

OpenMage Image Cleaner is a disk-space recovery tool for Magento 1 and OpenMage LTS that finds image files present on the filesystem but no longer linked to any database records. The extension implements two separate detection algorithms in app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php to handle the architectural differences between how Magento stores category and product image references.

How Category Orphan Detection Works

The category detection process focuses solely on the EAV varchar table for catalog categories, as category images are stored as simple string attributes without gallery support.

Querying the Category EAV Structure

The process begins by identifying the correct entity type ID for categories using Mage::getModel('catalog/category')->getResource()->getTypeId() (lines 28–31). The code then queries the eav_attribute table to find all attributes where frontend_input='image' and the entity_type_id matches the category type (lines 41–43).

These attribute IDs filter a SELECT value FROM catalog_category_entity_varchar query that retrieves every non-empty image path currently assigned to categories (line 44). This yields the complete list of filenames the database considers active.

Scanning the Filesystem and Computing Orphans

The scanner recursively walks Mage::getBaseDir('media') . '/catalog/category' using the helper method Mage::helper('fballiano_imagecleaner')->scandirRecursive() (lines 45–46), stripping the base path to produce relative filenames. A simple array_diff($fs_images, $db_images) (line 48) isolates files existing on disk but absent from the varchar table.

Each detected orphan is inserted into the custom table fb_imagecleaner_image (lines 50–60) with the category entity-type ID, making it available for review and deletion in the admin grid.

How Product Orphan Detection Works

Product detection is more complex because Magento stores product images across multiple tables and supports configurable placeholders.

Collecting Product Image Attributes

Like the category process, this starts by fetching the product entity type ID via Mage::getModel('catalog/product')->getResource()->getTypeId() (lines 66–70). However, it queries eav_attribute for frontend_input='media_image' (lines 79–81)—the input type used for image, small_image, and thumbnail attributes.

The code reads value from catalog_product_entity_varchar for these attributes, strips leading slashes, and explicitly excludes the Magento placeholder value 'no_selection' (lines 81–84).

Unlike categories, products store additional images in the catalog_product_entity_media_gallery table. The scanner pulls all value entries from this table (lines 91–93) to capture gallery images that might not be assigned to the main product attributes.

Additionally, the detection algorithm prevents false positives by treating placeholder images as "used." It queries core_config_data for paths like catalog/placeholder/small_image_placeholder, prepends placeholder/ to those filenames, and includes them in the valid reference set (lines 85–89).

The Set Difference Operation

The final orphan list is computed using array_diff($fs_images, $db_images, $media_gallery) (line 97). Only files not referenced in the main product attributes, the media gallery, or the placeholder list are considered orphaned. Results are stored in fb_imagecleaner_image with the product entity-type ID (lines 99–109).

Shared Filesystem Infrastructure

Both detection methods rely on app/code/community/Fballiano/ImageCleaner/Helper/Data.php for directory traversal. The scandirRecursive() method recursively scans directories while respecting a blacklist that excludes cache, watermark, and .thumbs directories from the orphan calculation. This ensures temporary or system-generated files do not clutter the results.

Practical Usage Examples

Administrators can trigger detection via the admin panel (System → Tools → Image Cleaner) or programmatically:

// Detect orphan category images
Mage::app()->getRequest()
    ->setControllerName('fbimagecleaner')
    ->setActionName('synccategory')
    ->setRouteName('adminhtml')
    ->dispatch();

// Detect orphan product images  
Mage::app()->getRequest()
    ->setControllerName('fbimagecleaner')
    ->setActionName('syncproduct')
    ->setRouteName('adminhtml')
    ->dispatch();

Direct URL access (replace <admin> with your admin front-name):

  • https://example.com/<admin>/fbimagecleaner/synccategory
  • https://example.com/<admin>/fbimagecleaner/syncproduct

Summary

  • Category detection queries only catalog_category_entity_varchar for attributes with frontend_input='image' and compares against files in media/catalog/category.
  • Product detection aggregates references from catalog_product_entity_varchar (media_image attributes), catalog_product_entity_media_gallery, and placeholder configurations from core_config_data.
  • Both processes use array_diff() to isolate files present on disk but missing from the aggregated database references.
  • The shared scandirRecursive() helper in Helper/Data.php handles directory walking with blacklist support for system directories.
  • Detected orphans are persisted to the fb_imagecleaner_image table for administrative review and bulk deletion.

Frequently Asked Questions

What database tables does OpenMage Image Cleaner query for orphan detection?

For categories, the extension queries eav_attribute and catalog_category_entity_varchar. For products, it queries eav_attribute, catalog_product_entity_varchar, catalog_product_entity_media_gallery, and core_config_data (for placeholder paths). These queries run in FbimagecleanerController.php during the synccategoryAction and syncproductAction methods.

Why does product orphan detection require checking placeholder images?

Placeholder images are stored in media/catalog/product/placeholder/ and configured via core_config_data, not referenced in product EAV tables. Without checking these config values, the tool would flag placeholder images as orphans even though they are actively used for products missing images. The code explicitly prepends placeholder/ to these filenames and excludes them from the orphan list (lines 85–89).

How does the extension handle the media directory blacklist?

The scandirRecursive() method in Helper/Data.php accepts a blacklist array containing cache, watermark, and .thumbs. It skips these directories during the recursive scan to prevent system-generated files from appearing in the orphan detection results.

Can I run the orphan detection programmatically without the admin UI?

Yes. You can dispatch the controller actions programmatically using Mage::app()->getRequest() with setControllerName('fbimagecleaner') and setActionName('synccategory') or syncproduct, as shown in the usage examples above. This allows integration with cron jobs or automated maintenance scripts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →