=== PDEV Image Optimizer ===
Contributors: grzegorzpuszka
Donate link: https://ko-fi.com/puszkadev
Tags: webp, avif, images, optimization, thumbnails
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.0
Stable tag: 1.2.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Create WebP or AVIF copies of WordPress images locally and serve them without changing original URLs. Free, simple, and without a PRO version.

== Description ==

PDEV Image Optimizer was created because I needed a small image optimization
plugin that simply did its job. I did not need a cloud dashboard, a subscription,
or a long list of advanced settings. I also did not want basic features to stop
working behind a paywall after installing the plugin.

This plugin is completely free and will remain free. There is no PRO version,
no limited free plan, no account, and no feature unlock hidden in the settings.

= What does the plugin do? =

PDEV Image Optimizer creates WebP or AVIF copies of images from the WordPress
Media Library. It can convert new uploads automatically and process an existing
library in small batches that can be stopped and continued later.

You only choose:

* WebP or AVIF as the output format.
* Which source formats should be converted: JPEG, PNG, GIF, or WebP where applicable.
* Conversion quality.
* Whether new uploads and images from the active theme should be processed.

The plugin also includes thumbnail scanning and regeneration, storage savings
statistics, conflict detection, optional Cloudflare support, and a detailed
system report for troubleshooting. The Settings overview explains failed checks
and links directly to the action needed to resolve each problem.

= How does it work? =

1. WordPress stores an image such as `photo.jpg` and usually creates thumbnail
   files such as `photo-768x512.jpg`.
2. PDEV Image Optimizer uses Imagick, or GD as a fallback, to create an optimized file next to
   each source file. The file is named `photo.jpg.webp`, `photo.jpg.avif`, or for
   example `photo-768x512.jpg.webp`.
3. The original image is not deleted, renamed, or replaced. WordPress content
   continues to use the original URL ending in `.jpg`, `.png`, `.gif`, or `.webp`.
4. When a browser requests that original URL, the web server checks the browser's
   `Accept` header. If the browser supports the selected modern format and the
   sidecar file exists, the server returns the WebP or AVIF file instead.
5. A browser without support receives the untouched original image.

On Apache and compatible LiteSpeed servers, the plugin adds a clearly marked
`PDEV Image Optimizer` block to `.htaccess` inside the uploads directory. If
theme image optimization is enabled, it also manages a marked block in the
active theme directory. The block uses rewrite rules, sets the correct MIME
type, and adds `Vary: Accept` so caches know that one URL can return different
file formats.

On Nginx, WordPress cannot safely edit the server configuration. PDEV Image Optimizer therefore
shows ready-to-copy `map` and `location` blocks in **System status**. A server
administrator must add them to the Nginx configuration and reload Nginx.

The Settings overview includes an optional live delivery test. It creates a
temporary one-pixel source and optimized sidecar inside uploads, requests the
source URL with the appropriate `Accept` header, verifies the returned HTTP
status and `Content-Type`, and immediately removes both test files. The test runs
only when an administrator clicks **Test image delivery**.

Conversion and delivery are separate steps. If WebP or AVIF files exist on disk
but the server rules are missing or ignored, conversion succeeded but visitors
will still receive the original files. Check **System status** when this happens.

= Main features =

* Local WebP and AVIF conversion with Imagick or GD.
* Automatic conversion of new uploads and WordPress thumbnails.
* Restartable optimization of the existing Media Library.
* Optional optimization of supported images from the active theme.
* Thumbnail scan, missing-thumbnail repair, full regeneration, and obsolete-file cleanup.
* Per-image safety limits that skip unsafe files without stopping the whole batch.
* Storage and estimated transfer savings statistics.
* Apache/LiteSpeed `.htaccess` delivery and generated Nginx configuration.
* General image-plugin and rewrite-rule conflict detection.
* Optional Cloudflare Free-compatible cache integration.
* Detailed privacy-safe system report with copy and JSON export.
* Clear Settings overview with tested encoder support, server requirements, delivery status, and conflict checks.
* Actionable recovery instructions and a live HTTP test for Apache/LiteSpeed and Nginx delivery.
* Error history from the last 24 hours, limited to 50 entries.
* No external conversion service, tracking, subscription, paywall, or PRO version.

= Server requirements - read before installing =

The plugin needs both an image conversion library and working web-server rules.
Installing and activating the plugin cannot add missing PHP extensions or change
server configuration that your hosting provider has disabled.

Required for conversion:

* WordPress 6.4 or newer.
* PHP 8.0 or newer.
* Imagick or GD installed and enabled in PHP.
* The selected library must support the selected output format. WebP support does
  not automatically mean AVIF support.
* The WordPress uploads directory must be writable by PHP.
* Enough PHP/server memory and execution time for the size of your images.

Required for automatic delivery on Apache or LiteSpeed:

* Apache-compatible rewrite support (`mod_rewrite`).
* MIME and header support (`mod_mime` and `mod_headers`).
* `.htaccess` files must be allowed and processed for the uploads directory.
  On Apache this normally requires an appropriate `AllowOverride` setting.
