=== SandyWP Cloner ===
Contributors: sandywphq, rizaardiyanto
Tags: migration, clone, staging, sandbox, backup
Requires at least: 5.8
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 4.8.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Clone this WordPress site into a fresh, disposable SandyWP sandbox: database, themes, plugins and media, in one click, in the background.

== Description ==

SandyWP Cloner copies your live site into a throwaway **SandyWP** sandbox so you can test plugins, themes, updates, or hand a client a safe playground without touching production.

Click once and the plugin works in the background while you keep using your site:

1. Packages your database and `wp-content` into a single archive.
2. Uploads it securely to your SandyWP account (large sites use resumable, direct-to-storage uploads).
3. SandyWP lays down clean WordPress core, restores your content, and rewrites URLs.
4. The new sandbox URL with a one-click admin login appears right on the screen.

A live progress screen shows each step. You can close the page and come back; the clone keeps running.

**You need a SandyWP account** to use this plugin. Connect in one click with the **Connect to SandyWP** button (no token to copy), or paste a personal API token (Account → API keys) as a fallback.

= Why use it =

* One-click clone no manual export/import, no FTP, no database juggling.
* Runs in the background with a real-time status screen.
* Handles large sites: resumable, chunked uploads that survive flaky connections.
* Your live site is never modified only read.

== Third-Party Service ==

This plugin sends your site's data to **SandyWP**, a third-party hosting service, to create the sandbox clone. It is not functional without a SandyWP account.

* Connecting your account: clicking "Connect to SandyWP" opens SandyWP in your browser to authorize this site (an OAuth authorization-code + PKCE flow); SandyWP then returns a connection key scoped to cloning only. Your site URL is sent as part of this request. Alternatively you can paste a personal API token, which is verified against SandyWP's identity endpoint.
* What is sent when cloning: your site's database export and a copy of your `wp-content` files, plus your site URL, WordPress version, and PHP version (in a small manifest). Data is transmitted to the SandyWP URL you configure (default `https://app.sandywp.com`) using the connection key.
* When: account data is sent when you connect; site data is sent only when you click "Clone to SandyWP".
* Service: SandyWP https://sandywp.com
* Terms of Service: https://sandywp.com/terms
* Privacy Policy: https://sandywp.com/privacy

== Installation ==

1. Upload the plugin to `/wp-content/plugins/sandywp-cloner`, or install it from the Plugins screen.
2. Activate it through the **Plugins** menu in WordPress.
3. Go to **Tools → SandyWP Cloner** and click **Connect to SandyWP** approve the connection in the tab that opens, and you're linked (no token to copy). Prefer a token? Click "Connect with an API token instead" and paste one from **Account → API keys**.
4. Click **Clone to SandyWP**.

== Frequently Asked Questions ==

= Do I need a SandyWP account? =

Yes. The plugin clones your site into your SandyWP account, so you need an account and a personal API token.

= Is my live site changed? =

No. The plugin only reads your database and files to build the archive. Nothing on your live site is modified.

= How big a site can it clone? =

Large sites are supported. When your SandyWP account has object storage enabled, uploads go directly to storage in resumable parts; otherwise the plugin uploads in 5 MB chunks. Very large sites need enough free temporary disk space on your host to build the archive.

= Can I make the clone smaller and faster? =

Yes. Open **Advanced options** on the clone screen before you start. You can exclude the media library (usually the bulk of a site), post revisions, spam and trashed comments, and inactive themes and plugins. Everything is included by default; these are opt-in. Backup-plugin folders, caches, and logs are always skipped automatically.

= The clone says "Queued" and never starts. =

The background job runs via WP-Cron through a loopback request. If your host blocks loopback requests or disables WP-Cron without a real cron job, the task can't start. Ask your host to allow loopback requests, or trigger WP-Cron via a system cron.

= Where do the credentials go? =

Your SandyWP URL and API token are stored in your site's options so you can re-clone. You can revoke the token anytime from your SandyWP account, and deleting the plugin removes the stored values.

== Screenshots ==

1. The clone screen: how big your database and media are, what the clone will cost you in time, and one button to start it.
2. The clone runs in the background — package, upload, restore — and the page picks the progress back up if you close the tab.
3. Your sandbox is live, with a direct link and a one-click logged-in admin login.

== Changelog ==

= 4.8.1 =
* The clone screen now notes that the database and files/media sizes are measured before compression, so the actual upload is usually smaller than the figures shown.
* Fixed: during the restore phase, the completed Upload step showed the live restore message (for example "Importing your database") instead of a static caption. It now reads "Upload complete", and the live restore step appears only under the Restore step.

= 4.8.0 =
* The Restore step now shows live progress. Large sites can spend minutes being restored on SandyWP, where the screen previously showed only a static "Restoring" label; it now displays the actual step in progress for example "Importing your database", "Restoring files (part 4 of 12)", "Starting WordPress container" with a real progress bar when SandyWP reports numbered steps (and an animated bar otherwise), plus a "last update Xs ago" readout so you can always tell a running restore from a stuck one. Works with older SandyWP servers too, falling back to the previous behavior.

