This plugin adds a Tools → Media Checker admin page where you can:
- run an automatic batch cleanup (AJAX, chunked processing with progress bar)
- review a paginated list of all images
- manually select and delete only those images that are confirmed unused
The core of the plugin is an 11-step “in-use” detector that checks common WordPress and WooCommerce locations (content, product galleries, taxonomy metadata, widgets/options, Customizer settings, site logo and favicon, etc.).
If an image is detected as in use, it is protected from deletion, and the interface clearly shows where the image is used.
What it does
Admin interface (Tools → Media Checker)
- Adds a management page under Tools
- Shows a paginated table of images with:
- thumbnail preview
- attachment title + ID
- usage status (in use / unused)
- total disk size including generated thumbnails
- “usage source” label (what triggered the protection)
Manual deletion mode
- Only images detected as unused are selectable
- Uses a nonce-protected form submission
- Deletes selected attachments permanently
Batch (automatic) cleanup
- Scans the entire Media Library via AJAX in batches of 100
- Shows a progress bar and live stats:
- scanned items
- deleted items
- freed disk space
- Designed to avoid timeouts by chunking requests
Accurate size calculation
- Calculates disk usage as:
- original uploaded file size
- plus every generated thumbnail size registered in attachment metadata
“In use” detection logic (11 checks)
For each image attachment ID, the plugin tries to prove it’s referenced somewhere.
If it finds a match, it returns a human-readable label and the image is considered protected.
- Featured image / product image
Checks_thumbnail_idinpostmeta. - WooCommerce product gallery
Checks_product_image_galleryandFIND_IN_SET(). - Embedded inside post content
Searches published post content for:
- the full image URL
- the Gutenberg class pattern
wp-image-{ID}
- Taxonomy thumbnail
Checkstermmeta.thumbnail_id(commonly used by Woo categories and similar taxonomies). - Taxonomy description
Searchesterm_taxonomy.descriptionfor the URL orwp-image-{ID}. - Taxonomy meta fields
Searchestermmeta.meta_valuefor:
- URL match
- direct numeric ID match
- ACF / custom fields (non-hidden meta keys)
Checkspostmetawheremeta_value = attachment IDandmeta_keydoes not start with_. - Widgets / site options
Searcheswp_options.option_valuefor:
- the attachment ID
- and the attachment URL
(Used as a broad “this might be referenced in widgets/settings” safety net.)
- Site Logo
Compares the attachment ID toget_theme_mod('custom_logo'). - Site Icon / favicon
Compares the attachment ID toget_option('site_icon'). - Customizer theme mods
Scans allget_theme_mods()values for either:
- numeric ID match
- URL substring match
If found, reports which Customizer setting contains the reference.
If none of the checks hit, the image is treated as unused and becomes eligible for deletion.
How the batch cleanup works (AJAX flow)
- Fetch all image attachment IDs
wp_ajax_muc_get_all_imagesreturns a full ID list (posts_per_page => -1)
- Process IDs in chunks
wp_ajax_muc_process_batchreceives up to 100 IDs- For each ID:
- run the 11-step check
- if unused → calculate size →
wp_delete_attachment( $id, true )
- Returns:
- number of deleted images
- total bytes freed
- Frontend loop continues
- updates progress bar
- keeps running until all IDs are processed
- retries after 3 seconds if an AJAX request fails
Important notes (very important)
1) This plugin permanently deletes files
It calls:
wp_delete_attachment( $id, true );That means:
- the attachment post is removed
- the original file and generated thumbnails are deleted from disk
2) Performance considerations
- Batch mode is chunked to reduce timeouts – good.
- However, the “get all IDs” step loads the entire image ID list at once. On huge media libraries, that can be heavy.
3) Be aware
This logic is strong, but not omniscient. Images can still be referenced in ways not covered here, for example:
- CSS files (background-image URLs)
- theme templates hardcoding URLs
- page builder data stored in custom tables
- JSON in custom meta keys starting with
_(your ACF check skips hidden keys) - WooCommerce variation images via
_thumbnail_idare covered, but other plugin-specific storage may not be
Where it fits best
- Large WooCommerce sites that accumulated thousands of old images
- Cleanup before migration / backup size reduction
- Sites where editors upload lots of media and never reuse it
Reviews
There are no reviews yet.