{"id":365534,"date":"2026-09-11T02:58:17","date_gmt":"2026-09-11T02:58:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/product-twenty-media-usage\/"},"modified":"2026-09-11T02:58:04","modified_gmt":"2026-09-11T02:58:04","slug":"product-twenty-media-usage","status":"publish","type":"plugin","link":"https:\/\/ml.wordpress.org\/plugins\/product-twenty-media-usage\/","author":23558041,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1","requires":"6.6","requires_php":"7.4","requires_plugins":null,"header_name":"Product Twenty Media Usage","header_author":"Product Twenty","header_description":"Find where Media Library images are referenced and surface images with no references found.","assets_banners_color":"f9f7f2","last_updated":"2026-09-11 02:58:04","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/producttwenty.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":39,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"producttwenty","date":"2026-09-11 02:58:04","revision":3690679}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3690679,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3690679,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3690679,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3690679,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3690679,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Media Usage &gt; Usage Index with resumable scan progress and status filters.","2":"Media Library grid badges showing usage status on thumbnails.","3":"Attachment details showing where references were found, with a protection control.","4":"Media Library list filter for In use, Referenced, Needs review, and related\nstatuses.","5":"Media Usage dashboard with index health, storage estimate, source totals,\nand skipped-source recovery details."}},"plugin_section":[],"plugin_tags":[1346,163,84,233,146945],"plugin_category":[50],"plugin_contributors":[279062],"plugin_business_model":[],"class_list":["post-365534","plugin","type-plugin","status-publish","hentry","plugin_tags-attachments","plugin_tags-images","plugin_tags-media","plugin_tags-media-library","plugin_tags-unused-images","plugin_category-media","plugin_contributors-producttwenty","plugin_committers-producttwenty"],"banners":{"banner":"https:\/\/ps.w.org\/product-twenty-media-usage\/assets\/banner-772x250.png?rev=3690679","banner_2x":"https:\/\/ps.w.org\/product-twenty-media-usage\/assets\/banner-1544x500.png?rev=3690679","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/product-twenty-media-usage\/assets\/icon.svg?rev=3690679","icon":"https:\/\/ps.w.org\/product-twenty-media-usage\/assets\/icon.svg?rev=3690679","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Product Twenty Media Usage builds a local index of image references across\nWordPress content, metadata, templates, builder data, and relevant site\nsettings.<\/p>\n\n<p>It adds:<\/p>\n\n<ul>\n<li>In use, Referenced, Needs review, No references found, Protected,\nand Not scanned statuses.<\/li>\n<li>Usage filters and status badges in the Media Library.<\/li>\n<li>Reference details in the attachment view showing where an image was found,\nsuch as Elementor widgets, Divi modules, Uncode Content Blocks, WPBakery\nelements, and ACF fields.<\/li>\n<li>A Media Usage dashboard with index health, pending incremental work, recent\nindex activity, status totals, estimated reclaimable image space, source\ntotals, and named skipped-source details.<\/li>\n<li>A top-level Media Usage menu with Dashboard and Usage Index screens.<\/li>\n<li>Incremental rescans after content, builder data, or image files change.<\/li>\n<li>Manual protection for images that should not be considered for cleanup.<\/li>\n<\/ul>\n\n<p>The scanner recognizes tested database patterns for normal WordPress blocks\nand Classic Editor content; media values in Elementor <code>_elementor_data<\/code> and\n    _elementor_page_settings; media-shaped attributes in WPBakery <code>[vc_*]<\/code>,\nUncode <code>[uncode_*]<\/code>, and Divi <code>[et_pb_*]<\/code> shortcodes; and structured media\nvalues stored in Divi <code>_et_*<\/code> post metadata. It also reads ACF image, gallery,\nand file fields when their field definitions are available, including common\nACF Options Page storage. It recognizes attachment IDs, WordPress image\nclasses, original URLs, resized image URLs, and exact uploads-relative CDN\npaths.<\/p>\n\n<p>Source labels describe where a match was found. They do not claim support for\nevery builder release, every widget, or every theme option screen. Builder\nformats change over time. Media Usage reports skipped or unusually complex\nsources and marks zero-match images Needs review when scan coverage is\nincomplete instead of claiming they have no references.<\/p>\n\n<p>The dashboard explains why each source was skipped and shows its measured value\nand normal safety limit. A separate protected retry processes one named source\nper request with higher but still finite limits. Only after every skipped source\nis resolved are affected image statuses repaired in small batches.<\/p>\n\n<p>The plugin deliberately says \u201cNo references found,\u201d not \u201cUnused.\u201d Custom code,\nexternal systems, conditional output, and inaccessible resources can contain\nreferences that a database scanner cannot prove do not exist.<\/p>\n\n<p>Media Usage does not delete files, alter content, contact an external service,\nor collect telemetry.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>product-twenty-media-usage<\/code> folder to <code>\/wp-content\/plugins\/<\/code> or\ninstall the release ZIP.<\/li>\n<li>Activate <strong>Product Twenty Media Usage<\/strong>.<\/li>\n<li>Open <strong>Media Usage &gt; Dashboard<\/strong>.<\/li>\n<li>Select <strong>Build usage index<\/strong>.<\/li>\n<\/ol>\n\n<p>The first scan processes existing sites in small, resumable batches. WordPress\nthen keeps the index current as content and supported settings change. Rebuilds\nare created as a separate generation; the last successful index remains active\nuntil the replacement is complete.<\/p>\n\n<p>Activation does not inspect the filesystem or scan content. Scan requests have\nshort time, memory, traversal, candidate, recursion, and reference-count\nceilings. Oversized or unusually complex sources are skipped with a visible\nwarning instead of being loaded or processed without a bound. A failed source\nkeeps its previously saved matches, and transient batch failures receive three\nbounded retries. Incremental rescans are paused during imports and replaced by\none deduplicated catch-up reconciliation. Noisy meta such as edit locks is\nignored so large editorial sites are not flooded.<\/p>\n\n<p>Image uploads, file replacements, and regenerated image metadata refresh only\nthat image's indexed status and known file size. The dashboard shows queued\nincremental jobs and retains only the newest 100 source-level activity entries;\nit does not create a per-reference audit log or write scanner logs to disk.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20%E2%80%9Cno%20references%20found%E2%80%9D%20mean%20an%20image%20is%20definitely%20unused%3F\"><h3>Does \u201cNo references found\u201d mean an image is definitely unused?<\/h3><\/dt>\n<dd><p>No. It means the latest complete scan found no reference in the sources the\nplugin can inspect. Theme files, custom PHP, remote content, inaccessible pages,\nor conditional JavaScript may still use an image.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20delete%20images%3F\"><h3>Does the plugin delete images?<\/h3><\/dt>\n<dd><p>No. The base plugin is an inspection and classification tool only.<\/p><\/dd>\n<dt id=\"why%20is%20an%20image%20marked%20%E2%80%9Creferenced%E2%80%9D%3F\"><h3>Why is an image marked \u201cReferenced\u201d?<\/h3><\/dt>\n<dd><p>It was found in a draft, private item, reusable block, saved layout, or builder\ntemplate rather than directly in published page content.<\/p><\/dd>\n<dt id=\"why%20is%20an%20image%20with%20zero%20references%20marked%20%E2%80%9Cneeds%20review%E2%80%9D%3F\"><h3>Why is an image with zero references marked \u201cNeeds review\u201d?<\/h3><\/dt>\n<dd><p>The latest scan could not inspect at least one source completely, so zero\nreferences is not yet a safe cleanup conclusion. Open <strong>Media Usage &gt; Dashboard<\/strong>\nto see the exact skipped source and safety limit. The protected retry checks one\nskipped source per request without rerunning the full site.<\/p><\/dd>\n<dt id=\"which%20builders%20are%20covered%3F\"><h3>Which builders are covered?<\/h3><\/dt>\n<dd><p>The scanner recognizes tested database patterns: media values in Elementor\n    _elementor_data and <code>_elementor_page_settings<\/code>; media-shaped attributes in\nWPBakery <code>[vc_*]<\/code>, Uncode <code>[uncode_*]<\/code>, and Divi <code>[et_pb_*]<\/code> shortcodes; and\nstructured media values stored in Divi <code>_et_*<\/code> post metadata. Matches are\nlabeled with the detected provider in the attachment details. This is\npattern-specific recognition, not a promise that every release, widget, or\ntheme option is covered. Because builders change, a full reconciliation is\nscheduled 30 days after each successful scan. Installing the plugin does not\nstart or schedule the first scan.<\/p><\/dd>\n<dt id=\"what%20custom%20fields%20are%20supported%3F\"><h3>What custom fields are supported?<\/h3><\/dt>\n<dd><p>URL-based references in post metadata are inspected generally. ACF image,\ngallery, and file fields receive dedicated attachment-ID handling when their\nfield definitions are available. Developers can declare other ID-based custom\npost-meta fields through <code>product_twenty_media_usage_is_media_meta_field<\/code>, and\nID-based values in relevant site options through\n    product_twenty_media_usage_is_media_option. Arbitrary numeric custom fields\nare not assumed to be image IDs because doing so would create false matches.<\/p><\/dd>\n<dt id=\"does%20scanning%20send%20site%20data%20anywhere%3F\"><h3>Does scanning send site data anywhere?<\/h3><\/dt>\n<dd><p>No. Scanning and storage remain inside the WordPress installation.<\/p><\/dd>\n<dt id=\"what%20happens%20on%20uninstall%3F\"><h3>What happens on uninstall?<\/h3><\/dt>\n<dd><p>The relationship index, scan state, statuses, and manual protection flags are\nremoved. Media files and site content are not modified.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20multisite%3F\"><h3>Does it work with multisite?<\/h3><\/dt>\n<dd><p>The plugin can be activated on an individual site. Network-wide activation and\nnetwork-level reporting have not been declared or tested.<\/p><\/dd>\n<dt id=\"is%20this%20the%20base%20for%20a%20future%20pro%20version%3F\"><h3>Is this the base for a future Pro version?<\/h3><\/dt>\n<dd><p>Yes. This plugin is the canonical, independently useful base. Product Twenty\nMedia Usage Pro is a separate optional companion using the documented extension\nAPI. The base contains no locked controls or licensing requests.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial public release.<\/li>\n<\/ul>","raw_excerpt":"Find where Media Library images are referenced and review images with no references found.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/365534","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=365534"}],"author":[{"embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/producttwenty"}],"wp:attachment":[{"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=365534"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=365534"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=365534"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=365534"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=365534"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ml.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=365534"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}