AVAR Media Optimizer Changelog

= 1.23.0 =

* Added: media used only as a social share image in All in One SEO is now detected; that plugin stores it in its own table rather than in post meta. Yoast, Rank Math, SEOPress and The SEO Framework were already detected.
* Added: the avar_mo/external_tables filter, so any plugin keeping media references in its own table can be read the same way. Table and column names are validated against the live schema before anything is read.
* Added: Disk files now reports whether anything links to each file, and which page the link was found on. "No link found" is reported only after a completed scan.
* Added: the trash records requests for files it is holding. A 404 for a trashed file, in any of its generated sizes, is counted against that item with the page that asked, while the item is still restorable. This is the only evidence that can exist for a reference no database holds — an og:image printed by a theme template, or a link from another site. A count proves the file is wanted; silence proves nothing, and the column never claims otherwise.
* Added: Diagnostics reports whether requests for missing media reach WordPress on your server at all. They do not if the server answers static files itself, and they do not with permalinks set to Plain, where WordPress redirects instead of returning 404.
* Changed: database version 14: new table avar_mo_path_refs, holding references to uploads paths that no attachment owns.
* Changed: database version 15: request counters on the trash table.
* Changed: database version 16: restore step names are stored in full (they were cut at 20 characters, so an interrupted restore could not be recognized), and the database upgrade after an update runs in wp-admin, WP-Cron or WP-CLI instead of during a visitor's page view.
* Changed: database version 17: path references are keyed by a hash of the whole path instead of its first 150 characters, so two long file names that start alike are no longer counted as one. A part of an upgrade that protects no file (the trash request counters, this hash) no longer pauses media operations when it cannot be completed; it is retried, and Diagnostics says so.
* Changed: the embedded AVAR Tools library is 1.4.5, a superset of every copy shipped by other AVAR plugins. 1.22.4 carried an older copy numbered higher than newer ones, which caused a critical error with AVAR Analytics 1.2.2.
* Changed: detection revision 5. A scan now records something it used to discard, so results from an earlier version cannot answer the new questions. The Disk files column reports "Rescan needed" rather than claiming nothing links to a file, and moving to the trash and Scheduled Cleanup ask for a new scan first, as they already do after any change in what the scanner can see.
* Fixed: deleting an image (Delete permanently), "Delete all next-gen", Media Replace and the full uninstall could delete another Media Library image whose file is named like a next-gen copy, for example photo.jpg.webp or photo.jpg.avif next to photo.jpg, also when the names differ only in letter case on Windows and macOS. Such files are now kept, and "Delete all next-gen" says how many it kept. On multisite, the full uninstall checks each site's own media.
* Fixed: on Windows and macOS, optimizing an image could write its WebP/AVIF copy over another image whose name differs only in letter case.
* Fixed: a critical error on hosts that disable the PHP function disk_free_space (moving to the trash, Diagnostics, optimizing with a backup, Media Replace).
* Fixed: media whose only use was added after the last scan was offered for cleanup: a video or audio poster, an image in a media description or caption, a category or profile image, an image linked in a comment, and a social image stored by All in One SEO. All in One SEO writes its own table without telling WordPress, so its tables are compared with the last scan before anything is moved to the trash.
* Fixed: media shown through a post's attached files was treated as unused and could be cleaned up while still shown on the page: a gallery or playlist without an ids list ([gallery], [gallery id="…"], [playlist]), a [video] or [audio] shortcode that names no file, and a Dynamic Gallery block using attached images, also inside a synced pattern. Attaching, detaching or uploading media to such a post updates the result immediately.
* Fixed: images in a gallery or playlist shortcode inside a widget (Text widget, Shortcode block), including one showing another post's images, were treated as unused.
* Fixed: media added to a post, a featured image or an option while a scan was running could be marked unused and offered for cleanup; canceling a scan during its last step ("Evaluating results") marked finished results as canceled and stopped keeping them up to date until the next scan.
* Fixed: images referenced only late in a long or nested JSON gallery (past the first 4 000 characters, after a nested list, or after a bracket inside a caption), from an "ids" list of media objects, or from a theme setting saved as text were offered for cleanup. These references are read as cautious evidence, so the image is placed in "Verify manually" rather than being treated as certainly used.
* Fixed: images referenced through an HTML-entity or percent-encoded URL (for example &quot; in a slider attribute, or %22 in custom CSS) were reported as unused.
* Fixed: on MySQL 8 and newer, a single very long unbroken value in post, term or user meta or in an option made every scan fail with a regular-expression timeout. Such a value is now read in smaller windows and its references are still found.
* Fixed: on servers running without PCRE JIT, a value the scanner could not fully read was silently treated as containing no media; results are now cautious ("Verify manually") instead.
* Fixed: the Overview and Results explanation of why files are marked "Verify manually" was stored in the language the scan ran in, so it could appear in another language, and it described a too-large value or a custom uploads folder as if it were a plugin.
* Fixed: restoring from the trash stripped backslashes from the image's title, caption, description and metadata and from block content updated to point back to it, and could stop for manual review because of them. Restoring the same image a second time no longer stops for manual review.
* Fixed: moving to the trash and restoring refused to run on a volume with less than 500 MB free, even for a small file; the check now asks for room for the files being copied plus a margin (15%, at least 10 MB), which the avar_mo/space_reserve filter can still raise.
* Fixed: when another plugin stopped WordPress from deleting an attachment, a move to the trash could still remove its files. The deletion is now confirmed by reading the attachment back before any file is touched.
* Fixed: a failed rebuild of the media ownership safety index, recorded by one request, could be overwritten by another request that read a cached copy, and its safety lock could later be cleared.
* Fixed: a recovery copy set aside during a failed Media Replace could be deleted when the uploads storage was briefly unreachable during the daily cleanup.
* Fixed: optimizing an animated PNG (or an animated WebP on servers using Imagick) kept only its first frame. Animated images are now skipped and get no next-gen copy.
* Fixed: next-gen conversion ignored the next-gen quality setting, could write a JPEG under a .jpg name next to the image when the server's first image library cannot write WebP/AVIF, and, when interrupted, could leave an empty file that was served to visitors.
* Fixed: optimizing on upload discarded metadata that other plugins add during upload (for example focal points).
* Fixed: with "Optimize anyway, without keeping a recovery copy" selected, the Optimize tab claimed optimization was paused and the Backups card promised backups.
* Fixed: Disk files listed WebP/AVIF copies named like photo.webp, and next-gen files recorded in an image's metadata, as orphans or stale thumbnails.
* Fixed: the Disk files trash could move a WebP/AVIF copy that an image still serves (photo.webp beside photo.jpg) when the Disk files list came from a scan made before updating.
* Fixed: on multisite, uninstall applied only the main site's setting; each site's own "delete plugin data" choice is now honored. The default uninstall keeps the records needed to finish an interrupted restore, and full deletion removes the plugin's restore records from attachments.
* Fixed: Media Replace failed when WordPress scaled or rotated the new image (photos over 2560 px or with EXIF rotation) and left a stray -scaled file behind; a failed replace now says why.
* Fixed: "Delete all backups" and "Delete all next-gen" stopped after a few seconds of work and reported nothing; bulk optimization, the savings estimate and Regenerate thumbnails now stay within their time budget per request; a bulk action chosen from the dropdown below the Results or Disk files table was ignored.
* Fixed: "Repair storage protection" could write or remove guard files outside the uploads folder when no backup folder existed yet; a last-resort recovery record without a transaction token kept automatic cleanup paused; Potential savings under-reported the optimization estimate for duplicate copies.
* Fixed: Scheduled Cleanup stopped early when the first items it tried could not be moved; `wp avar-mo trash purge <id>` deleted permanently without asking (use --yes to skip the prompt); the Duplicates tab offered "Move to trash" while a rescan was required; several buttons showed no message when their request failed.
* Fixed: PHP warnings on activation, on "Move to trash" and in Diagnostics when the uploads folder is not writable.

= 1.22.4 =

* Initial WordPress.org release.
