Linux 软件免费装
Banner图

Media Mage

开发者 ltracy
更新时间 2026年8月31日 22:53
捐献地址: 去捐款
PHP版本: 7.4 及以上
WordPress版本: 7.1
版权: GPLv2 or later
版权网址: 版权信息

标签

media library cleanup wp-cli unused media duplicate images

下载

1.0.0

详情介绍:

Media Mage scans your media library for two kinds of clutter: A tool that deletes files is only as good as the search it runs first, because anything the search misses gets reported as unused and then deleted. Most of the work in this plugin is in that search, and in the guards that sit between the search result and the delete. What counts as a reference Media Mage checks all of the following before it will call a file unused: Each of those is checked against every URL the attachment can appear under: the full-size file, every generated size variant, the -scaled version and the preserved original. Inserting an image at Medium embeds the medium URL and never the full-size one, so checking only the full-size URL is how a live image ends up on an unused list. URLs are also matched in their JSON-escaped form (\/ instead of /), which is how Elementor, Divi and Gutenberg block attributes store them. What it cannot see Media Mage reads the database. It does not read your code. It will not find: If your theme prints wp-content/uploads/2026/01/hero.jpg straight out of a template file, that image is reported as unused. Review the list before deleting. There is a wpmj_is_referenced filter for protecting files programmatically - see the FAQ. One more thing worth knowing, because it works the other way: an attachment whose post_parent points at a post that still exists counts as referenced. Most images uploaded through the post editor have one, so on a long-lived site the unused list will be shorter than you expect. That is deliberate - it errs toward keeping files - but it is why a scan can come back nearly empty on a site you were certain was full of clutter. How it avoids breaking your site Other things it does Free, and staying that way No pro tier, no license key, no upsell. If it saved you an afternoon you can buy me a coffee. Never required.

安装:

  1. Upload the media-mage folder to /wp-content/plugins/, or install the zip through Plugins > Add New > Upload Plugin.
  2. Activate it on the Plugins screen.
  3. Go to Media > Media Mage.
  4. Click Scan Media Library.
Before your first scan

屏幕截图:

  • The unused list. Every file here was checked against twelve places first, and the notice is a standing reminder that a database scan cannot read your theme's PHP.
  • Nothing is deleted without naming the files first. Cancel leaves the library untouched.
  • Removals go to the trash and stay on disk. Restore puts a file back; emptying the trash is the separate step that actually reclaims the space.
  • A scan in progress. The log names every file as it goes, so a run that misses something is visible rather than silent.

升级注意事项:

1.0.0 First public release. Deleting sends media to the trash rather than removing it, every file is re-checked against the full reference search immediately before it is touched, and duplicate resolution re-points every reference - including size variants - before anything is deleted.

常见问题:

Will this break my site?

It is built not to, and the design assumes it will be run on a site nobody has a recent backup of. Deleting unused media moves files to the trash rather than removing them, and every file is re-checked against the whole reference search immediately before it is touched. Resolving a duplicate rewrites every reference to the keeper - full-size URL, every size variant, the -scaled and original siblings, and the JSON-escaped forms - before the duplicate is removed. Take a backup anyway. Any tool that can delete media can delete the wrong media.

What does it miss?

References that live in code rather than in the database. Theme PHP, plugin PHP, child-theme templates, and anything served through a CDN URL that does not match what is stored. Media Mage cannot see those and does not pretend to. Read the unused list before acting on it.

How big a media library can it handle?

Comfortably up to a couple of thousand attachments in the browser. Past that, use WP-CLI. The honest version: finding duplicates is cheap and scales linearly. Finding unused media is not. Every attachment is checked against post content, post meta, term/user/comment meta, options and comments, and those are substring searches that no database index can help with. The cost of each check grows with the size of the library, so the total grows faster than the number of files does. Measured on a test fixture (2 KB images, 3,000 posts, 70% of the library referenced), on a developer machine rather than production hardware:

  • 1,000 attachments - about 90 seconds
  • 5,000 attachments - roughly 40 minutes
  • 20,000 attachments - many hours
Your numbers will differ, and larger image files make the hashing step slower without affecting the rest. Treat these as the shape of the curve, not a promise. What this means in practice: on a small or medium site, scan from the admin screen. On a large one, run wp media-mage scan from the command line, where there is no request timeout, and then use wp media-mage unused and wp media-mage delete --dry-run to review before acting. Making the unused scan fast on very large libraries is the main thing on the list for the next version.

How do I protect a file it keeps reporting as unused?

Add it to the ignore list. Ignored files stay in the media library and stop appearing in the unused results. For anything you want handled in code, the wpmj_is_referenced filter runs last, after every built-in check has come up empty, and receives the attachment ID and every URL path that was checked: add_filter( 'wpmj_is_referenced', function ( $referenced, $att_id, $paths ) { if ( in_array( $att_id, [ 42, 108 ], true ) ) { return true; } return $referenced; }, 10, 3 );

Does it work with Oxygen Builder?

Yes, and this is why the plugin exists. Oxygen stores layouts as base64-encoded post meta and options. Read those values as plain text and no image reference in them is visible, so an Oxygen site looks like it has hundreds of unused images. Media Mage decodes that data and searches inside it, matching on full paths rather than bare filenames so logo.png does not match site-logo.png.

Does it work with Elementor, Divi, Gutenberg and ACF?

Yes. All four store their data in post content or post meta, where the URL search reaches, including the JSON-escaped slashes that block attributes and JSON meta use. Gutenberg blocks that carry an attachment ID and no URL are matched on the ID and on the wp-image-N class.

What about images used only in trashed posts?

They count as referenced. Trash is restorable, and deleting the images out from under a trashed post breaks the restore.

Can I undo a duplicate resolution?

No. Resolving rewrites the references to the keeper and then removes the duplicate for good. The site keeps rendering, because every reference now points at the keeper, but the file is gone. Deleting unused media is the reversible one, up until the trash is emptied.

How fast is it?

The hash phase runs 50 attachments per request, the reference phase 25, and hashes are cached against file mtime so a second scan skips the hashing work for anything that has not changed. On a test fixture of 500 attachments across 38 posts, a full first scan takes roughly 30 to 40 seconds. Larger libraries scale roughly linearly.

Is there a command line interface?

Yes. Every operation the admin screen performs is available under wp media-mage: wp media-mage scan wp media-mage duplicates --format=json wp media-mage unused wp media-mage where <id> wp media-mage resolve --dry-run wp media-mage delete --dry-run wp media-mage delete --permanent --yes wp media-mage export --file=report.csv wp media-mage ignore add <id>... wp media-mage ignore list wp media-mage trash list wp media-mage trash restore <id>... wp media-mage trash empty --yes resolve and delete both take --dry-run, which reports exactly what would happen and changes nothing. Use it first.

Is there a Pro version?

No. This plugin is free, GPLv2, and intentionally has no premium tier. If it's useful to you, a coffee is a kind way to say thanks.

Does it work on multisite?

The scan runs per site. Uninstall cleans up its data on every site in the network.

更新日志:

1.0.0 - 2026-08-04 First public release. Everything below is relative to 0.3.0. Fixed - would not activate Fixed - data loss Fixed - reliability and security Added Fixed - found by later adversarial passes over the same day's work Added - reliability 0.3.0 - 2026-04-26 0.2.0 - 2026-04-08 0.1.0 - 2026-04-06