=== icomm Image Optimizer ===
Contributors: icomm
Tags: images, webp, avif, performance, optimization
Requires at least: 6.0
Tested up to: 6.6
Requires PHP: 7.4
Stable tag: 0.6.30
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Generates modern image formats (WebP/AVIF) and serves them safely via <picture> tags in post content.

== Changelog ==

= 0.6.30 =
* AI Alt: אחרי שמירת alt — רענון מטמון תוכנית השיפור של Site Health (אם מותקן).

= 0.6.29 =
* AI Alt: אחרי «שמור» — הודעת הצלחה ברורה, הסרת שורות שנשמרו מהטבלה, עדכון מונה «ללא alt»; תיקון ספירה כש־alt זהה לקיים.

= 0.6.28 =
* Fix: AI Alt — לא לסווג כל HTTP 429 כמכסה אזלה; הפרדה בין Rate limit לבין חיוב; הודעת שגיאה כוללת טקסט מ-OpenAI; בדיקת מפתח כוללת קריאת מודל אמיתית (gpt-4o-mini).

= 0.6.27 =
* AI Alt: כפתורי «סמן הכל» / «נקה סימון», תיבת סימון בכותרת הטבלה, מונה «X מתוך Y נבחרו»; הסבר Pay as you go במדריך.

= 0.6.26 =
* AI Alt: זיהוי שגיאת מכסה/חיוב OpenAI (HTTP 429) — הודעה בעברית, עצירה אחרי שגיאה ראשונה (במקום רשימה ארוכה).

= 0.6.25 =
* Fix: AI Alt — דחיסת תמונה לפני שליחה ל-OpenAI, הורדה מ-URL אם הקובץ חסר, הודעות שגיאה מפורטות (HTTP), כפתור «בדיקת מפתח API», עיבוד תמונה-תמונה עם progress.

= 0.6.24 =
* AI Alt: progress bar לסריקה/הצעות/שמירה; הסבר שלבים; הצגת שגיאות API; שליחת תמונה כ-base64 (אמינות טובה יותר); הערה שמנוי ChatGPT אינו כולל API.

= 0.6.23 =
* AI Alt: מדריך «איך להשיג ולעדכן מפתח OpenAI» + הסברים בשדה המפתח (החלפה / מחיקה).

= 0.6.22 =
* AI Alt: הודעת פרטיות — הסבר שתמונות נשלחות ל-OpenAI בלחיצה על «הצע alt», עם קישור למדיניות הפרטיות.

= 0.6.21 =
* New: AI Alt text — סריקת מדיה ללא alt, הצעות OpenAI Vision, שמירה מרוכזת (מנוי + מפתח API). אינטגרציה עם icomm Site Health.

= 0.6.19 =
* Fix: shared license telemetry file safe when multiple icomm plugins are active (no fatal redeclare).

= 0.6.18 =
* Licensing: clearer message when a key is bound to another site (“domain mismatch”).

= 0.6.16 =
* PRO purchase: buy button in License settings (531 ₪ incl. VAT) via icomm.market + Pelecard; automatic license activation after payment (checkout signing secret is configured only on icomm.market).
* Plugin details page: new «רכישה» tab with pricing and checkout form on icomm.market.

= 0.6.15 =
* License telemetry: daily ping to license.icomm.systems (install tracking; no license required).

= 0.6.14 =
* Fix: Bulk optimize "Apply selected" button at the bottom of the scan results table now works (same action as the top button).

= 0.6.11 =
* New "Clean junk files" button on Bulk optimize: scans the whole uploads tree and removes orphaned junk left by the earlier buggy Auto builds — doubled extensions (.webp.webp / .avif.avif) and leftover temp files (.iolossy.webp / .iolossless.webp). Reports how many files and how much space were freed.

= 0.6.10 =
* Fix (critical): Auto WebP mode failed for every file in 0.6.8–0.6.9. The temporary lossy/lossless files used a non-image extension that WordPress' image editor silently rewrote, so the plugin looked for the wrong filename and reported "Failed". Temp files now end in .webp (kept by the editor) and the real saved path is trusted. Junk ".webp.webp" files left by the buggy builds are cleaned up automatically on the next run. Re-run Bulk optimize to convert the affected images.

= 0.6.9 =
* Bulk optimize report: The summary now appears at the TOP (right under the progress bar) and in a completion popup — no more scrolling past 200 rows. It breaks results down into Converted / Already optimized (untouched) / Failed, plus new files written and total space saved vs. the originals.
* Live progress: While running, the status line shows percentage AND a running tally (✔ converted, ⏭ already done, ✖ failed).
* Re-scan safety made explicit: re-running never re-encodes or corrupts files that already have WebP/AVIF — those are counted as "Already optimized (untouched)" and skipped.

