1-Click Migration changelog: versions before 3.1.20.
Newer versions are in readme.txt and on https://wordpress.org/plugins/1-click-migration/#developers

= 3.1.19 =
* **Binary database backup**: New backups hex-encode BINARY/BLOB columns (for example Wordfence file-hash tables) so those dumps restore cleanly. Older backups that still contain broken (non-hex) binary values need a fresh backup from a 3.1.19+ source; plain-text UTF-8 values stored in BLOB columns restore normally. BIT columns are no longer exported as quoted text, so their values restore exactly on hosts without mysqldump.
* **Broken binary restore guard**: Restores that detect broken binary data stop before anything on the site is changed and ask for a fresh backup.
* **Database part restore guard**: If the database was meant to be included but can't be downloaded or unpacked, the restore stops before any site files are replaced. A backup that intentionally left the database out (files-only) still restores its files without stopping.
* **Empty uploads backup**: An empty uploads, themes, or plugins folder no longer fails the backup; the plugin writes a valid empty archive and restore accepts it. An empty database dump still fails as before.
* **URL rewrite reliability**: Source addresses from `.local`/localhost and temp/cPanel domains expand scheme/www variants for the primary site path only (and checklist-approved domains). Other URLs such as CDN, embeds, and affiliate links stay unchanged.

