How to Recover Accidentally Deleted Images After Using OpenMage Image Cleaner
Recovering accidentally deleted images requires restoring the physical file from a filesystem backup and re-inserting the database record into the fb_imagecleaner_image table, as the module performs permanent deletion via unlink() without maintaining a recycle bin.
The OpenMage Image Cleaner extension by fballiano/openmage-image-cleaner helps administrators remove unused images from the media directory. However, because the deletion process permanently erases both the physical file and its database reference, accidental removal requires manual recovery procedures outside the module's functionality.
How the OpenMage Image Cleaner Deletes Images
Understanding the deletion mechanism is essential for recovery planning. The module removes images through two primary controller actions in app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php:
File System Deletion:
deleteAction(lines 221-238) andmassDeleteAction(lines 48-71) executeunlink($image_path)to permanently remove the physical file from the media directory.
Database Cleanup:
- The same methods execute
DELETE FROM {$cleaner_table} WHERE image_id=?(lines 33-39 and 65-67) to remove the corresponding row from thefb_imagecleaner_imagetable.
The module does not implement a trash bin, soft delete flag, or backup mechanism. Once unlink() executes, the file is irretrievable without external backups.
Recovery Methods for Deleted Images
Since the OpenMage Image Cleaner performs hard deletions, recovery depends entirely on infrastructure backups:
- Filesystem Backup Restoration: Recover the deleted file from server snapshots, rsync backups, or hosting provider backup systems.
- Database Backup Restoration: Extract the
fb_imagecleaner_imagetable row from a database dump to retrieve the original path and entity type metadata. - Permanent Loss: Without backups, the image cannot be recovered or regenerated by the module.
Step-by-Step Recovery Process
Identify the Missing Image Path
Before restoring, determine the exact relative path of the deleted image:
- Check the Image Cleaner grid (
System → Image Cleaner → Unused Images) if the row hasn't been purged from the display cache. - Query a database backup for the path:
SELECT path, entity_type_id FROM fb_imagecleaner_image WHERE path LIKE '%filename.jpg%'. - The
entity_type_iddetermines the media subdirectory (e.g., 1 for products, 2 for categories), calculated viaFballiano_ImageCleaner_Helper_Data::getMediaDirByEntityTypeId().
Restore the Physical File from Backup
Use a shell script or Magento shell script to copy the file from your backup location to the media directory:
<?php
require 'app/Mage.php';
Mage::app('admin');
$relativePath = 'wysiwyg/catalog/product/abc.jpg'; // From DB backup
$backupFile = '/backups/magento_media/' . $relativePath;
$mediaDir = Mage::getBaseDir('media');
$targetPath = $mediaDir . '/' . $relativePath;
$io = new Varien_Io_File();
if (!$io->fileExists($targetPath) && $io->fileExists($backupFile)) {
$io->cp($backupFile, $targetPath);
echo "File restored to: $targetPath\n";
} else {
echo "File already exists or backup not found.\n";
}
Re-insert the Database Record
After restoring the physical file, recreate the database entry so the Image Cleaner recognizes the image:
<?php
require 'app/Mage.php';
Mage::app('admin');
$resource = Mage::getSingleton('core/resource');
$db = $resource->getConnection('core_write');
$table = $resource->getTableName('fb_imagecleaner_image');
$data = [
'entity_type_id' => 3, // Example: 3 for catalog/product
'path' => 'wysiwyg/catalog/product/abc.jpg',
];
$db->insertOnDuplicate($table, $data);
echo "Database record restored.\n";
Alternatively, use the module's model:
Mage::getModel('fballiano_imagecleaner/image')
->setEntityTypeId(3)
->setPath('wysiwyg/catalog/product/abc.jpg')
->save();
Verify the Recovery
Confirm the restoration by:
- Refreshing the Image Cleaner grid (
app/code/community/Fballiano/ImageCleaner/Block/Adminhtml/Fbimagecleaner/Grid.php) to verify the image appears as "unused". - Using the Download action in the grid (handled by
downloadActionin the controller) to confirm the file is readable and not corrupted.
Key Source Files Involved in Deletion and Recovery
Understanding these files helps when customizing recovery scripts or debugging:
app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php: ContainsdeleteAction,massDeleteAction, anddownloadAction. Lines 221-238 and 48-71 handle the permanent deletion logic.app/code/community/Fballiano/ImageCleaner/Helper/Data.php: ProvidesgetMediaDirByEntityTypeId()to determine the correct media subdirectory (e.g.,catalog/productvs.wysiwyg) andscandirRecursive()for file scanning.app/code/community/Fballiano/ImageCleaner/Model/Image.php: Represents thefb_imagecleaner_imagetable. Use this model to programmatically recreate deleted records during recovery.app/code/community/Fballiano/ImageCleaner/etc/config.xml: Defines the module's configuration, model aliases (fballiano_imagecleaner/image), and database table setup.app/code/community/Fballiano/ImageCleaner/Block/Adminhtml/Fbimagecleaner/Grid.php: Renders the admin interface where you verify recovered images appear in the unused images list.
Summary
- OpenMage Image Cleaner performs hard deletes using
unlink()on physical files andDELETESQL statements on database records, leaving no internal recovery mechanism. - Recovery requires external backups: You must restore the file from filesystem backups (server snapshots, rsync, or hosting backups) and restore the database row from SQL dumps.
- Manual restoration process: Identify the path from backups, copy the file to the media directory using
Varien_Io_File, and re-insert the record intofb_imagecleaner_imageusing theFballiano_ImageCleaner_Model_Imagemodel or raw SQL. - Prevention is critical: Since the module cannot regenerate deleted images, always verify backups exist before running mass deletion operations.
Frequently Asked Questions
Can I recover images without a backup?
No. Because the OpenMage Image Cleaner executes unlink($image_path) to permanently delete physical files and removes the database reference without maintaining a trash bin or archive, recovery is impossible without a filesystem or database backup. If no backups exist, the images are permanently lost.
Where does OpenMage Image Cleaner store deleted images?
The module does not store deleted images. Unlike systems with a "recycle bin" feature, the deleteAction and massDeleteAction methods in FbimagecleanerController.php immediately erase files from the media directory (e.g., media/catalog/product/ or media/wysiwyg/) using PHP's unlink() function.
How do I prevent accidental deletion in the future?
Implement a pre-deletion backup workflow before using the Image Cleaner. Create a server snapshot or run rsync to backup the media/ directory and the fb_imagecleaner_image database table. Additionally, modify the module's behavior by extending FbimagecleanerController.php to move files to an archive directory instead of calling unlink(), though this requires custom development.
What database table stores the image records?
The module uses the fb_imagecleaner_image table (defined in config.xml and mapped via Fballiano_ImageCleaner_Model_Image). This table stores the image_id, entity_type_id (mapping to media subdirectories), and path (relative to the media directory). Recovery requires re-inserting rows into this table with the correct entity_type_id and path values.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →