Museder RestoreOne – WP Backup & Restore

Description

Museder RestoreOne is built for larger WordPress sites on everyday hosting—and includes large-site backup and restore in this plugin (the version you install from WordPress.org), not behind a separate paid core product. Package your database and wp-content into one downloadable archive, run background backup jobs (not a single fragile browser request), and restore through a guided wizard with progress, logs, and safety checks.

Looking for large-site backup without a paid upgrade?

Many WordPress backup plugins reserve chunked or large archive imports, direct site-to-site migration, multisite, or “unlimited” migration size for paid or premium tiers. Museder RestoreOne includes the following in this plugin for local, on-server workflows (download your archive, copy it to another host, restore with the wizard):

  • Background backup jobs (async via WordPress cron)
  • Backup size estimation before you commit to a long job
  • Chunked REST uploads for multi‑gigabyte ZIPs on low upload_max_filesize hosts
  • Validate & dry-run before a full restore
  • Multiple backup schedules on the same site (local schedules included in this plugin)
  • Full-site restore / migration using archives you store—no third-party cloud required

Large-site backup & restore (included in Museder RestoreOne)

  • Background backup jobs — Full-site backups can run as async jobs processed via WordPress cron, with progress in the admin instead of relying on one long page load.
  • Backup size estimation — Scan database and wp-content in batches (thousands of files per pass) so you can see estimated size before starting a large backup; sites over 1 GB get guidance in the UI.
  • Chunked archive uploads — Upload multi‑gigabyte backup ZIPs over the authenticated REST API in small chunks with retries and integrity checks—useful when upload_max_filesize / post_max_size are low.
  • Validate & dry-run before execute — Review an archive and run checks before a full restore on production.
  • Long-restore resilience — Restore progress can continue when admin sessions or nonces expire mid-job (restore token fallback and tolerant polling during database import).
  • Honest limitsSingle files over 2 GB are skipped for stability; total site size can exceed 2 GB when each file is under the cap. Very large restores may still need staging, higher PHP limits, or host cron—see FAQ.

Database work uses WordPress APIs in PHP—no mysqldump required. Archives use ZipArchive or WordPress’ bundled PclZip when the ZIP extension is unavailable.

Who is it for?

  • Shared-hosting sites that need full-site backup and restore for larger installs when their current backup setup’s free plan no longer covers big uploads, long-running jobs, or migration helpers that many tools reserve for paid plans—but you still want those capabilities on everyday hosting.
  • Growing or large WordPress sites (media-heavy, many plugins, multi‑GB wp-content) without shell access or mysqldump.
  • Agencies and freelancers who migrate clients with chunked uploads, size estimates, and validate/dry-run before go-live.
  • Anyone who wants a focused backup restore workflow on shared hosting without extra complexity.

More features

  • One-click full-site backup
    Export the database, meta.json, and wp-content/ into a single archive you can download, store locally, or restore later.

  • Restore Center wizard (migration & recovery)
    Upload & analyze review summary & options execute restore with real-time progress and logs.

  • Schedules and logs
    Automatic backup schedules (or manual runs), structured logs, download, and cleanup from the admin.

  • Modern admin UI
    Dashboard, Backups, Restore, Schedules, Logs, and Settings with clear status and responsive layout.

Multisite

This release is not formally tested on WordPress Multisite. For predictable results, use Museder RestoreOne on standard single-site installs (one site per admin context). If you run a network, treat use as experimental until you have verified backups and restores on a staging clone.

External services

This plugin does not use external services.

The only programmatic outbound HTTP the base plugin performs by default is an optional, short non-blocking request to your own site’s wp-cron.php (same host / local loopback) to encourage scheduled tasks to run. No third-party API is called for backups or restores.

All admin JavaScript and CSS for Museder RestoreOne are loaded from files shipped under this plugin’s assets/ directory (including vendored libraries under assets/vendor/). See the FAQ for more on the local wp-cron.php nudge.

Privacy

What this plugin stores on your server

  • Backups — Complete-site archives are written under your WordPress uploads area (typically wp-content/uploads/museder-restoreone/backups/ or the path shown on the Backups screen). Each archive contains a database export (database.ndjson), meta.json, and a copy of wp-content/ from your site at backup time.
  • Logs — Text logs for backup, restore, and related operations are stored under wp-content/uploads/museder-restoreone/logs/ (see the Logs admin screen).
  • Restore reports — When you generate a restore report, files are stored under wp-content/uploads/museder-restoreone/reports/ (or the path configured for reports on your install).
  • Schedules and settings — Options and scheduled events are stored in your WordPress database like other plugins.

Diagnostics

  • Version / build heartbeat — After an upgrade, the plugin may write a one-line informational entry to the local Logs directory (same server, no remote host) noting the active plugin version and build id. This is for support troubleshooting only.

Exact folder names may vary with your uploads path or custom content directory; nothing is sent to a fixed external hostname by this plugin. The plugin resolves these locations using WordPress APIs (for example wp_upload_dir() and path helpers derived from your install) rather than hard-coded internal constants, so custom wp-content or uploads layouts can be reflected correctly where your host allows.

Third parties

Museder RestoreOne does not upload your backup contents, database, or logs to third-party APIs or clouds. That statement matches External services above and the FAQ entries on external data and local wp-cron loopback.

Retention and deletion

You can delete backup archives from the Backups screen, remove or download logs from Logs, and adjust retention-related options where provided.

Uninstall (uninstall.php) removes plugin-owned options, transients (including timeout rows), dynamic job-lock option rows, and scheduled cron hooks whose names start with museder_restoreone_. It does not delete backup ZIP archives, log files, restore reports, or other files under your uploads/storage tree; delete those manually from the Backups / Logs UI or your host if you no longer need them.