= 0.6.8 =
* WebP encoding mode: New "Auto" mode (now the default) encodes each image both lossy and lossless and keeps whichever file is smaller — so photos get lossy and logos/graphics get lossless automatically, with no manual per-file choice. The old single lossless checkbox is replaced by an Auto / Lossy / Lossless dropdown.
* Backups: Removed the non-functional "automatic daily ZIP backup" option. Use the on-demand "Download all originals as ZIP" button on the Originals backup page instead.

= 0.6.7 =
* Originals backup: The "Move originals on optimize" mode now has a full management page. It shows whether the mode is ON/OFF and how many files/size are stored, and lets you (a) Restore selected originals, (b) permanently Delete selected backups, (c) Delete the entire backup folder, and (d) Download all originals as a single ZIP (ZipArchive with PclZip fallback). Restore moves the original back and removes the generated WebP/AVIF; Delete keeps the live WebP and frees disk space.

= 0.6.6 =
* Usage transparency: The Usage column now shows the EXACT evidence behind each "Used on page" verdict — the meta key (e.g. _elementor_data) plus a highlighted snippet of the matching text, or the matching content. This makes it possible to tell a real (sometimes hidden/leftover) reference apart from a coincidence, e.g. why ID 72 is reported on a page where the image isn't visible. Re-run the scans to refresh.

= 0.6.5 =
* Usage accuracy: All numeric ID matches (image classes, Gutenberg/Elementor JSON, gallery shortcodes) are now delimiter-bounded. Previously a low ID like 72 falsely matched "id":721, wp-image-720, etc., reporting an image as "used" on pages where it isn't. URL/path matching remains as a safety net so genuinely-used images are still detected. Re-run the scans to refresh.

= 0.6.4 =
* Duplicates: Color signature now uses chroma sums instead of average RGB, so logos on a white background (where the average color is dominated by white) are correctly separated by hue — the same shape in teal vs red is no longer flagged as a duplicate. Re-run the duplicates scan to refresh results.

= 0.6.3 =
* Duplicates: Visual duplicate detection is now color-aware. Previously the perceptual hash was grayscale-only and merged the same shape in different colors (e.g. the same logo in teal vs red) into one group; a coarse average-color signature is now part of the match key. Re-run the duplicates scan to refresh results.

= 0.6.2 =
* Unused scan: Now also surfaces orphaned records whose file is missing on disk (including inside the icomm-io-unused folder), clearly marked "file missing — safe to delete", so the Media Library can be cleaned of dead rows.
* Usage details: The Usage column (unused + duplicates) now lists ALL pages an image appears on (previously capped at 3), with a "+N more" indicator.

= 0.6.1 =
* Unused media: The "Used" verdict now shows the exact source (which option/setting, theme logo, site icon, or category/tag image references it) instead of an opaque "theme/widget" label — so you can verify before deleting.
* Safety: An attachment that is currently detected as used can no longer be moved to the unused folder, preventing broken (404) images on the live site.

= 0.6.0 =
* UX: Backup reminder on all admin screens and in settings — full site backup before optimization or moving originals.

= 0.5.8 =
* License trial: record install time with `add_option` on activation and when missing in admin (avoids fragile defaults); validate stored `icomm_io_installed_at` so corrupt/empty values are repaired once instead of behaving unpredictably.
* Trial UI: show exact trial end date/time (site timezone) next to “days left” on the Plugins row (Hebrew) and on the License section in settings.

= 0.5.7 =
* Updater: apply the same long timeout and `Accept-Encoding: identity` to the exact `download_url` from update metadata (not only license.icomm.systems hostnames), reducing truncated/corrupt ZIP downloads.
* Updater: `upgrader_pre_download` runs a lightweight HEAD check for our package URL — clearer Hebrew errors for HTTP failures or HTML responses instead of only PCLZIP_ERR_BAD_FORMAT (-10). HEAD unsupported (405/501) falls back to normal download.

= 0.5.6 =
* Fix: when “Move originals” is on but an intermediate size has no WebP/AVIF sidecar (often only `thumbnail` was generated), fall back to the **full** modern file URL instead of a removed JPEG — fixes Elementor/media sizes above ~150×150 disappearing while thumbnail still worked.
* HTML URL pass-through uses `attachment_url_to_postid()` when available so the same fallback applies to hard-coded image URLs.