= 4.7.0 =
* One-click **Connect to SandyWP**: link this site to your account without copying an API token, using a secure OAuth authorization-code + PKCE flow. SandyWP returns a connection key scoped to cloning only. Pasting a token still works as a fallback, now with instant validation as you type.
* Redesigned admin screen. Before you clone, a pre-flight manifest shows your database size, files/media size, and a rough time estimate; a "Trim the clone" panel shows the live MB saving for each thing you skip and updates the clone button (e.g. "Clone to SandyWP 53 MB, ~1 min"). While cloning, a staged Package → Upload → Restore checklist replaces the single bar, with real transfer speed and time-left during upload. Success shows a copyable sandbox URL and a one-click logged-in link; failures now map to plain-English guidance (including a "Retry without media" button when you hit a storage limit). Recent clones are listed so their URLs aren't lost.
* Added a `SANDYWP_CLONER_BASE_URL` constant to override the API base URL (for development/staging) from `wp-config.php`.

= 4.6.1 =
* Backup-plugin working folders and page/object caches that live directly under wp-content for example UpdraftPlus's wp-content/updraft, plus wp-content/cache and wp-content/upgrade are now excluded from the clone, matching how the same folders were already skipped under uploads. This leaves out disposable, often multi-gigabyte scratch a sandbox never needs, and avoids errors when a backup plugin deletes its own log files midway through the export.

= 4.6.0 =
* Added support for cloning WordPress multisite networks. Subdirectory networks (subsites at /path) are exported in full the network tables plus every subsite and restored into a SandyWP sandbox as a working multisite. Subdomain networks remain unsupported (they need wildcard DNS and per-subsite TLS, which the single-host sandbox model can't provide) and are reported clearly instead of producing a broken clone.

= 4.5.2 =
* Fixed an "Import failed" error that could stop a clone during the database step on sites carrying older or loosely-typed data (for example some jReviews / Joomla-heritage tables). The exported database now reloads under a permissive SQL mode, the same way mysqldump does, so values the sandbox's stricter database would otherwise reject empty values in number columns, out-of-range integers, zero dates no longer abort the import.

= 4.5.1 =
* The progress screen now follows the restore to completion. Large sites can take longer to restore than the background poller runs, which previously left the bar stuck on "Uploaded still restoring" even after the sandbox was live; the status now updates straight from SandyWP, so it reaches "ready" (or "failed") on its own.

= 4.5.0 =
* Much faster database export on large sites: each table is now paged by its primary key instead of OFFSET. On tables with hundreds of thousands of rows (postmeta, usermeta, WooCommerce, etc.) this cuts the database step from many minutes to seconds.
* Skip more plugin audit/activity/log tables (schema kept, history dropped) so heavy logging plugins don't bloat the clone.

= 4.3.2 =
* Redesigned the finished and failed states: the progress bar is replaced by a success (or error) badge on a tinted card, and the sandbox link plus its actions (Open, Visit, Dismiss) now sit on a horizontal row instead of a tall left-aligned stack.

= 4.3.0 =
* The SandyWP URL field is gone it defaults to https://app.sandywp.com, so you only paste your API token.
* Added a **Save API token** button so you can store your token without starting a clone.
* The clone no longer takes over the screen. After you click clone, it appears as a row in a new **Your import** section below the form, with a live progress bar, while the form stays available.
* Clearer reminder that you can close the tab the import keeps running in the background and the progress reappears when you return.

= 4.2.4 =
* Fixed: after a clone finished or failed, clicking "Clone again" then refreshing the page replayed the old result screen instead of returning to the form. "Clone again" now clears the stored status so a refresh starts fresh.

= 4.2.3 =
* Fixed: values containing "%" (e.g. URL-encoded links in some SEO plugin tables) were exported with WordPress placeholder tokens instead of "%", causing corruption and "Data too long" errors on restore.

= 4.2.2 =
* Fixed: the status screen could show both "Cancel clone" and "Clone again" at once. Now only Cancel shows while a clone runs, and Clone again only after it finishes or fails.

= 4.2.1 =
* Fixed: binary and BLOB database values (e.g. some import/SEO plugin tables) are now exported as hex literals, preventing "Data too long" / corruption errors during restore.

= 4.2.0 =
* Added a Cancel button to stop a clone in progress; it aborts cleanly even mid-packaging and frees any in-flight upload.

= 4.1.0 =
* Faster packaging: already-compressed media (images, video, audio, PDFs, fonts) is stored instead of re-compressed.
* Always skips junk that never belongs in a sandbox backup-plugin folders, caches, logs, version-control and dependency directories, and database transients.
* New **Advanced options**: optionally exclude the media library, post revisions, spam/trashed comments, and inactive themes and plugins.

= 4.0.0 =
* Rearchitected into a namespaced, object-oriented plugin (autoloader, single-responsibility classes).
* Background clone now runs on WP-Cron instead of a custom endpoint.
* Assets enqueued instead of inlined; full internationalization; security and escaping hardening.
* Added uninstall cleanup.

= 3.2.0 =
* Direct-to-object-storage resumable multipart uploads for large sites.

= 3.0.0 =
* Asynchronous background clone with a live, branded status screen.

== Upgrade Notice ==

= 4.2.0 =
Adds a Cancel button to stop a clone in progress.

= 4.1.0 =
Faster packaging and new Advanced options to exclude media, revisions, comments, and inactive themes/plugins. Full clone remains the default.

= 4.0.0 =
Internal rearchitecture for reliability and WordPress.org compliance. No configuration changes required.