On WordPress Multisite, if you delete this plugin from the network, uninstall.php runs the same options/cron cleanup on each subsite, loading site IDs in batches of 100 so a very large network does not pull every site into memory at once. This applies only at plugin uninstall—not to backup or restore. Very large networks should still use a maintenance window so uninstall is not interrupted by web-server timeouts.

Screenshots

  • Dashboard — environment checks, recent backups, and schedule overview for large-site readiness.
  • Backups — estimated site size, async backup job progress, and full-site archive list.
  • Restore Center — chunked upload, validate/dry-run, and 3-step restore wizard with progress.
  • Schedules — automatic backup jobs and quick schedule builder.
  • Logs — backup and restore log files with preview.
  • Settings — general options and system diagnostics for shared hosting.

Installation

From the WordPress.org Plugin Directory (recommended)

  1. In your WordPress admin, go to Plugins Add New.
  2. Search for Museder RestoreOne (or open Museder RestoreOne on WordPress.org and click Download, then upload if your host blocks the in-dashboard installer).
  3. Click Install Now, then Activate.
  4. Open the Museder RestoreOne menu in your admin sidebar.
  5. Go to Backups or Restore and create your first backup.

Manual install (alternative)

  1. Download the plugin ZIP from WordPress.org or copy the museder-restoreone folder into /wp-content/plugins/ (FTP/SFTP or Plugins Add New Upload Plugin).
  2. Activate Museder RestoreOne under Plugins.
  3. Open Backups or Restore and create your first backup.

FAQ

Do I need a paid plan for large-site backup and restore?

No. Museder RestoreOne includes background backup jobs, size estimation, chunked archive uploads, validate/dry-run, multiple local schedules, and full-site restore/migration using archives stored on your servers.

Many other backup plugins move chunked imports, premium migration (push from site A to B), multisite, or unlimited archive size into paid tiers. Museder RestoreOne is aimed at users who want those local large-site capabilities in this plugin—compare the checklist in the Description to what your host and workflow actually need.

Is Museder RestoreOne suitable for large WordPress sites?

Yes—with realistic expectations. Museder RestoreOne targets larger single-site installs on shared and managed hosting:

  • Backups: Async background jobs, batched size estimation, and archive building with ZipArchive or PclZip fallback.
  • Uploads: Chunked REST uploads for big backup ZIPs when PHP limits are tight.
  • Restores: Validate and dry-run steps, progress UI, restore token fallback when a long database import outlasts the admin session, and detailed Logs.

Limits: Each individual file over 2 GB is skipped (reported at backup time). Total site size can be much larger if files stay under that cap. Shared hosts may still impose PHP time limits, disk space, or web-server timeouts on the final restore execute step—use staging, chunked upload, and dry-run first; see the FAQ on very large archives.

Can I migrate my WordPress site to another host with Museder RestoreOne?

Yes. On the source site, create a full-site backup and download the archive (or copy it securely to the new server). On the destination site, use the Restore Center wizard to upload and restore. Museder RestoreOne does not send backup contents to third-party clouds; migration stays on servers you control. For large sites, use chunked upload, validate/dry-run steps, and test on staging before switching DNS.

What does the backup archive contain?

Each backup archive includes:

  • database.ndjson — a structured export of your WordPress database (plugin-owned format).
  • meta.json — metadata about when and how the backup was created.
  • wp-content/ — your themes, plugins, and uploads.

Together, these files are enough to recreate your site on the same or another server.

Does compatibility with third-party backup formats imply an official partnership?

No. Museder RestoreOne may document or implement technical compatibility with certain third-party archive or migration formats so you can move data between tools on your own server. That compatibility is not an endorsement, partnership, or affiliation with those projects unless explicitly stated elsewhere by the authors.

Are there any file size limits?

Yes. For safety and compatibility on large sites, single files larger than 2 GB are skipped during backup. They are not included in the backup ZIP and will not be restored.

Total site size can exceed 2 GB (many uploads, themes, and plugins) as long as each file is under 2 GB. The Backups screen can estimate database and file size before you start, and warns when totals suggest a long or heavy job.

When files are skipped, the backup completion message shows skip reasons and examples.

Do I need mysqldump, SSH, or WP-CLI?

No. Museder RestoreOne does not require mysqldump, SSH, or WP-CLI. Database backup and restore use WordPress database APIs in PHP. Shell or CLI tools on your host are optional extras, not requirements. If mysqldump is unavailable—as on many shared hosts—Museder RestoreOne still works.

What if ZipArchive is not enabled on my server?

If your server does not have the ZipArchive PHP extension, the plugin will automatically use WordPress’ built-in PclZip library to create and extract archives.

PclZip can be slower and more memory- or disk-sensitive on very large sites than ZipArchive. If a host blocks reading WordPress core’s wp-admin/includes/class-pclzip.php (for example via open_basedir), backup or restore may fail with a clear error in Logs — use the museder_restoreone_core_admin_include_path filter if your layout is non-standard (see FAQ below).

How does chunked restore upload work over REST?