= 0.5.5 =
* Fix (Elementor + “Move originals”): replace hard-coded `.jpg`/`.png` URLs inside rendered HTML via late `the_content`, `elementor/frontend/the_content`, and `elementor/widget/render_content` when a matching WebP/AVIF exists — fixes banners that still pointed at removed originals.

= 0.5.4 =
* Default **Enable optimization** is now **off** so installing/activating the plugin does not register front-end hooks until you opt in (prevents immediate banner/Elementor breakage).
* Default **Smart lazy-load** and **Preload LCP** are off until you enable them (same reason). Existing saved settings in the database are unchanged.

= 0.5.3 =
* Fix (Elementor + media library): `image_downsize` now runs once without `wp_get_attachment_url` rewriting so core can build correct intermediate *.jpg paths, then swap to WebP — avoids broken URLs when the main file basename is already *.webp
* Fix: `wp_prepare_attachment_for_js` rewrites every `sizes[].url` (and main `url`) to WebP when originals are in backup — fixes editor preview for medium/large/full where WP concatenates metadata *.jpg onto a WebP-based base URL

= 0.5.2 =
* Fix: when serving WebP/AVIF after moving originals to backup, rewrite `srcset` URLs via `wp_calculate_image_srcset` (WordPress does not pass those through `wp_get_attachment_url`). Prevents broken images for Elementor/widget sizes above thumbnail (medium, large, full).

= 0.5.1 =
* Fix: register all image/attachment runtime hooks only when **Enable optimization** is on (`init`). With the master switch off, the plugin no longer attaches `the_content`, `wp_get_attachment_*`, `wp_content_img_tag`, or `wp_head` preload — same practical effect as deactivating for the front-end.
* Fix: “Move originals to backup” is ignored unless optimization is enabled; saving settings with optimization off forces that checkbox off (avoids a dangerous UI state).
* Optional: define `ICOMM_IO_DISABLE` as true in `wp-config.php` to hard-disable all optimizer behavior without deactivating the plugin.

= 0.5.0 =
* Fix: never wrap `<img>` tags that already have `srcset` (Elementor, WordPress responsive images). A single WebP `<source>` does not match multi-size `srcset` and commonly breaks banners/thumbnails.
* Harden: treat WebP/AVIF as usable only if the file is readable and non-trivial size (avoids empty/corrupt sidecars).
* New filter: `icomm_io_wrap_img_in_picture` (pass `false` to skip wrapping for custom cases).
* Default: “Serve modern formats in post content” is now **off** for new installs (generation on upload unchanged). Existing saved settings are preserved.

= 0.4.9 =
* Fix: do not inject WebP/AVIF `<picture>` sources when the image URL host differs from the uploads base URL (e.g. CDN/offload) — local `file_exists` was true but the CDN returned 404 for the modern file
* Fix: skip `<picture>` wrapping when `data-src` / `data-lazy-src` / similar points to a different URL than `src` (common in Elementor and lazy-load markup)
* Fix: `move_originals_to_backup` attachment URL swap now resolves disk paths from the URL path (avoids broken `str_replace` against `baseurl`)

= 0.4.8 =
* LCP preload: emit a single `rel=preload` (AVIF or WebP or original) instead of three competing preloads
* LCP preload: detect first image from raw post content when there is no featured image (`wp_head` runs before `the_content`, so the previous “first content image” preload almost never fired)
* Note: for lab scores like PageSpeed, pair this plugin with full-page caching (e.g. LiteSpeed Cache) — this plugin targets image formats and markup, not JS/CSS minify or HTML cache

= 0.4.7 =
* Fix: only add WebP/AVIF `<source>` and modern-format preloads when the file exists on disk (prevents broken images right after activation before bulk optimize)

= 0.4.6 =
* Remove Settings shortcut and add dedicated submenus: Bulk optimize, Restore, Media scan
* Add progress bars with percent for actions
* Restore bulk optimize + restore originals tools
* Improve unused scan results UI (table with preview/size/duplicate + actions)
* Add “Move to unused” folder (excluded from future unused scans) and “Delete” actions
* Improve duplicates scan: detect exact duplicates (hash) and visual duplicates (perceptual hash) with actions
* New workflow: scan + recommendations first, then apply selected; end-of-run report shown on screen
* Add Unused folder + Originals backup submenus with restore/delete actions and UI feedback
* Show usage (where used) in scan tables
* After apply: remove processed rows + exclude unused/backup folders from scans
* Add select all/none controls for restore/delete screens
* Fix: checkboxes now render in Unused/Originals screens (select all + per-row selection works)
* Fix: unused scan cache resets between runs and excludes moved items