* The uploads directory or its existing `.htaccess` file must be writable by PHP
  so the plugin can add its marked rules.
* If theme images are enabled, the active theme directory and its `.htaccess`
  file must meet the same requirements.

Required for delivery on Nginx:

* Access to the Nginx website configuration.
* Permission to add the generated `map` block to the `http` context and the
  generated `location` block to the correct `server` context.
* Permission to test and reload Nginx after changing its configuration.

If you use managed hosting and do not have access to these settings, ask the
hosting provider whether Imagick/GD supports WebP or AVIF and whether the required
Apache modules and `.htaccess` overrides are enabled. PDEV Image Optimizer cannot bypass server
restrictions imposed by the hosting provider.

= Hosting resource protection and image limits =

Image conversion can use considerably more memory than the compressed source
file suggests. To reduce timeouts, 503 responses, and account resource-limit
errors on shared hosting, PDEV Image Optimizer applies conservative limits before and during
conversion.

Default limits applied to both Imagick and GD:

* Maximum source file size: **64 MB**.
* Maximum width or height: **16,384 pixels**.
* Maximum total image size: **25 megapixels**.

Additional GD protection:

* GD conversion uses a conservative **256 MB per-request memory budget**.
* The estimate includes decoded image pixels, the source file, current PHP
  memory usage, and a reserved safety margin.
* A hosting provider or PHP configuration may impose a lower effective limit.

Additional Imagick protection:

* Memory limit: **128 MB**.
* Memory-map limit: **256 MB**.
* Temporary disk limit: **512 MB**.
* Processing time limit: **30 seconds**.
* Thread limit: **1 thread**.

These are safety ceilings, not resource reservations. The server may enforce
lower limits, and increasing a PHP or plugin limit cannot bypass the hosting
account's CPU, RAM, process, or I/O allowance.

Media Library optimization starts with one attachment per request and may use
two only after several fast batches. Slow or memory-heavy batches automatically
return to one attachment. Short pauses are added between requests, and temporary
HTTP 409, 429, 502, 503, and 504 responses use an increasing retry delay. Progress
is saved after every attachment, so a stopped job can be continued without
starting the library scan from the beginning.

One WordPress attachment can contain the original image and several thumbnail
files. Processing one attachment can therefore still convert several physical
files. Thumbnail regeneration always handles one attachment per request and
waits briefly before requesting the next one. Thumbnail scanning is lighter and
uses batches of up to five attachments.

An image that exceeds a safety limit is not converted. It is shown as a failed
item with the reason in the conversion log and error list, while the optimizer
continues with the next attachment. The original image is never removed or
modified. Developers can adjust the safeguards with WordPress filters, but doing
so should be based on the real limits of the hosting account.

== Installation ==

1. Install and activate PDEV Image Optimizer.
2. Open **Tools > Image Optimizer > Settings** and review the Overview section.
3. Follow the instruction next to every yellow or red check.
4. Choose WebP or AVIF, source formats, and quality, then click **Save settings**.
5. On Nginx, open **System status > Nginx configuration**, copy the generated
   blocks into the server configuration, and reload Nginx.
6. Click **Test image delivery** in Overview. The result should confirm an
   `image/webp` or `image/avif` response.
7. Open **Media library** and start optimization for existing images.

Do not enable overlapping WebP/AVIF rewrite rules in more than one image plugin.

== Frequently Asked Questions ==

= Are original images deleted or replaced? =

No. The original files stay in place. PDEV Image Optimizer writes a separate sidecar file next
to every converted source and WordPress continues to use the original URL.

= Why do I see WebP or AVIF files on disk but the website still sends JPEG or PNG? =

Conversion works, but delivery rules do not. On Apache/LiteSpeed, check that
`.htaccess`, `mod_rewrite`, `mod_mime`, `mod_headers`, and `AllowOverride` are
available. On Nginx, install the generated configuration and reload the server.
Also clear page, server, CDN, and browser caches before testing again.

= Why is AVIF unavailable? =

Your installed Imagick and GD builds decide which output formats are available.
Many servers support WebP but were compiled without AVIF support. The plugin
cannot add AVIF support to PHP; the hosting provider must enable it.

= Which library is used? =

Imagick is preferred when it supports the selected output format. GD is used as
a fallback. The detailed System status report shows both libraries, versions,
format support, and resource limits.

= How can I test delivery? =

Open **Settings > Overview** and click **Test image delivery**. PDEV Image
Optimizer creates temporary local test files, requests the original URL with the
selected format in the `Accept` header, verifies the response, and removes the
files immediately. A successful result confirms an `image/webp` or `image/avif`
response. The last result remains visible until conversion or delivery settings
change.

You can also verify a real image in browser developer tools. Select its request
in the Network panel and inspect `Content-Type`. The URL may still end in `.jpg`
while the response type is `image/webp` or `image/avif`; that is expected.

