Understanding entity_type_id Mapping in OpenMage Image Cleaner: Negative vs Positive Values

The Image Cleaner uses positive entity_type_id values (3, 4) for real Magento EAV entities (categories and products) and negative values (-4, -98) as synthetic flags to identify product cache thumbnails and standalone WYSIWYG assets that lack a true entity association.

The fballiano/openmage-image-cleaner extension tracks unused media files in the fb_imagecleaner_image table, relying on an entity_type_id mapping system to categorize each image's origin. Understanding when this mapping uses negative versus positive values is essential for developers customizing cleanup logic or extending the module to handle additional media types.

entity_type_id Value Mapping in the Database

Each row in fb_imagecleaner_image stores an entity_type_id that determines the media subdirectory and the nature of the file. The mapping distinguishes between genuine EAV entity types and synthetic identifiers for special media groups.

entity_type_id Meaning Media Folder
3 Category images (catalog/category) media/catalog/category/
4 Product images (catalog/product) media/catalog/product/
-4 Product cache images (catalog/product/cache) media/catalog/product/ (same base folder; negative flag indicates cache source)
-98 WYSIWYG files (wysiwyg) media/wysiwyg/

Why Negative Values Are Used for Non-EAV Assets

Negative entity_type_id values are synthetic markers rather than real Magento entity types. They allow the cleaner to store disparate media types in a single table while maintaining a clear distinction between EAV-backed assets and auxiliary files.

Product Cache Images (-4)

The value -4 represents product image cache thumbnails stored under media/catalog/product/cache/. The controller derives this by negating the standard product entity type ID (4) in app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php at line 117:

$entity_type_id = -Mage::getModel('catalog/product')->getResource()->getTypeId(); // Results in -4

The helper method getMediaDirByEntityTypeId() does not contain a specific case for -4 because both 4 and -4 resolve to the same base directory (media/catalog/product/). The negative sign serves solely as a flag for the synchronization logic to indicate the source is the cache subdirectory.

WYSIWYG Files (-98)

The value -98 identifies WYSIWYG editor files located in media/wysiwyg/. These assets are not attached to any Magento entity and therefore lack a natural entity type ID. The controller hardcodes this value in app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php at line 165:

$entity_type_id = -98;

This synthetic ID allows the cleaner to track orphaned WYSIWYG images using the same table structure as entity-bound assets.

Technical Implementation in the Codebase

The support for negative values requires specific database schema adjustments and logic in the controller and helper classes.

Database Schema Support for Signed Integers

The entity_type_id column must accept negative integers. The install script app/code/community/Fballiano/ImageCleaner/sql/fballiano_imagecleaner_setup/install-0.1.0.php creates the table, while the upgrade script app/code/community/Fballiano/ImageCleaner/sql/fballiano_imagecleaner_setup/upgrade-1.0.0-1.1.0.php explicitly modifies the column to SMALLINT SIGNED at line 19:

$installer->run("ALTER TABLE {$installer->getTable('fb_imagecleaner_image')} CHANGE COLUMN entity_type_id entity_type_id SMALLINT SIGNED NOT NULL;");

This schema change enables the storage of negative markers without database constraint errors.

Controller Logic and ID Assignment

The Adminhtml/FbimagecleanerController.php assigns entity_type_id values based on the synchronization context. For standard entities, it queries the EAV resource:

// Category sync (lines 30-31)
$entity_type_id = Mage::getModel('catalog/category')->getResource()->getTypeId(); // Returns 3

// Product sync (lines 68-69)
$entity_type_id = Mage::getModel('catalog/product')->getResource()->getTypeId(); // Returns 4

For special cases, it negates or hardcodes values:

// Product cache sync (line 117)
$entity_type_id = -Mage::getModel('catalog/product')->getResource()->getTypeId(); // Returns -4

// WYSIWYG sync (line 165)
$entity_type_id = -98;

Helper Resolution of Media Directories

The helper class app/code/community/Fballiano/ImageCleaner/Helper/Data.php translates entity_type_id into filesystem paths via getMediaDirByEntityTypeId() (lines 35-42):