= 3.1.18 =
* **Database archive failover**: If `ZipArchive::close()` fails while packing `db.zip`, backup no longer dead-ends when the host has no system `zip` binary. It now fails over to the existing in-process streaming zip, logs close diagnostics (libzip status, disk space), and only fails after ZipArchive, system zip, and in-process zip have all been tried (#69).

= 3.1.17 =
* **Review addresses before restore**: New backups collect an address inventory during database export. After checking the restore code, administrators can review old-to-new URL previews and select extra domains before restore starts. All choices start unchecked. Approved addresses are updated with the primary site URL in one serialized-safe pass. Older backups keep the post-restore address review.

= 3.1.16 =
* **Concurrent Backup Safety**: Added an atomic single-flight owner and per-run scratch directory so overlapping starts cannot share SQL dumps, archives, queue items, retry state, or bucket attribution.
* **Backup Part Accuracy**: Successful uploads are committed before timeout handling and cannot later be marked skipped. Part manifests are bound to the run's registered bucket, and stale workers cannot update a newer run.
* **ZIP Retry Accuracy**: A retry now accepts a valid archive left by a completed `ZipArchive::close()` before invoking monitored system-zip failover, avoiding false backup failures.

= 3.1.15 =
* **Restore Reliability**: Hardened options SQL import so large remapped `INSERT`s are no longer rejected as WordPress "invalid data" (`$wpdb->query()` `strip_invalid_text`, including the Turkish core string "Sorgu, içinde geçersiz veriler bulunduğundan işlenemedi"). Dump statements now prefer the raw mysqli handle when available; utf8/utf8mb3 connections are promoted to utf8mb4. Destination-prefix remap from 3.1.14 is unchanged.
* **Backup Integrity**: S3 uploads now fail closed: failed or missing encrypted archives are recorded as missing, remain on disk for diagnosis/retry, never receive an `ok` manifest status, and cannot trigger a restore-code email. Streamed SQL exports retry short writes and abort the backup if any dump byte cannot be written.
* **Safer Prefix Restore**: Prefix-remap temp files use checked full writes and atomic replacement, source-prefix detection requires exactly one canonical `*usermeta.sql` dump, and every SQL dump is validated/remapped before destination tables are dropped. Destination review-dismiss/count preferences survive the database replacement.
* **Large Archive Reliability**: Normal sites continue to use `ZipArchive`. If `ZipArchive::close()` fails or a persisted marker shows that it hung/timed out on a huge tree, the retry switches to a slower monitored system-zip streaming failover with worker heartbeats.
* **Log Security and Monitoring**: The migration log moved from the public plugin directory to a deny-protected private directory and is downloadable only by a nonce-verified administrator. Monitor classification now treats errors appended after a terminal marker as the current state while allowing a later terminal marker to resolve earlier transient errors.

= 3.1.14 =
* **Review Notice Accuracy**: The destination-site review notice is now armed only by restores that completed cleanly. Restores that finished with parts skipped after repeated failures (or parts missing from storage) no longer count as clean, so the notice cannot appear after a partial restore. Failed restores never counted. Same permanent dismiss flag as before.
* **Restore Reliability**: Fixed a cross-prefix restore failure where the database import could run `CREATE TABLE` against the source prefix while the `INSERT`s targeted the destination prefix (e.g. `Table '….eol_options' doesn't exist` when restoring a `wp_` backup onto a site using a different prefix). The prefix swap is now verified and repaired at statement level before import, the importer remaps any `CREATE`/`INSERT`/`DROP`/`ALTER` statement still carrying the source prefix to the destination prefix at execution time, a failed prefix rewrite aborts the restore instead of importing wrong-prefix tables, and leftover temp files in the restore DB folder are no longer imported. The destination-prefix table (e.g. `eol_options`) is always created before rows are inserted into it. Same-prefix (`wp_` → `wp_`) restores behave exactly as before.

= 3.1.13 =
* **Review Notice**: After the first clean restore, the destination site's wp-admin now shows a persistent review notice with a Leave a review button and a permanent "Don't ask again" dismiss (same dismiss flag as the 3.1.11 restore-complete popup).
* **Large-archive Reliability**: The native zip step and the encryption step now refresh the PHP time limit and the worker heartbeat while processing multi-GB archives, so they no longer die against the 300-second execution timeout. Encryption progress is logged every 512MB (offsets only).

= 3.1.12 =
* **Directory Listing Refresh**: Updated the WordPress.org listing title and short description (Free 1-Click WordPress Migration). Plugin behavior is identical to 3.1.11 — no code changes.

= 3.1.11 =
* **Log Sanitization**: The plugin log (`ocm_debug.log`) no longer records encrypted/binary payload data; I/O errors are logged as errno codes only, and every backup now ends with a terminal `Backup completed` or `Backup failed` line so log consumers can reliably detect the outcome.
* **Restore Success UX**: The Leave a review button now appears on the first clean restore-complete dialog (previously 2nd+). It is still hidden on warned, missing-parts, partial, or failed restores, and remains permanently dismissible.

= 3.1.10 =
* **Large-database dumps**: SQL dumps now stream to disk in chunks instead of building the dump in PHP memory, with a preflight that logs DB size vs `memory_limit` and forces the streamed path when an in-memory dump would OOM. Low-memory warnings are written to the plugin log.
* **Partial-backup honesty**: Skipping a part after the upload retry cap (e.g. `Skipping uploads Uploading`) now records that part as skipped in `BACKUP_PARTS` and finishes as completed-with-missing-parts — never `uploads=ok`.

= 3.1.9 =
* **Restore Reliability**: Restore now swaps the destination directory aside (`dest.ocm_bak`) and only deletes it after the new tree is in place, so a kill mid-replace leaves the old or new tree, never an empty folder. Restore logs the actual destination `$directory` path.

= 3.1.8 =
* **Restore Reliability**: Fixed a false siteurl/home failure during database restore when leftover foreign-prefix `*_options` tables (or custom table prefixes) were present on the destination. The gate now verifies `siteurl` and `home` only on the just-imported `{base_prefix}options` table, using the exact `{source_prefix}options.sql` dump — not other `*options.sql` files.

= 3.1.7 =
* **Restore Success UX**: When a restore finishes, you are taken back to the 1-Click Migration admin page and shown a clear restore-complete success dialog. A large Review button (WordPress.org reviews/#new-post, no rating filter, no incentive copy) appears only after a 2nd+ clean restore on that site — never on warned/missing-parts runs — and is permanently dismissible.

= 3.1.6 =
* **Partial Backup Honesty**: Backups that skip a part (e.g. uploads after repeated timeouts) now finish with a clear "completed with missing parts" status, an incomplete-backup warning banner, and a restore-code email that lists what's missing instead of reporting a normal completion.
* **Restore Awareness**: Restores now read the backup's part manifest up front, warn which parts the backup does not contain, and fail clearly when a part that should exist is missing from storage.
* **Background Worker Watchdog**: Backup and restore workers now write a heartbeat, and the progress poller automatically resumes a stalled worker — fixing silent hangs on hosts that block admin-ajax loopback requests (basic auth, WAF, firewalls).
* **Loopback Handling**: When the pre-dispatch loopback check fails, the backup now runs in direct processing mode immediately instead of dispatching a background worker that never starts.
* **Disk Space**: Restores delete encrypted and intermediate archives as soon as each step completes, check free space before every extraction, and use real uncompressed sizes from the backup for the up-front disk check. Backups likewise clean up each part's temp files right after upload, so peak disk usage is much lower on both sides.
* **Clearer Failures**: Running out of disk space during a download or extraction now stops the restore immediately with an actionable message instead of retrying into a full disk.

= 3.1.5 =
* **Backup Reliability**: Added multipart uploads for large backup archives to reduce S3 timeout failures on slower hosts.
* **Restore Reliability**: Added resumable downloads and stronger ZIP state validation so large restores can recover from interrupted transfers.
* **Database Restore**: Hardened SQL import fallback for hosts without MySQL CLI access.
* **Compatibility**: Removed pre-3.0 legacy backup endpoint handling.

= 3.1.4 =
* **Log Noise Reduction**: Suppressed unrelated theme/plugin PHP errors after migrations finish and deduplicated identical PHP errors across requests while migrations are active.

= 3.1.3 =
* **User Guidance**: Added contextual "How to fix" messages for quota, write permission, loopback, download/decrypt/extract, and database import failures.

= 3.1.2 =
* **Restore Reliability**: Restore now fails clearly when disk quota or write permissions prevent downloads, decryption, or ZIP extraction instead of reporting partial files as restored.
* **Restore Diagnostics**: Added a restore workspace write probe and hardened DB failure-context logging for malformed SQL payloads.

= 3.1.1 =
* **Backup Diagnostics**: Added admin-ajax loopback and worker dispatch logging to help identify hosts that block background backup workers.

= 3.1 =
* **Restore Reliability**: Fixed PHP fallback database imports on hosts where `proc_open` is disabled so comment-prefixed SQL table definitions are imported correctly.
* **Restore Safety**: Database import errors now stop the restore and surface a clear failure instead of logging `Restore completed.`
* **Restore Validation**: Restore now verifies the imported `siteurl` option before running URL replacement.

= 3.0 =
* **Redesigned Admin UI**: New tabbed Backup / Restore interface with clearer steps, inline help, progress card, and a yellow notice banner that surfaces the email/restore-code reminder after a backup completes.
* **Simpler Restore Access**: Backup now uses your email and sends an 8-character restore code when the backup completes. Restore takes only that code — no separate email field needed.
* **Pre-Flight Disk Space Check**: Backup and restore exit early with a clear message if there's not enough free disk space, instead of failing midway.
* **Backup Security**: Files continue to be encrypted (AES-256) before upload, with improved key handling behind the scenes.
* **Retention**: Backup availability is now consistently 48 hours.
* **Backup Reliability**: Improved backup stability on sites with plugins that interfere with long-running background tasks.
* **Restore Reliability**: Improved restore stability when plugin code, locked folders, or stubborn file permissions would previously interrupt a migration.
* **Security**: Removed the old legacy access path and tightened the restore flow.
* **Compatibility**: Existing backups from the previous version remain restorable during the short upgrade window only.

= 2.6.1 =
* **Critical Fix**: Fixed fatal `Call to undefined function OCM\ini_set()` crash on shared hosts that disable `ini_set`/`ini_get` via `disable_functions` — this was a 100% restore blocker on affected cPanel hosts
* **Critical Fix**: Fixed "OS: Windows" log message being written 250+ times per backup on Windows/XAMPP hosts — now logs only once per session
* **Bug Fix**: Fixed fatal crash when Stop & Reset is clicked mid-backup — background process now re-creates the temporary directory if it was deleted

= 2.6.0 =
* **Critical Fix**: Fixed DivisionByZeroError crash during database backup when tables report 0 MB in information_schema (affected Gravity Forms and other small tables)
* **Bug Fix**: Changed error catch from `Exception` to `Throwable` so PHP 8 DivisionByZeroError is properly caught by the fallback handler
* **Log Noise Reduction**: Added error deduplication to suppress identical PHP errors from being logged 30+ times per session (e.g. theme/plugin bugs)
* **Log Noise Reduction**: Suppressed per-table "Table being backed up" log messages that generated 50-80+ lines per backup on large sites
* **Log Fix**: Fixed misleading "Bucket created" log message that appeared after AWS 502 errors — now correctly says "Retrying bucket creation"

= 2.5.9 =
* **Maintenance Mode**: Automatically enables maintenance mode during restore to prevent visitors from seeing broken pages, white screens, or database errors
* **Admin & API Bypass**: Admin users and REST API requests (e.g. progress polling) bypass maintenance mode so the dashboard stays functional
* **Progress Indicator**: The admin progress endpoint now reports maintenance mode status so the dashboard indicator works
* **Auto Cleanup**: Maintenance mode is automatically disabled when the restore completes or is cancelled via Stop & Reset

= 2.5.8 =
* **Timeout Fix**: Reset PHP time limit before each major operation (archive, encrypt, upload, download, decrypt, extract) to prevent timeouts on large sites
* **Upload Fix**: Upload timeout now uses the full execution budget instead of the exhausted background process remaining time
* **Download Fix**: Restore file downloads now use the full timeout budget instead of remaining background process time
* **Bug Fix**: Fixed `Undefined array key "tables"` crash when mysqldump fails and falls back to PHP-based export
* **Bug Fix**: Fixed `error_reporting` never being restored on success paths in zip creation and folder backup
* **Resilience**: Error handler no longer kills the process for fatal errors from external themes/plugins (e.g. WooCommerce dependency in child themes)
* **Reliability**: Added pre-flight disk space check before DB and folder backups to fail early with a clear message
* **Cleanup**: Removed dead `retry` parameter from `wp_remote_post` calls

= 2.5.7 =
* **Bug Fix**: Fixed fatal error during restore where `$presigned_urls` (stdClass) was passed to `sprintf` instead of the directory path string
* **Bug Fix**: Made `mkdir` recursive when creating `tmp/db/` directory so it succeeds even if the parent `tmp/` directory was cleaned up
* **Restore Fix**: Clear stale background process queues after DB import to prevent source site's backup tasks from firing on the destination

= 2.5.6 =
* **Concurrency Fix**: Added MySQL advisory locks to prevent concurrent background handlers from processing the same batch simultaneously
* **Reliability**: Fixed race condition where multiple handlers could duplicate compress, encrypt, and upload operations
* **Upload Fallback**: Improved upload step to construct expected encrypted file path when step metadata is missing, preventing silent upload skips

= 2.3.7 =
* **Progress Bar Fix**: Resolved progress bar jumping back to 1% during database backup operations
* **Memory Management**: Implemented dynamic memory management with automatic page sizing based on available system resources
* **Error Handling**: Added robust validation and error handling for S3 file uploads with proper file path checking
* **Logging Improvements**: Enhanced logging system with better filtering to prevent progress bar interference from verbose messages
* **Debug Tools**: Added conditional debug logging (WP_DEBUG only) to help identify unmapped progress messages
* **Database Optimization**: Improved database export operations with dynamic row increment sizing and better memory monitoring

= 2.3.6 =
* **Reliability Fix**: Disabled async dispatch in favor of direct processing for guaranteed execution on all hosting environments
* **Compatibility**: Resolved backup hanging issues on AWS and other servers where async HTTP requests may fail silently
* **Stability**: Reverted to proven direct processing approach for maximum reliability across all hosting providers

= 2.3.5 =
* **UX Improvement**: Disable Backup/Restore buttons when all components are excluded to prevent empty backups
* **UX Improvement**: Fixed progress bar jump from 1% to 0% at the start of backup/restore operations
* **Bug Fix**: Added validation to prevent silent failures when attempting to backup with all components excluded

= 2.3.3 =
* **Bug Fix**: Fixed `is_processing()` method compatibility issue with different WP Background Processing library versions
* **Compatibility**: Replaced method call with direct transient check for maximum compatibility

= 2.3.2 =
* **Security Fix**: Added nonce verification and capability checks to prevent unauthorized access (CVE-2025-3455)
* **Reliability**: Simplified background processing for maximum compatibility across all hosting environments
* **UX Improvement**: Fixed progress bar freeze after restore completion and login
* **Performance**: Removed async complexity that caused race conditions on various hosts
* **Compatibility**: Enhanced stop & reset functionality to prevent stuck states

= 2.3.1 =
* Fixed white screen on deactivation  
* Improved retry logic for presigned URLs  
* Enhanced cleanup & error handling  

= 2.3 =
* Stability improvements  

= 2.2 =
* CSRF fix & updates  

= 2.1 =
* Bug fixes  

= 2.0 =
* Full redesign for easier use  
* Multiple bug fixes  

= 1.6 =
* Manual & automated retries  
* Improved hosting compatibility  

= 1.4 =
* Selective backup/restore added  
* Stop & Reset button implemented  

= 1.3 =
* Support for serialized DB entries  
* PayPal integration  

= 1.0 – 1.2 =
* Initial release & dependency updates