= Does it convert existing images and thumbnails? =

Yes. **Media library** processes the original attachment and all registered
WordPress image sizes. Work is split into small restartable requests. One failed
or oversized image is logged and skipped without stopping the remaining batch.

= Why was an image skipped because of a resource or safety limit? =

The compressed file size does not show how much memory is needed after decoding.
PDEV Image Optimizer skips sources larger than 64 MB, wider or taller than 16,384 pixels, or
containing more than 25 megapixels. GD and Imagick also have separate memory,
time, disk, and thread safeguards described in **Hosting resource protection and
image limits** above. The skipped attachment remains unchanged and is listed as
an error so it can be reviewed instead of silently exhausting the server.

= What are Thumbnail tools for? =

They scan the Media Library for missing registered thumbnail files and obsolete
files associated with image sizes that are no longer registered. They can create
missing sizes or fully regenerate thumbnails. Thumbnail regeneration itself does
not create WebP or AVIF files; run Media Library optimization afterward.

= Can it optimize images stored in my theme? =

Yes. Enable active theme images in Settings. The theme directory must be readable
and writable, and the web-server delivery rules must also cover that directory.
Development directories such as `node_modules`, `vendor`, `.git`, and `.svn` are
excluded from scanning.

= Are animated GIF files supported? =

Animated GIF files are detected and skipped so animation is not replaced by a
static image. A non-animated GIF can be converted when GIF is selected.

= Does the plugin use extra disk space? =

Yes. Original files are preserved and optimized sidecars are added next to them.
The Storage savings card shows sidecar disk usage and estimates the smaller
transfer size visitors may receive.

= Does it work with Cloudflare? =

Local conversion and origin delivery work without connecting an API. Without a
confirmed shared-cache rule, PDEV Image Optimizer uses private-cache protection so Cloudflare
does not cache the wrong format for a shared image URL.

The optional Cloudflare tab can configure a Free-compatible Cache Rule, test
delivery, and purge cache. Automatic rule creation requires a zone-scoped token
with **Cache Settings: Edit** and **Cache Purge: Purge**. The standard Cloudflare
WordPress token preset supports purge but does not include Cache Settings: Edit.

Credentials can optionally be defined in `wp-config.php`:

`define( 'PDEV_IMAGE_OPTIMIZER_CLOUDFLARE_ZONE_ID', 'your-zone-id' );`

`define( 'PDEV_IMAGE_OPTIMIZER_CLOUDFLARE_API_TOKEN', 'your-api-token' );`

= Does the plugin send images or usage statistics anywhere? =

No. Images are converted locally. The plugin has no telemetry or analytics
endpoint. Cloudflare is contacted only when an administrator explicitly provides
credentials or runs the compatibility test. The Ko-fi page opens only after the
user clicks its link.

= What is included in the system report? =

The report includes WordPress, PHP, web-server, Imagick, GD, plugin settings,
delivery status, writable-directory checks, Cloudflare status, optimization
statistics, the last live delivery test, conflicts, thumbnail status, and recent
plugin errors. Site URLs,
credentials, personal data, media content, and full server paths are excluded.

= How long are plugin errors stored? =

Only errors from the last 24 hours are shown and included, with an additional
maximum of 50 entries. Paths, URLs, email addresses, and image names are redacted
from the support report. The log is removed when the plugin is uninstalled.

= Is there a PRO version? =

No. Every feature is free and the plugin will remain free.

== External services ==

Cloudflare integration is optional. When configured, PDEV Image Optimizer sends the Zone ID and
API token to Cloudflare to manage its own Cache Rule and purge the selected zone.
The compatibility test requests one public Media Library image with different
`Accept` headers and stores only technical response information. Images are not
uploaded to Cloudflare by this plugin.

Cloudflare information: [Terms](https://www.cloudflare.com/website-terms/) and
[Privacy Policy](https://www.cloudflare.com/privacypolicy/).

== Screenshots ==

1. Simple conversion settings for format, sources, automatic conversion, theme images, and quality.
2. Restartable Media Library optimization with live progress and error counts.
3. Thumbnail scan and regeneration tools.
4. Optional Cloudflare connection, compatibility test, and cache actions.
5. Privacy-safe System status report covering WordPress, PHP, server, Imagick, GD, delivery, and recent plugin errors.

== Support ==

Support is provided **only through the official support forum for this plugin on
WordPress.org**: [PDEV Image Optimizer support forum](https://wordpress.org/support/plugin/pdev-image-optimizer/).

Support is not provided by email, through the author's website, Ko-fi, social
media, private messages, or any other channel. Please use the WordPress.org forum
so questions and solutions remain public and useful to other users.

Before opening a topic, check **Tools > Image Optimizer > System status**,
then copy the report or export its JSON file and include the relevant details in
your forum post. The report is designed to omit URLs, credentials, personal data,
full server paths, and media content.

== Changelog ==

= 1.2.1 =

* [Release] First public build.
