== Changelog ==

= 1.4.3 =

* [Security] Imagick opens every source image with an explicit JPEG, PNG, GIF or WebP decoder chosen from the file content, so a disguised SVG, MSL or PostScript file is rejected instead of reaching a dangerous ImageMagick coder (CERT VU#580079).
* [Added] System status warns when the server ImageMagick security policy does not block the MSL, PS, EPS or PDF coders, and the diagnostic report lists them.

= 1.4.2 =

* [Fixed] "Regenerate all thumbnails" now rebuilds sizes from the original upload instead of the -scaled or -rotated copy, so existing thumbnail URLs keep working and the original image stays linked to the attachment.
* [Fixed] A failed thumbnail regeneration (editor, memory or resource limit) restores the previous metadata and no longer deletes existing thumbnails. Files shared with another attachment are never removed.
* [Fixed] Thumbnail regeneration resumes from the last processed image after an interruption, retries a busy lock or transient server errors, and no longer slows down on large libraries.
* [Security] Optimized WebP/AVIF files are removed when their source image is deleted, even while another image operation is running, and Apache/Nginx rules only serve an optimized file while its source still exists.
* [Security] PDEV no longer writes rewrite rules into the uploads or theme .htaccess when the site root .htaccess has rewrite rules for that folder (for example media protection plugins); the rules are shown for manual placement instead.
* [Security] On multisite, Cloudflare actions and theme image operations require network administrator rights.
* [Fixed] Apache rewrite rules are active only when mod_headers is available, so caches never store an optimized variant without Vary: Accept. The delivery test also checks the Vary header.
* [Fixed] The generated Nginx location is limited to the uploads and theme folders and documents how to keep server-level headers and private-folder deny rules.
* [Fixed] Cloudflare zone cache is purged only after a run that changed optimized files; the purge permission check no longer purges the whole zone.
* [Fixed] Deleting media no longer causes a fatal error when WordPress cannot initialize its filesystem, and non-array attachment metadata from other plugins no longer causes a fatal error.
* [Fixed] Animated PNG (APNG) images are skipped instead of being converted to a static first frame.
* [Fixed] Cleanup removes stale temporary files left by an interrupted conversion and works when the uploads folder is a symlink.
* [Fixed] Multisite: cleanup and uninstall on the main site no longer touch subsite files, uninstall cleans every site, and network deactivation removes rules for every site.
* [Fixed] Uninstall no longer stops halfway on an unreadable folder.
* [Fixed] Bulk optimization retries HTTP 500 responses so the crash-skip logic can move past a failing image, and refreshes an expired REST nonce during long runs.
* [Fixed] WP-CLI optimize reports a lost lock as an error instead of a fatal error.
* [Performance] Media Library status uses a single aggregate query; theme image runs write their state once per batch and cache the theme status for five minutes.
* [Performance] Failure tracking skips option updates for unchanged entries and avoids reading the failure list for empty batches.
* [Performance] Automatic conversion avoids repeatedly encoding unchanged images whose optimized result was not smaller during successive metadata updates in the same upload request. Content changes and conversion errors remain retryable.
* [Performance] Cleanup scans use resumable directory batches, skip unreadable directories with a warning, and stop at the preview limit instead of walking the remaining tree. WP-CLI completes the scan before reporting or requesting deletion.
* [Performance] Media Library status reads only optimization signatures in bounded batches instead of loading all attachment metadata.

= 1.4.1 =

* [Fixed] Retried bulk starts retain their run identity and checkpoints; the last completed response can be replayed after a lost connection.
* [Fixed] Image operations and settings changes share a connection-scoped database lock, including CLI, retries, thumbnail regeneration and cleanup.
* [Fixed] Cleanup invalidates optimization state before deleting current variants, including interrupted or partially completed batches.
* [Fixed] Theme image conversion persists crash markers and per-image results so resumed batches skip repeatedly crashing files.
* [Fixed] Distribution builds reject output paths that would delete plugin sources or traverse directory links.
* [Fixed] Apache cache headers now match generated .pio.webp and .pio.avif files.
* [Fixed] Re-conversion removes an older optimized variant when the new result is not smaller than the source; failed removal is reported as an error.
* [Fixed] The Cloudflare delivery test finds current sidecar names and validates both HTTP statuses, image MIME types and Vary: Accept headers.

= 1.4.0 =

* [New] WP-CLI support. Run bulk optimization, targeted conversion, generated-file cleanup, the live delivery test, and format or speed changes from the command line with wp pdevio (optimize, convert, cleanup, status, test-delivery, set). The optimize command shares the same lock as the admin screen, so a command-line run and a browser run never process the same images at once.
* [New] Optimization speed setting (Conservative, Balanced, Fast) on the Settings screen. Bulk optimization now grows to larger batches with shorter pauses while the server keeps up, and still drops back to one image per request the moment a batch runs long or memory gets tight. Balanced is the new default. Shared hosting that sees timeouts can switch to Conservative; a VPS or dedicated server can use Fast. Filters pdev_image_optimizer_max_batch_limit and pdev_image_optimizer_min_cooldown_ms tune the ceilings further.
* [New] "Force optimize all" button on the Media Library screen re-optimizes every image from the start, next to the normal button that resumes where it left off. A "Stop optimization" button pauses a run with its progress saved; the button then reads "Continue optimization".
* [Changed] The main plugin screen is now a short summary: one line confirming that optimized images are being served, or only the checks that still need attention. The full diagnostic Overview moved to the top of the System status screen. When the live delivery test confirms visitors receive the optimized images, the summary is shown in green and a leftover competing rewrite rule from another plugin is treated as optional cleanup rather than a warning; the note about it now lives on System status.
* [Changed] Removed the database table that tracked generated files. A generated WebP or AVIF file is now identified only by its exact name (image.jpg.pio.webp) and its location inside the uploads or active theme folder. Cleanup and uninstall never remove a file unless a real source extension precedes .pio. in its name and it sits in a managed folder, so a file you happened to name something.pio.webp is always left alone. The old table is dropped automatically on update. New filter pdev_image_optimizer_generated_roots adds folders to the scan for sites that store media elsewhere.
* [Changed] Overwriting a generated file no longer depends on a database record. Any file at the reserved .pio.webp or .pio.avif path derived from a real source image is treated as PDEV's own and refreshed normally.

= 1.3.2 =

* [Fixed] AVIF bulk optimization could stop with an "HTTP 409" error on some servers and never recover. A single image whose AVIF encode outruns the server's memory or time limit was killing the PHP worker before it could report a failure, so the job never advanced past that image and every retry hit it again and left the optimization lock stranded. That image is now detected after the first crash, recorded as a failed image, and skipped so the rest of the library finishes; AVIF batches also process one image at a time, the encoder runs at a bounded speed (filter pdev_image_optimizer_avif_speed), a batch the web server kills mid-request no longer holds the lock for 90 seconds (kept fresh while running, reclaimed within 45 seconds otherwise), and the optimizer waits out a busy lock or a dropped connection instead of failing immediately. The crash-skip threshold is adjustable through pdev_image_optimizer_max_attachment_attempts.
* [Fixed] Large photos near the megapixel limit could fail with "cache resources exhausted" on Imagick. The Imagick pixel-cache limits are now large enough to process an image up to the safe megapixel cap, including its orientation pass, and stay adjustable through the pdev_image_optimizer_imagick_resource_limits filter.
* [New] Filter pdev_image_optimizer_preferred_driver (gd or imagick) forces which encoder is tried first. The capability probe still runs, so forcing a driver that cannot encode the chosen format falls back to the other one.
* [Fixed] After moving a site, migrating its database, or restoring from a backup, every previously generated file reported "a file with PDEV's reserved optimized-image name already exists and was not created by PDEV" and could not be optimized again. A valid WebP or AVIF sitting at the reserved .pio path is now treated as an earlier PDEV conversion and re-created normally (the hard refusal is kept only for a file that is not a valid image of the target format), and the ownership table is recreated automatically if a migration left it behind.
* [Changed] A competing WebP or AVIF rewrite rule from another plugin - often left in .htaccess after that plugin is removed - no longer disables PDEV delivery. PDEV now installs its own rules regardless and shows a warning that names the competing block, says whether the plugin that created it is still active, tells you which # BEGIN / # END block to delete when it is not, and points to the live delivery test.
* [Changed] Overview cleanup: removed the "View detailed status" button (it only opened System status, which repeats what Overview already shows); after a competing rewrite rule is detected, the live delivery test result now appears in the conflict block where the test button is, instead of only in the Image delivery row; and once that test passes, the loud competing-rule warning collapses to a short "delivery still works" note, leaving the details one click away.

= 1.3.1 =

* [Fixed] The 1.3.0 release package was incomplete: several class files were missing, which caused a fatal error (Class "PDEV\ImageOptimizer\Rest\CleanupRoute" not found) on sites that installed or updated to 1.3.0. This release ships the complete plugin.

= 1.3.0 =

* [Feature] Added registry-backed, preview-first cleanup for obsolete PDEV-generated WebP and AVIF files, with an optional "all generated files" mode that also clears the optimization state so images are regenerated.
* [Feature] Added a "Delete generated files on uninstall" setting; when enabled, the uninstaller removes registered .pio.webp / .pio.avif files (best effort, time-limited) while never touching originals.
* [Changed] Generated files now use the unambiguous `.pio.webp` and `.pio.avif` naming contract; legacy sidecars are no longer served or removed automatically.
* [Security] Cleanup accepts no browser-supplied paths and revalidates exact registry ownership immediately before deletion.
* [Fixed] The live delivery test no longer fails on a self-signed or mismatched certificate when the uploads URL is on this site's own host; TLS verification is skipped for that loopback request, as WordPress core does for its own loopback checks.

= 1.2.1 =

* [Changed] Branding change.
* [Feature] Added actionable recovery instructions for every Overview warning and error.
* [Feature] Added a privacy-safe live HTTP delivery test with stored diagnostics for Apache/LiteSpeed and Nginx.

= 1.2.0 =

* [Feature] Added a clear compatibility overview for image encoders, writable directories, delivery rules, and conflicts.

= 1.1.1 =

* [Changed] Moved Image Optimizer from the shared PDEV Tools menu to the standard WordPress Tools menu.

= 1.1.0 =

* [Fix] Added real encoder capability tests for WebP and AVIF in both Imagick and GD.
* [Feature] Added persistent optimization jobs with per-attachment checkpoints and safe continuation after an interrupted request.
* [Performance] Replaced growing database offsets with an ID cursor so resumed jobs do not rescan previously processed attachments.
* [Performance] Added adaptive one- or two-attachment batches, cooldown periods, and automatic backoff for temporary server errors.
* [Feature] Added batch duration, progress, active driver, and load information to the conversion log and diagnostic report.
* [Security] Added conservative source image, pixel, memory, execution time, and Imagick thread limits suitable for shared hosting.
* [Performance] Reduced retry batches and added pauses between requests to avoid sustained server load.
* [Performance] Limited thumbnail regeneration to one attachment per request with a short cooldown between attachments.
* [Docs] Documented image limits, driver safeguards, adaptive batching, retries, and shared-hosting resource protection.
= 1.0.0 =

* [Release] First public build.
