=== Domain Move ===
Contributors: quintaphon
Donate link: https://buymeacoffee.com/quintaphon
Tags: search replace, domain, migration, serialized, move site
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.1.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Move WordPress to a new domain safely. Serialization-safe search and replace across the whole database, with a dry run first.

== Description ==

Domain Move replaces an old domain with a new one everywhere in your database: posts, meta, options, widgets, page builder data and plugin tables. It was built for moving the WordPress admin to a private host while a static export of the site keeps the public domain, and works just as well for any domain change.

Plugin site: [quintaphon.com/wordpress/domain-move](https://quintaphon.com/wordpress/domain-move/)

= Safe by design =

* **Dry run first:** see every table, row and replacement before anything is written, with before and after examples.
* **Serialization-safe:** serialized data is rewritten token by token and every string length is recalculated. Nothing is ever unserialized, so no plugin objects are created while the data is changed. A value that does not parse is left exactly as it was and reported.
* **Exact host matching:** `example.com` and `www.example.com` are replaced, but never a subdomain such as `cdn.example.com` and never a longer name such as `example.com.au`. Subdomains that were found are listed in the report.
* **Every link format:** plain links, JSON-escaped links (`https:\/\/`) and URL-encoded links (`https%3A%2F%2F`).
* **Static Push stays on the public domain:** its settings, including the Static site address, are never rewritten.
* **Skip list:** leave other chosen options untouched, with `*` as a wildcard.
* **Small batches:** rows are processed 200 at a time over AJAX, so large databases never hit a server timeout. You can stop a run between batches.
* **Site address last:** option tables are processed at the very end, so the site keeps working until the run is done.

= Also included =

* Upgrade `http://` links to `https://` on the new domain.
* Replace or keep email addresses on the old domain.
* Include or leave out post GUIDs.
* Pick the tables to include, with a filter for large installs.
* Health Check: wp-config.php constants that still hold the old domain, tables without a primary key, object cache and multisite notes.
* History of the last 20 dry runs and replaces.

= Before you run the replace =

1. Point the new domain at your server and add it to the web server and SSL certificate.
2. Take a full database backup.
3. Run a dry run and review the results.

After the replace your login cookie still belongs to the old domain, so you log in again on the new one.

== Installation ==

1. Upload the `domain-move` folder to `/wp-content/plugins/`, or install the ZIP under Plugins > Add New > Upload Plugin.
2. Activate the plugin.
3. Open Tools > Domain Move.

On multisite, only super admins can use the tool.

== Frequently Asked Questions ==

= Can I undo a replace? =

Only from a backup. Domain Move asks you to confirm that you have a fresh database backup before every replace.

= Why are some rows skipped? =

Rows are skipped when their option name is in the skip list, or when a table has no primary key. A row without a primary key cannot be updated safely, so matches there are counted but never changed.

= What does "unreadable serialized values" mean? =

The value looked like serialized data but did not parse, usually because it was already damaged before the move. It is left exactly as it was.

= Does it change wp-config.php? =

No. If wp-config.php defines WP_HOME, WP_SITEURL, DOMAIN_CURRENT_SITE or a similar constant with the old domain, the Health Check lists it so you can edit it by hand.

= Does it work with page builders? =

Yes. Builder data is stored as serialized or JSON text, and both are handled.

== Screenshots ==

1. Domain Move: old and new domain, what to replace and the tables to include.
2. Results of a dry run, with before and after examples.
3. Health Check.

== Changelog ==

= 1.1.1 =
* Static Push settings (cfsp_*, including the Static site address) and its cached transients are now always protected, even if the skip list is empty or edited. The skip list is only for extra options.

= 1.1.0 =
* New admin app in the Static Push design: sidebar navigation, Results, Health Check and History pages.
* Run replace now asks for confirmation in a dialog, and warns when no dry run was made with the same settings.
* A run can be stopped between batches.
* The form remembers the new domain, options, skip list and table choice.
* History of the last 20 runs.
* Table and column names go through the %i placeholder of $wpdb->prepare(); requires WordPress 6.2.
* Table lists and column layouts are cached for the request.
* The site address is read through get_option() after the cache flush.
* Added readme.txt and uninstall.php.

= 1.0.1 =
* Faster batches on large tables (continues after the last primary key).

= 1.0.0 =
* First release.