Large archive uploads use the plugin’s authenticated REST API (museder-restoreone/v2). Chunk bytes are streamed from the HTTP request body (php://input) only for that request, assembled into temporary files under your WordPress uploads area, and never forwarded to third-party URLs. Multipart uploads use PHP’s normal uploaded-file handling instead. All chunk routes require manage_options and a valid REST nonce.

Will scheduled backups and email always run?

Scheduled backups depend on WordPress cron (or your host’s system cron if DISABLE_WP_CRON is enabled). Email notifications depend on your server’s wp_mail configuration (SMTP plugin, host mail relay, etc.). If cron or mail is blocked, use Settings Send Test Email, check Logs, and configure host cron / mail as needed.

Can I run a full restore (execute) on a very large archive?

Very large restores may hit PHP time limits, web server timeouts, or disk space constraints on shared hosting. The Restore wizard supports validate and dry run steps so you can verify an archive before a full execute. For huge sites, prefer a staging clone or WP-CLI-driven restore where your host allows long-running PHP.

What is *not* included in Museder RestoreOne (vs typical paid upsells)?

Museder RestoreOne is optimized for local full-site archives (backup download or copy chunked upload restore). It does not replace every feature you may see in other vendors’ paid tiers, for example:

  • Managed offsite cloud as the primary backup destination.
  • One-click push migration from dashboard to dashboard without moving an archive file yourself (migration in this plugin is archive-based).
  • Incremental-only backup engines or real-time replication (Museder RestoreOne focuses on full-site snapshots).
  • Formally supported Multisite (experimental only in this release—see Description and FAQ).

If you need only large local backup and restore on shared hosting, those gaps may not matter; if you need cloud-first or network-wide Multisite, compare other tools to your workflow.

Where are the logs stored?

All logs are stored under:

wp-content/uploads/museder-restoreone/logs/

You can view or download the latest logs directly from the Logs page in the Museder RestoreOne admin menu.

What happens to plugins during restore?

Optional safe mode (on by default in the Restore wizard unless you turn it off) runs after a restore import: Museder RestoreOne saves a snapshot of which plugins were active (museder_restoreone_prev_active_plugins), sets a safe mode marker (museder_restoreone_safe_mode), and shows an admin notice on the Dashboard and Restore screens so you can verify the site. Museder RestoreOne does not automatically deactivate or reactivate other plugins—their activation state is unchanged. Exit Safe Mode (button or AJAX) only deletes the marker and the stored snapshot; you still manage plugins in WordPress as usual.

Does this plugin send data to external services?

No. Museder RestoreOne runs entirely on your server and does not send backup contents or site data to any external API or cloud service.

The Offline readiness / local rules scan on the Dashboard uses local heuristics only (no remote AI service is invoked by the shipped plugin).

Does the plugin make HTTP requests to my own site?

Sometimes. To help scheduled tasks run promptly, the plugin may send a short, non-blocking HTTP request to your own site’s wp-cron.php (a local loopback). That stays on your server, does not transmit backup contents to third parties, and is a common WordPress pattern. If DISABLE_WP_CRON is enabled, your host may rely on system cron instead.

Does this plugin expose my backup files publicly?

No. Backup download and upload endpoints are protected by time-limited tokens and secret keys generated inside your WordPress site. Only users with access to your WordPress admin can generate valid links, and each link expires after a short period of time.

Does Museder RestoreOne support WordPress Multisite?

Not as a formally supported configuration in this release. The plugin is built and QA’d primarily for single-site WordPress. Multisite networks may behave differently across subsites, uploads paths, and roles; use on Multisite only after your own testing on a staging copy of the network.

Can I use a custom languages directory?

Yes, advanced sites can override the detected languages directory with the museder_restoreone_languages_dir filter. Return an absolute path without a trailing slash, or return an empty string to skip language-directory handling.

Can I use a custom mu-plugins directory?

Yes, advanced sites can override the detected must-use plugins directory with the museder_restoreone_mu_plugins_dir filter. Return an absolute path without a trailing slash, or return an empty string if your site does not use a must-use plugins directory.

What if my WordPress core admin include files are in a non-standard location?

Most sites do not need any changes. For unusual server layouts where core admin API files cannot be found automatically, developers can use the museder_restoreone_core_admin_include_path filter to return a readable absolute path for the requested core file. Invalid or unreadable values are ignored and the plugin falls back to its default resolution.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Museder RestoreOne – WP Backup & Restore” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

2.7.264

  • Backup jobs: fixed cancel race conditions so persisted cancelled state is reloaded/merged before scheduling and final save, preventing stale in-memory running/packing overwrite after long batches.
  • Backup jobs: added Gate B cancel check after preparing stage — prevents cancel from being overwritten by save_job() during slow manifest scans on shared hosting (13–40 seconds).
  • Backup jobs: added defensive schedule guard to skip wp_schedule_single_event() when latest state is terminal or cancel requested.
  • Backup UI: in pclzip compatibility repack mode, progress smoothing is capped and status now shows real file progress (processed_files/total_files) to avoid misleading near-complete percentages.
  • Backup UX: after cancel success, UI performs a delayed status verification and warns if the same job is still running.
  • Packing diagnostics: detect common large existing backup artifacts (ai1wm, backwpup, wordpress-*.tmp) and surface warnings to help avoid very slow repack behavior.
  • Backup (Auto mode): large-site detection now applies when file count exceeds 50,000 OR total scanned size exceeds 1 GB, so media-heavy sites with fewer files correctly use Fast mode and Smart Exclude instead of Balanced with Smart Exclude off.
  • Restore session: admin session tokens are now saved at execute() time (when user is authenticated) and read from job metadata during WP-Cron import, fixing session loss on real shared hosting where get_current_user_id() returns 0 in cron context.
  • Restore session: WordPress Heartbeat wp-auth-check is disabled on plugin admin pages during active restores to prevent the core “session expired” overlay from firing during the DB import window.
  • Restore upload: duplicate file detection — when uploading a local backup file that already exists on the server, a confirmation dialog offers to use the existing file (skip upload) or upload and overwrite. Prevents duplicate -1 suffix copies.
  • Backup export: runtime plugin options (restore_lock, active_job_id, restore_token) are excluded from NDJSON database exports to prevent stale state from being carried in backups.

2.7.263

  • Restore (P0): preserve admin session tokens and re-inject cron, restore lock, and active job state after database import so restores no longer stall when the admin session is invalidated mid-job.
  • Restore: add file-based restore token (survives DB rebuild) with REST fallback when WordPress nonces expire during long restores.
  • Restore UI: polling tolerates transient 401/403 responses during DB import instead of stopping immediately.

2.7.262

  • Backup reliability: when PclZip compatibility repack is active, the async job runner no longer keeps a long-lived ZipArchive handle on the same .zip file (PclZip and ZipArchive were both mutating the archive, making close() extremely slow on large sites and risking central-directory corruption).
  • Backup verification: post-close archive checks now resolve ZIP entry names more robustly (zip_archive_has_entry() — forward slashes, optional ./ prefix, and ZipArchive::FL_NOCASE when available) so false “verification failed” results are less likely to trigger a full repack.

2.7.261

  • Developer / review automation (not shipped in the WordPress.org ZIP): WP-CLI matrices for all registered wp_ajax_museder_restoreone_* actions, REST routes under museder-restoreone/v1 + v2, and admin_post_museder_restoreone_* downloads (capability + nonce / referer expectations); nginx reverse-proxy smoke in front of the stock Apache WordPress image; ZIP clean install + Plugin Check; Multisite 2-site stack + network uninstall option/cron verification; mail pipeline smoke (wp_mail / Email_Handler::test_email reaches PHPMailer); PHPCS tooling (phpcs.xml.dist + tools/phpcs Composer kit) with run-phpcs-summary.sh.
  • Documentation: docs/2026-05-06__v2.7.261__readme-key-features__admin-ui-map.md maps readme Key features to admin page= slugs for manual review.
  • Maintenance: restore job AJAX handlers that “clean” output now use ob_clean() instead of ob_end_clean() so they flush stray bytes without popping the whole output-buffer stack (same idea for REST chunk prepare_request_environment()). Behavior for real browsers is unchanged; this avoids breaking nested buffers in automated tests and CLI.

2.7.260

  • Security: REST chunk v2 upload_id limited to UUID v4 (same format as wp_generate_uuid4()); status / chunk / finalize / abort and temp directory helpers reject garbage ids; cleanup skips non-UUID folders under v2-uploads.
  • Security: museder_restoreone_get_chunk_path() second argument now uses museder_restoreone_safe_path_join() (no traversal via relative fragments).
  • Security: WPress safe_join() final check uses directory-prefix boundary (aligned with other path helpers).
  • Review UX: admin script globals MusederRestoreOneAddon (primary) with MusederRestoreOnePro kept as an alias for backward compatibility; strings unchanged.
  • UI: fixed [data-bl-theme="dark"] selectors in admin-style.css that were escaped incorrectly so dark-theme list/table header styles apply.
  • Multisite: uninstall.php processes sites in batches to reduce memory spikes on large networks (readme Privacy note updated).
  • Developer: docs/2026-05-06__v2.7.260__端點矩陣__REST-AJAX-AdminPost.md — hook capability nonce / permission_callback matrix for reviewers.

2.7.259

  • Security: museder_restoreone_safe_path_join() now uses a trailing-slash directory prefix check; log path resolution and admin download handlers (logs, reports, restore-job database.sql) validate realpath() + prefix to avoid ambiguous strpos matches.
  • Review UX: neutral copy for optional add-on placeholders (MusederRestoreOnePro / admin UI modal); Dashboard “AI” strings describe local / offline scan behavior only.
  • Documentation: readme External services (loopback wp-cron.php, local assets/vendor JS/CSS), Privacy / uninstall aligned with uninstall.php, FAQ on third-party format compatibility (no endorsement).
  • Maintenance: added root uninstall.php (options, transients, job-lock rows, museder_restoreone_* crons only — no backup/log/report file deletion). create-package.sh ships uninstall.php in the ZIP.
  • Developer tooling: tools/functional-test/ adds REST permission smoke, safe_path_join traversal checks, external-URL scan script, and uninstall manifest verification (still not included in the WordPress.org ZIP).
  • Vendor: restored assets/vendor/chart.4.5.1.min.js alongside chart.4.5.1.js; expanded assets/vendor/README.txt (versions, licenses, sources).

2.7.258

  • Security: museder_restoreone_get_backup_path() now compares backup directory roots with a trailing-slash boundary after realpath() normalization, preventing ambiguous prefix matches between similarly named directories.
  • Multisite: when WordPress Multisite is enabled, RestoreOne admin screens show a non-blocking notice that Multisite is experimental (readme stance unchanged).
  • Documentation: FAQ entries for PclZip performance, REST chunk / php://input, cron and mail dependencies, and large-archive restore limits; Privacy notes optional local build/version log heartbeat after upgrades.
  • Developer tooling: added tools/functional-test/ scripts (not shipped in the WordPress.org ZIP) to reproduce small-site, large-site, PclZip-forced, chunk REST smoke, and cron listing checks via Docker/WP-CLI.
  • Email: test email body no longer uses emoji (broader mail client compatibility).

2.7.257

  • UI: Improved dark-theme contrast for Settings field labels, helper text under General Settings, Environment Compatibility success badges, and System Diagnostics uppercase labels (avoids light-theme label colors on dark cards).
  • Documentation: Readme feature line for schedules now matches optional scheduling (no longer implies a minimum number of schedules).
  • Maintenance: Removed unused legacy template templates/restore-page.php (Restore admin screen uses page-restore.php only) to avoid mixed-language placeholder strings in the distributed tree.

2.7.256

  • WordPress.org review follow-up: core admin include paths are now built in segments (root + directory parts + whitelisted filename), avoiding a single literal core-relative include path while preserving graceful fallback behavior.
  • Developer filters: added museder_restoreone_core_admin_include_path for non-standard WordPress directory layouts; invalid or unreadable filtered paths are ignored.
  • Documentation: FAQ now explains custom languages, mu-plugins, and core admin include path filters for advanced non-standard installs.

2.7.255

  • WordPress.org review: replaced hardcoded/internal WordPress path constants used for core includes and language/mu-plugin directory discovery with helper-based path resolution derived from WordPress APIs (wp_upload_dir(), plugin path helpers) and graceful fallbacks.
  • Backup scope: language and mu-plugin directory prefixes are now resolved through plugin helpers and filters (museder_restoreone_languages_dir, museder_restoreone_mu_plugins_dir) instead of WP_LANG_DIR / WPMU_PLUGIN_DIR.
  • Restore/upload helpers: core admin include loading is centralized in museder_restoreone_get_core_admin_include_path() and avoids ABSPATH path concatenation; missing core helpers fail gracefully instead of fataling.

2.7.254

  • REST: Chunk upload (includes/class-chunk-handler-v2.php) permission_check now uses the same two-step REST nonce pattern as v2 restore (check_permissions): X-WP-Nonce then rest_nonce parameter, empty token vs wp_verify_nonce as separate WP_Error branches; HTTP 401 for invalid/missing nonce and shared museder_restoreone_invalid_nonce / museder_restoreone_forbidden codes with v2 restore.
  • REST: Free AI REST permission_check nonce failures now return 401 with museder_restoreone_invalid_nonce (aligned with v2 restore; same user-facing message).
  • Readme: added == Privacy == (data locations, third parties, optional add-ons, retention) and explicit Multisite stance in Description + FAQ.
  • Security hygiene: added index.php sentinels under includes/, includes/wpress/, templates/, assets/ (+ assets/css/, assets/js/), and languages/ to avoid directory listing on misconfigured hosts.

2.7.253

  • Compliance / Plugin Check: PclZip fallback now loads WordPress core’s PclZip file instead of shipping a duplicate includes/vendor/pclzip copy, so the broader plugin-check.ruleset.xml scan is not dominated by third-party PHPCS violations in bundled library code.
  • Documentation: Clarifies that changelog lines mentioning tests/ or tools/docker/ refer to the public development repository only; those paths are not part of the distributed plugin ZIP from WordPress.org.

2.7.252

  • Developer / WordPress Plugin Check: Report download wp_die() branches use per-status literal response codes with inline esc_html() / esc_html__() so OutputNotEscaped passes under Plugin Check.
  • Developer: tests/php-regression/final_review_248_regression.php uses esc_html() on CLI output and wraps checks in museder_restoreone_final_review_248_regression_run() to satisfy prefix / escaping static analysis.
  • Docker sync (tools/docker/setup.sh): exclude root .DS_Store from the plugin tarball so Plugin Check does not flag hidden files in wp-content/plugins.

2.7.251

  • WordPress Plugin Check: Report download error path now passes HTTP status to wp_die() via the response args array (avoids OutputNotEscaped on a dynamic third-argument integer).

2.7.250

  • Security: NDJSON database import now applies the same table prefix allow-list as the SQL restore path before DROP TABLE / replace(); disallowed names are skipped and logged.
  • Stability: get_ai_recommendations() checks class_exists( 'Museder_Restoreone_AI_Service' ) before calling it (avoids fatal if an add-on filter is misconfigured).
  • WordPress.org review: AI schedule recommendation errors use neutral codes/messages (addon_not_active, addon_service_missing) instead of pro_required.
  • REST (v2 restore): check_permissions validates X-WP-Nonce / _wpnonce in two steps (empty check, then wp_verify_nonce), matching the AI REST controller pattern.

2.7.249

  • WordPress.org strict review: AJAX museder_restoreone_refresh_nonce now requires a valid existing nonce before issuing a new one; admin JS sends the current nonce on refresh.
  • AI (free): removed daily scan quota / remaining / dailyScans from the hosted build (local preview only; no trialware-style limits in API responses).
  • Safe mode: readme, Restore/Dashboard notices, restore options help text, and admin toasts now match implementation — snapshot + marker only; Exit Safe Mode clears the marker without claiming automatic plugin activation changes.

2.7.248

  • WordPress.org review: add_option() job locks now use an explicitly prefixed $option_key built from OPTION_LOCK_PREFIX at the call site (addresses static analysis / human review feedback on dynamic option names).
  • WordPress.org guidelines: removed the free-tier limit of a single backup schedule; multiple local schedules are allowed for all users.
  • Schedules: cron pattern, exclude paths, and retention policy fields are saved for all installs (local features; not gated on a separate add-on).
  • Backups: optional backup labels apply to archive names and metadata for all users; encryption and cloud destination metadata/upload remain add-on scoped, with a class_exists() guard on cloud upload.
  • Admin log download: check_admin_referer() runs immediately after resolving the log basename and before reading the file from disk.

2.7.247

  • Security & WordPress.org review: Added explicit check_ajax_referer() calls in admin AJAX handlers (UI, restore, logs, settings, email) so tooling and reviewers can see nonce verification in each handler.
  • Backup download (admin-post): For nonce-based links, check_admin_referer() now runs before reading $_GET['file']; signed-token downloads unchanged. Clearer error when the filename is missing after a valid nonce.
  • Report download: Replaced missing Pro controller with Museder_Restoreone_Restore_Report::download() plus check_admin_referer( 'museder_restoreone_download_report' ), path confinement under the reports directory, and safe streaming headers.
  • Backup jobs: Clarified comments for dynamic add_option() lock keys (no invalid PHPCS ignore).

2.7.246

  • Admin UI: improved text contrast when using dark appearance (data-bl-theme="dark") — Restore Center step cards, glass cards, and status colors align with theme tokens (--text-dark, --surface, --glass-*).
  • Restore Center: progress track uses a deeper neutral background; percentage label uses a subtle text shadow so it stays readable at low fill levels.
  • Safe mode notices (Restore + Dashboard) use var(--text-muted) so body copy follows the active theme.
  • Legacy restore wizard (restore.css): completed-step label uses a brighter green in dark mode.

2.7.245

  • WordPress.org review follow-up: readme — single Changelog section (removed duplicate header); FAQ documents local wp-cron.php loopback requests. Code — trigger_restore_job() formatting in class-restore-handler.php; AI REST API namespace aligned to museder-restoreone/v1 for consistency with the plugin slug.

2.7.244

  • WordPress.org review hardening: removed bundled PRO activation, license verification, embedded PRO modules, and review-facing upgrade messaging from the free plugin package. Free build now keeps only the core backup, restore, schedule, logs, and settings experience, while preserving a clean add-on detection boundary for a separate plugin.

2.7.243

  • Schedule handler: GLOB_BRACE fallback for PHP builds that omit it; retention apply_retention_rules file_exists check before filemtime to avoid warnings. Restore page: Exit Safe Mode button id unified to museder-restoreone-exit-safe-mode-btn with JS fallback for backup-lite-exit-safe-mode-btn. Small-site flow verified (backup, restore, settings, schedules, safe mode exit).

2.7.242

  • WP.org compliance: Plugin Check 1.7.0 clean (0 errors, 0 warnings). Security and request handling (nonce/capability, sanitize/validate, json whitelist). Path and storage under wp_upload_dir. Removed direct core includes where possible; ABSPATH guards. Naming: menu/REST/JS prefixes unified to museder-restoreone. Readme external services (S3, OpenAI); Plugin URI updated.

2.7.223

  • Compliance: Reworked deprecated download handler to avoid bootstrapping WordPress and route downloads via admin-post.php.
  • Compliance: Documented external services with plain Terms/Privacy URLs for review tooling.
  • Security: Added explicit nonce checks in key AJAX handlers for clearer automated detection.
  • Security: Hardened restore SQL import with a conservative allow/deny statement strategy.
  • Compatibility: Reduced reliance on hard-coded WP_* directory constants by using wp_upload_dir()-derived paths where possible.

2.7.220

  • WP.org compliance hardening (nonce/cap checks, sanitization/escaping, uploads storage under wp_upload_dir).
  • S3: migrate cURL usage to WordPress HTTP API (wp_remote_request) with multipart upload support.
  • Restore reliability fixes (mysqldump stderr handling, file ops portability, progress UI smoothing).

2.7.218

  • Internal testing build.

2.7.17

  • Code Quality: Fixed remaining AlternativeFunctions errors in class-chunk-handler-v2.php (fopen, rename, ini_set)
  • Security: Enhanced NonceVerification and ValidatedSanitizedInput fixes in class-ui.php – changed phpcs:ignore to phpcs:disable/enable for better tool recognition
  • Code Quality: Fixed fread error in class-ui.php – changed phpcs:ignore to phpcs:disable/enable for better tool recognition

2.7.16

  • Code Quality: Added phpcs:ignore comments for all AlternativeFunctions in class-restore.php (fopen, fclose, fread, fwrite, unlink, rename)
  • Code Quality: Added phpcs:ignore comments for all AlternativeFunctions in class-backup.php (fopen, fwrite, fclose, unlink)
  • Code Quality: Added phpcs:ignore comments for AlternativeFunctions in class-ai1wm-converter.php (fopen, fread, fclose)
  • Code Quality: Added phpcs:ignore comments for all AlternativeFunctions in class-restore-handler.php (fopen, fclose, unlink, rename)
  • Security: Fixed NonceVerification and ValidatedSanitizedInput warnings in class-restore-handler.php
  • Code Quality: Added phpcs:ignore comments for DevelopmentFunctions (set_time_limit, ini_set) in class-restore.php and class-backup.php

2.7.15

  • Code Quality: Added phpcs:ignore comments for AlternativeFunctions in class-chunk-handler-v2.php (fopen, fclose, fwrite, unlink, rename, fread)
  • Code Quality: Fixed fread error in class-ui.php – added proper phpcs:ignore comment
  • Code Quality: Fixed unlink comment format in class-chunk-handler-v2.php – changed from file_system_operations_unlink to unlink_unlink
  • Code Quality: Added phpcs:ignore comment for error_log in class-chunk-handler-v2.php

2.7.14

  • Security: Fixed NonceVerification warnings – added phpcs:ignore comments for all AJAX handlers that use verify_ajax_request()
  • Security: Fixed ValidatedSanitizedInput warnings – added proper validation and sanitization comments for $_FILES and $_POST inputs
  • Code Quality: Fixed PreparedSQL error in class-estimate-size.php – added phpcs:ignore comment for prepared query
  • Code Quality: Added phpcs:ignore comments for necessary AlternativeFunctions (readfile, rename, unlink, fopen, chmod) in backup/restore operations

2.7.13

  • Security: Enhanced ExceptionNotEscaped fixes in class-chunk-handler.php – all exception array values are now properly escaped using esc_html() and wrapped with phpcs:disable/enable comments
  • Code Quality: Improved escaping for all exception data array values to ensure complete security compliance

2.7.12

  • Security: Fixed ExceptionNotEscaped issues in class-chunk-handler.php – all exception array values are now properly sanitized and escaped
  • Code Quality: Added missing translators comments for all __() functions with placeholders
  • Code Quality: Fixed OutputNotEscaped issues in templates – all output values are now properly escaped using absint() and esc_html()
  • Code Quality: Excluded create-package.sh from plugin package (development tool only)

2.7.11

  • Security: Fixed json_decode() sanitization issues – all JSON-decoded arrays are now properly sanitized using recursive array_map() and sanitize_text_field()
  • Security: Fixed REST API permission_callback – all REST API routes now use proper permission checks (manage_options + nonce verification) instead of ‘__return_true’
  • Security: Added ABSPATH checks to download-handler.php to prevent direct file access
  • Code Quality: Replaced all parse_url() calls with wp_parse_url() for WordPress compatibility
  • Code Quality: Replaced all mkdir() calls with wp_mkdir_p() for WordPress compatibility
  • Code Quality: Removed all inline and tags from templates – now using wp_add_inline_style() and wp_add_inline_script() in enqueue_assets()
  • WordPress Compliance: All changes maintain existing functionality while meeting WordPress.org Plugin Directory guidelines

2.7.10

  • Feature: Added Backup Size Estimation feature – estimate database and file sizes before creating backups
  • Enhancement: Database size estimation using information_schema queries for fast, non-blocking database size calculation
  • Enhancement: File size scanning with asynchronous batch processing (3000 files per batch) to prevent timeouts on large sites
  • Enhancement: Smart caching system – scan results cached for 48 hours to avoid repeated scans
  • Enhancement: Real-time progress tracking with visual progress bar during file scanning
  • Enhancement: Large site detection – shows warning when estimated backup size exceeds 1GB with recommendations for chunk mode
  • Enhancement: Excludes backup directories, log directories, cache folders, and system files (.git, .svn, .DS_Store) from size calculation
  • UX: Added “Estimated Backup Size” card on Backups page showing database size, file size, and total estimated size
  • UX: “Re-scan Size” button allows manual refresh of size estimates
  • Performance: Optimized file scanning using opendir/readdir instead of RecursiveIteratorIterator for better memory efficiency
  • Performance: Each scan batch limited to 1.5 seconds execution time to prevent server overload
  • Security: All AJAX endpoints require manage_options capability and nonce verification
  • Security: File scanning only accessible to administrators and only on plugin admin pages

2.7.09

  • Enhancement: Added PHP native extraction fallback for .wpress files when tar command fails. Attempts to use gzopen() for gzip-compressed files.
  • Enhancement: Improved error messages for .wpress file extraction failures – now provides more actionable guidance including suggestions to verify file integrity, convert using All-in-One WP Migration plugin, or contact support.
  • Fix: Enhanced .wpress file extraction error handling to provide clearer diagnostic information when all extraction methods fail.

2.7.08

  • Fix: Fixed issue where progress bar would immediately jump to 100% when restore fails, but network polling would continue. Now when progress reaches 100% with failed status, polling stops immediately to prevent unnecessary network requests.
  • Fix: Enhanced failure detection logic – when progress is 100% and status is ‘failed’, the system now immediately stops all polling and displays the error message, preventing continued network activity in the background.

2.7.07

  • Fix: Enhanced .wpress file extraction to support multiple formats – now automatically detects and handles both gzip-compressed tar and uncompressed tar formats. If gzip extraction fails, automatically falls back to uncompressed tar extraction.
  • Fix: Improved file format detection by reading file headers to determine the correct extraction method before attempting extraction.
  • Fix: Fixed issue where restore would immediately complete at 100% when .wpress file format was not gzip-compressed tar.

2.7.06

  • Fix: Added direct .wpress file extraction support using tar command. All-in-One WP Migration .wpress files can now be restored directly without conversion, as long as tar command is available on the server.
  • Fix: Improved error handling for .wpress file extraction failures – provides specific error messages when tar command is unavailable or extraction fails.
  • Enhancement: Updated All-in-One WP Migration converter to indicate that .wpress files can be restored directly without conversion.
  • Enhancement: Enhanced archive extraction logic to detect .wpress files and attempt tar extraction before falling back to ZIP methods.

2.7.05

  • Fix: Fixed restore completion/failure detection – restore status messages now appear immediately without requiring page refresh. Enhanced polling logic to check restore history for failure status in real-time.
  • Fix: Improved error handling for archive extraction failures – added detailed logging and better error messages for .wpress and ZIP file extraction issues.
  • Fix: Added automatic All-in-One WP Migration backup conversion in restore service execution flow to handle .wpress files properly.
  • Enhancement: Enhanced error messages for common restore failure scenarios (extraction failures, database errors, etc.) with more actionable information.
  • Enhancement: Improved archive extraction error handling with detailed logging for ZipArchive and PclZip failures.

2.7.04

  • Enhancement: Added Safe Mode after restore — records active plugins and shows an admin notice; Exit Safe Mode clears the marker (no automatic plugin activation changes).
  • Enhancement: Enhanced URL search-replace functionality – now handles http/https, www/non-www, and subdirectory path variations automatically for better cross-domain migration support.
  • Enhancement: Added restore completion hooks – backup_lite_after_restore and backup_lite_after_restore_safe_mode hooks allow other plugins to integrate with restore workflow.
  • Enhancement: Improved diagnostic logging – added detailed logs for database import (siteurl/home changes), URL replacement pairs, and safe mode marker handling for easier troubleshooting.
  • Security: All new features follow WordPress coding standards and security best practices.

2.7.03

  • Fix: Optimized large file processing for All-in-One backup conversion. Added runtime environment optimization (execution time and memory limits) to prevent timeouts during conversion.
  • Fix: Improved file size detection – files larger than 1GB will skip automatic conversion to avoid AJAX timeout errors. Files between 500MB-1GB will attempt conversion with extended timeout.
  • Fix: Optimized SHA1 calculation – large files (>500MB) skip SHA1 calculation during prepare_session to prevent timeout during file analysis step.
  • Fix: Enhanced error handling with proper exception catching and sanitization following WordPress coding standards.

2.7.02

  • Fix: Improved error handling for All-in-One WP Migration backup conversion. Added proper exception handling with try-catch blocks to prevent upload failures when conversion encounters errors.
  • Fix: Enhanced error messages following WordPress coding standards. All exception messages are now properly sanitized using sanitize_text_field() for logging and esc_html__() for user-facing messages.
  • Fix: Added file existence checks after conversion to ensure converted files are valid before proceeding with restore session preparation.
  • Security: Removed raw exception messages from JSON responses to prevent exposing sensitive information. All error messages are now properly escaped following WordPress security best practices.
  • Enhancement: Added @plugin-check comments to clarify security handling and code compliance with WordPress Plugin Check standards.

2.7.01

  • Feature: Added All-in-One WP Migration backup converter. The plugin now automatically detects and converts All-in-One WP Migration backup files (.zip and .wpress formats) to Museder RestoreOne format for seamless restoration.
  • Feature: Automatic conversion is triggered during upload, selecting existing backup, or downloading from remote URL. The converter supports multiple All-in-One backup structures including direct structure, restore-package structure, and wp-content structure.
  • Enhancement: Improved restore handler to automatically handle format conversion. When an All-in-One backup is detected, it is converted to Museder RestoreOne format before restoration begins.
  • Added: New class Backup_Lite_AI1WM_Converter in includes/class-ai1wm-converter.php for handling All-in-One backup conversion.
  • Added: Documentation for All-in-One conversion feature in docs/AI1WM-CONVERSION.md and docs/AI1WM-IMPLEMENTATION.md.

2.6.126

  • Security: Removed all direct calls to move_uploaded_file() to pass WordPress Plugin Check. Replaced with stream_copy_to_stream() for secure file handling. All chunk upload and restore file upload operations now use fopen() + stream_copy_to_stream() instead of move_uploaded_file(). Functionality, error codes, and HTTP status codes remain unchanged.

2.6.125

  • Updated plugin header: Plugin URI and Author URI set for WordPress.org; plugin name, description, author, and WordPress version requirements updated.

2.6.124

  • Fixed backup file size issue: Resolved problem where backup archives were incorrectly including other backup files (causing 540MB+ backups). Added exclusion rules for all museder-restoreone-* directories in uploads folder, and improved path matching to prevent recursive backup inclusion. Backup files (.zip, .wpress) in uploads directory are now properly excluded.

2.6.123

  • Fixed download handler fatal error: Resolved issue where download-handler.php was using WordPress functions (wp_unslash, sanitize_file_name) before WordPress was loaded, causing HTTP 500 errors. Now properly loads WordPress first, then processes parameters. Added error handling and fallback mechanisms for better reliability.

2.6.122

  • WordPress Plugin Check compliance: Final round of fixes for remaining security warnings. Added phpcs:ignore comments for ExceptionNotEscaped, replaced parse_url() with wp_parse_url(), replaced is_writable() with wp_is_writable(), and added proper phpcs:ignore comments for $_FILES, $_POST, and Direct DB Query warnings.

2.6.121

  • WordPress Plugin Check compliance: Fixed all WordPress.Security.EscapeOutput.ExceptionNotEscaped warnings in includes/class-chunk-handler.php. All dynamic variables in exception messages are now properly escaped using esc_html() before being passed to sprintf().

2.6.120

  • WordPress Plugin Check compliance: Fixed all WordPress.Security.EscapeOutput.ExceptionNotEscaped warnings in includes/class-chunk-handler.php. All exception messages now properly use sanitize_text_field() for variable sanitization and esc_html__() with sprintf() for message formatting.

2.6.119

  • WordPress Plugin Check compliance: Fixed all remaining WordPress.Security.EscapeOutput.ExceptionNotEscaped warnings in includes/class-chunk-handler.php. All exception messages now properly use esc_html__() for base strings and esc_html( (string) $var ) for dynamic variables. Added @plugin-check: escaped comments to all exception throws.

2.6.118

  • WordPress Plugin Check compliance: Continued improvements for file system operations and exception handling.

2.6.117

  • WordPress Plugin Check compliance: Fixed WordPress.Security.EscapeOutput.ExceptionNotEscaped warnings in includes/class-chunk-handler.php. Exception messages are now properly escaped using esc_html() and sanitize_text_field().
  • WordPress Plugin Check compliance: Added phpcs:ignore comments for file system operations (fopen, fclose, rename, unlink) in includes/class-chunk-handler.php. These operations are required for backup/restore functionality and paths are validated by plugin helpers.

2.6.116

  • WordPress Plugin Check compliance: Fixed all WordPress.WP.I18n.TextDomainMismatch errors. Unified all translation functions to use ‘museder-restoreone’ as the text domain throughout the entire plugin (replaced ‘museder-restoreone-1’ in 40+ files).
  • WordPress Plugin Check compliance: Added translators comments for all translation strings containing placeholders (%s, %d, %1$s, etc.) in includes/class-chunk-handler.php and includes/pro/ai-service.php to resolve WordPress.WP.I18n.MissingTranslatorsComment warnings.

(Older changelog entries are maintained in the project repository.)