public function getMediaDirByEntityTypeId($entity_type_id)
{
    $media_dir = Mage::getBaseDir('media') . '/';

    if ($entity_type_id == 3)   return "{$media_dir}catalog/category/";
    if ($entity_type_id == 4)   return "{$media_dir}catalog/product/";
    if ($entity_type_id == -98) return "{$media_dir}wysiwyg/";

    return $media_dir;
}

Notice the absence of a case for -4; the method treats it identically to 4, returning media/catalog/product/. The negative value's significance is consumed entirely by the synchronization logic that populates the table.

Working with entity_type_id in Custom Code

When extending the Image Cleaner or building reports, always use the helper to resolve paths rather than hardcoding logic based on the ID sign.

Retrieve the media folder for a stored image

/** @var Fballiano_ImageCleaner_Helper_Data $helper */
$helper = Mage::helper('fballiano_imagecleaner');

/* $row is a record from fb_imagecleaner_image */
$mediaDir = $helper->getMediaDirByEntityTypeId($row['entity_type_id']);
$fullPath = $mediaDir . $row['path'];

Insert a new unused image record

When manually inserting records for cache or WYSIWYG files, preserve the negative ID convention:

$entity_type_id = -Mage::getModel('catalog/product')->getResource()->getTypeId(); // –4
$path           = 'cache/some/unused_image.jpg';

$cleanerTable = $resource->getTableName('fb_imagecleaner_image');
$db->insert($cleanerTable, [
    'entity_type_id' => $entity_type_id,
    'path'           => $path
]);

Delete an image using the stored ID

$imageId = 123; // from request
$row = $db->fetchRow("SELECT * FROM {$cleanerTable} WHERE image_id = ?", $imageId);
$fullPath = $helper->getMediaDirByEntityTypeId($row['entity_type_id']) . $row['path'];

if (file_exists($fullPath) && unlink($fullPath)) {
    $db->query("DELETE FROM {$cleanerTable} WHERE image_id = ?", $imageId);
}

Summary

  • Positive entity_type_id values (3, 4) represent genuine Magento EAV entity types for categories and products, fetched dynamically from resource models.
  • Negative entity_type_id values (-4, -98) are synthetic markers invented by the extension to track product cache thumbnails and WYSIWYG files that lack true entity associations.
  • The database schema explicitly supports negatives via SMALLINT SIGNED in upgrade-1.0.0-1.1.0.php, allowing these markers to be stored without constraint violations.
  • The helper method getMediaDirByEntityTypeId() ignores the negative sign for -4, treating it identically to 4, while explicitly handling -98 for WYSIWYG paths.

Frequently Asked Questions

What happens if I manually change a negative entity_type_id to positive in the database?

Converting -4 to 4 or -98 to 98 causes the helper method getMediaDirByEntityTypeId() to return the default media directory instead of the specific WYSIWYG path, potentially breaking deletion logic. For -4, the path resolution still works because both map to catalog/product/, but the sync controller will treat the record as a standard product image during reconciliation, which may cause duplicate detection errors or cache regeneration issues.

Why does the helper not have a specific case for -4 in getMediaDirByEntityTypeId?

The helper method intentionally omits a branch for -4 because both product images (4) and product cache images (-4) reside under the same base directory media/catalog/product/. The negative value acts purely as a logical flag for the synchronization controller to indicate the image originated from the cache subdirectory, while the filesystem resolution remains identical to standard product media.

Can I add custom negative entity_type_id values for other media types?

Yes, the SMALLINT SIGNED column type supports custom negative values ranging from -32768 to -1 for extension-specific purposes. To implement a new media type (such as -10 for custom module uploads), modify getMediaDirByEntityTypeId() in Helper/Data.php to return the appropriate base directory, and update the relevant controller sync action to populate the table using your chosen negative constant.

How does the database schema support negative entity_type_id values?

The installation script install-0.1.0.php creates the entity_type_id column, but the critical support for negatives comes from upgrade-1.0.0-1.1.0.php at line 19, which executes ALTER TABLE ... CHANGE COLUMN entity_type_id entity_type_id SMALLINT SIGNED NOT NULL. This explicit type change to signed smallint allows the storage of negative markers without database constraint violations.

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 →