{"id":263980,"date":"2026-05-19T16:41:20","date_gmt":"2026-05-19T16:41:20","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/museder-restoreone\/"},"modified":"2026-05-27T05:19:19","modified_gmt":"2026-05-27T05:19:19","slug":"museder-restoreone","status":"publish","type":"plugin","link":"https:\/\/ro.wordpress.org\/plugins\/museder-restoreone\/","author":16780801,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.7.268","stable_tag":"2.7.268","tested":"7.0","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"Museder RestoreOne","header_author":"Adrian Lin","header_description":"Museder RestoreOne is a simple backup & restore plugin for WordPress.","assets_banners_color":"000000","last_updated":"2026-05-27 05:19:19","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/musederlabs.com\/restoreone-plugin\/","header_author_uri":"https:\/\/profiles.wordpress.org\/artherslin\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":132,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.7.263":{"tag":"2.7.263","author":"artherslin","date":"2026-05-20 18:12:30"},"2.7.264":{"tag":"2.7.264","author":"artherslin","date":"2026-05-24 08:58:43"},"2.7.265":{"tag":"2.7.265","author":"artherslin","date":"2026-05-27 05:19:19"},"2.7.268":{"tag":"2.7.268","author":"artherslin","date":"2026-05-27 05:19:19"}},"upgrade_notice":{"2.7.262":"<p>Fixes large-site backup jobs that could appear <strong>stuck near 95%<\/strong> after a failed post-close verification (PclZip repack conflicting with an open ZipArchive handle). Recommended if you run <strong>large full-site backups<\/strong> on production.<\/p>","2.7.261":"<p>No behavior change intended for production sites; this release mainly adds reviewer-oriented automation in the development repository (endpoint matrices, nginx+Apache smoke, ZIP install check, Multisite uninstall verification, mail\/PHPCS tooling) and readme\u2194admin UI mapping for manual checks.<\/p>","2.7.260":"<p>Stricter REST chunk session ids; safer chunk\/WPress paths; neutral <code>MusederRestoreOneAddon<\/code> global (Pro alias retained); dark-theme CSS selector fix; batched Multisite uninstall.<\/p>","2.7.259":"<p>Path-boundary hardening for helpers and download handlers; neutral add-on\/\u201cAI\u201d admin copy; <code>uninstall.php<\/code> for clean option\/cron removal without deleting your backups; functional-test helpers in the development repository.<\/p>","2.7.258":"<p>Tightens backup-path directory prefix checks; Multisite admin notice; expanded FAQ for chunk uploads, PclZip, cron\/mail, and large restores; optional functional-test tooling in the development repository.<\/p>","2.7.257":"<p>UI contrast fixes for dark theme on Settings and dashboard status badges; readme schedule wording aligned with optional schedules; legacy unused restore template removed.<\/p>","2.7.256":"<p>Further reduces review risk around path determination: segmented core admin include path resolution, a documented override filter for non-standard layouts, and FAQ guidance for custom language \/ mu-plugin paths.<\/p>","2.7.255":"<p>Addresses WordPress.org feedback on determining plugin\/content directories correctly: no <code>ABSPATH<\/code>-based core includes, no <code>WP_LANG_DIR<\/code> \/ <code>WPMU_PLUGIN_DIR<\/code> in backup scope; centralized core include helper with graceful failures. Recommended before resubmitting to the Plugin Directory.<\/p>","2.7.254":"<p>REST nonce handling aligned across Chunk, AI, and v2 restore; readme adds Privacy and Multisite statements; directory index sentinels. Recommended before WordPress.org resubmission.<\/p>","2.7.253":"<p>Loads PclZip from WordPress core (no bundled duplicate library); readme clarifies dev-only paths. Recommended before running full Plugin Check ruleset or resubmitting to WordPress.org.<\/p>","2.7.252":"<p>Plugin Check\u2013clean report download handling, regression test script escaping, and Docker exclude for <code>.DS_Store<\/code>. Recommended before resubmitting Plugin Check results.<\/p>","2.7.251":"<p>Plugin Check \/ escaping fix for report download <code>wp_die()<\/code> status handling. Recommended update before WordPress.org Plugin Check resubmission.<\/p>","2.7.250":"<p>Tighter NDJSON import table policy, safer AI recommendations hook, REST nonce checks aligned with AI routes. Recommended update before directory resubmission.<\/p>","2.7.249":"<p>Stricter admin AJAX nonce refresh, AI scan response without quota fields, safe mode copy aligned with actual behavior. Recommended before WordPress.org resubmission.<\/p>","2.7.248":"<p>Review-driven fixes: visible prefixed option keys for job locks, unlimited local schedules, backup labels for everyone, safer log download nonce order. Recommended before resubmitting to WordPress.org.<\/p>","2.7.247":"<p>Security and directory-review hardening: clearer nonce checks in AJAX handlers, safer backup download order, working admin report download handler. Recommended update before WordPress.org resubmission.<\/p>","2.7.246":"<p>UI polish: better dark-theme contrast on Restore Center and related cards; clearer restore progress label. Recommended update for admin readability.<\/p>","2.7.245":"<p>Readme and review polish: unified changelog, FAQ for local wp-cron loopback, code formatting and AI REST namespace alignment. Update recommended before WordPress.org resubmission.<\/p>","2.7.21":"<p>Security &amp; compliance: Hardened security with comprehensive nonce verification, input sanitization, and WordPress.org standards compliance. Fixed Restore History timestamp accuracy and restore success detection. Update recommended for all users.<\/p>","2.7.20":"<p>Critical fixes: Enhanced file path validation for restore operations, fixed Restore History timestamp accuracy, improved security with wp_delete_file(). Update recommended for all users.<\/p>","2.7.19":"<p>Bug fixes: Fixed restore file path errors and download white screen issue. Removed hardcoded timezone offsets - all time displays now respect WordPress timezone settings. Update recommended if experiencing restore or download issues.<\/p>","2.7.18":"<p>Timezone fix: All time displays now correctly use WordPress local timezone. Restore History, Dashboard, Logs, and Schedules pages now show accurate local times. Update recommended if timestamps are incorrect.<\/p>","2.7.17":"<p>Code quality and security improvements: Fixed remaining AlternativeFunctions errors, enhanced NonceVerification and ValidatedSanitizedInput fixes. Improved tool recognition for phpcs comments. Update recommended for better WordPress Plugin Check compliance.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3538187,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3538187,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3537809,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3537809,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["2.7.263","2.7.264","2.7.265","2.7.268"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3537809,"resolution":"1","location":"assets","locale":"","width":1742,"height":885},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3537809,"resolution":"2","location":"assets","locale":"","width":1685,"height":628},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3539416,"resolution":"3","location":"assets","locale":"","width":1772,"height":880},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3539416,"resolution":"4","location":"assets","locale":"","width":1759,"height":566},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3539416,"resolution":"5","location":"assets","locale":"","width":1756,"height":556},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3539416,"resolution":"6","location":"assets","locale":"","width":1772,"height":880}},"screenshots":{"1":"Dashboard with environment compatibility, recent backups, and schedule overview.","2":"Backups page showing available backups and the backup progress bar.","3":"Restore Center 3-step wizard: upload &amp; analyze, review options, execute restore.","4":"Schedules page listing upcoming backup jobs and quick schedule builder.","5":"Logs page with log file list and preview panel.","6":"Settings page with general options and system diagnostics."}},"plugin_section":[],"plugin_tags":[151,10718,4155,152,141017],"plugin_category":[59],"plugin_contributors":[263564],"plugin_business_model":[],"class_list":["post-263980","plugin","type-plugin","status-publish","hentry","plugin_tags-backup","plugin_tags-database-backup","plugin_tags-migration","plugin_tags-restore","plugin_tags-site-backup","plugin_category-utilities-and-tools","plugin_contributors-artherslin","plugin_committers-artherslin"],"banners":{"banner":"https:\/\/ps.w.org\/museder-restoreone\/assets\/banner-772x250.png?rev=3537809","banner_2x":"https:\/\/ps.w.org\/museder-restoreone\/assets\/banner-1544x500.png?rev=3537809","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/museder-restoreone\/assets\/icon-128x128.png?rev=3538187","icon_2x":"https:\/\/ps.w.org\/museder-restoreone\/assets\/icon-256x256.png?rev=3538187","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/museder-restoreone\/assets\/screenshot-1.png?rev=3537809","caption":"Dashboard with environment compatibility, recent backups, and schedule overview."},{"src":"https:\/\/ps.w.org\/museder-restoreone\/assets\/screenshot-2.png?rev=3537809","caption":"Backups page showing available backups and the backup progress bar."},{"src":"https:\/\/ps.w.org\/museder-restoreone\/assets\/screenshot-3.png?rev=3539416","caption":"Restore Center 3-step wizard: upload &amp; analyze, review options, execute restore."},{"src":"https:\/\/ps.w.org\/museder-restoreone\/assets\/screenshot-4.png?rev=3539416","caption":"Schedules page listing upcoming backup jobs and quick schedule builder."},{"src":"https:\/\/ps.w.org\/museder-restoreone\/assets\/screenshot-5.png?rev=3539416","caption":"Logs page with log file list and preview panel."},{"src":"https:\/\/ps.w.org\/museder-restoreone\/assets\/screenshot-6.png?rev=3539416","caption":"Settings page with general options and system diagnostics."}],"raw_content":"<!--section=description-->\n<p>Museder RestoreOne lets you create complete WordPress backups (database + <code>wp-content<\/code>) as a single archive, and restore them in a guided 3-step wizard.<\/p>\n\n<p>It is designed for shared hosting environments and uses WordPress APIs for database backup\/restore, with archive compression handled by <code>ZipArchive<\/code> or WordPress\u2019 bundled PclZip.<\/p>\n\n<p><strong>Key features<\/strong><\/p>\n\n<ul>\n<li><p>One-click full-site backup<br \/>\nExport the database, <code>meta.json<\/code>, and <code>wp-content\/<\/code> into a single archive you can download or restore later.<\/p><\/li>\n<li><p>Restore Center wizard<br \/>\nA clear 3-step flow: upload &amp; analyze \u2192 review summary &amp; options \u2192 start restore with real-time progress and logs.<\/p><\/li>\n<li><p>Chunked uploads with validation<br \/>\nBypass <code>upload_max_filesize<\/code> \/ <code>post_max_size<\/code> limits by uploading your archive in small chunks, with retries and integrity checks.<\/p><\/li>\n<li><p>Shared-hosting friendly<br \/>\nUses pure PHP + WordPress APIs for database backup\/restore, and falls back from <code>ZipArchive<\/code> to PclZip compression when needed.<\/p><\/li>\n<li><p>Schedules and logs<br \/>\nCreate one or more automatic backup schedules (or run backups manually), then inspect, download, or clean up structured backup and restore logs.<\/p><\/li>\n<li><p>Neo-glass admin UI<br \/>\nModern Dashboard, Backups, Restore, Schedules, Logs and Settings screens with clear calls-to-action, status messages, and responsive layout.<\/p><\/li>\n<\/ul>\n\n<p><strong>Multisite<\/strong><\/p>\n\n<p>This release is <strong>not formally tested on WordPress Multisite<\/strong>. For predictable results, use RestoreOne on <strong>standard single-site<\/strong> installs (one site per admin context). If you run a network, treat use as <strong>experimental<\/strong> until you have verified backups and restores on a staging clone.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin does not use external services.<\/p>\n\n<p>The <strong>only programmatic outbound HTTP<\/strong> the base plugin performs by default is an optional, short <strong>non-blocking<\/strong> request to <strong>your own site\u2019s<\/strong> <code>wp-cron.php<\/code> (same host \/ local loopback) to encourage scheduled tasks to run. No third-party API is called for backups or restores.<\/p>\n\n<p>All <strong>admin JavaScript and CSS<\/strong> for RestoreOne are loaded from files shipped under this plugin\u2019s <code>assets\/<\/code> directory (including vendored libraries under <code>assets\/vendor\/<\/code>). Optional add-ons, if you install them separately, may introduce their own network behavior; see each add-on\u2019s readme. See the FAQ for more on the local <code>wp-cron.php<\/code> nudge.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p><strong>What this plugin stores on your server<\/strong><\/p>\n\n<ul>\n<li><strong>Backups<\/strong> \u2014 Complete-site archives are written under your WordPress uploads area (typically <code>wp-content\/uploads\/museder-restoreone\/backups\/<\/code> or the path shown on the Backups screen). Each archive contains a database export (<code>database.ndjson<\/code>), <code>meta.json<\/code>, and a copy of <code>wp-content\/<\/code> from your site at backup time.  <\/li>\n<li><strong>Logs<\/strong> \u2014 Text logs for backup, restore, and related operations are stored under <code>wp-content\/uploads\/museder-restoreone\/logs\/<\/code> (see the <strong>Logs<\/strong> admin screen).  <\/li>\n<li><strong>Restore reports<\/strong> \u2014 When you generate a restore report, files are stored under <code>wp-content\/uploads\/museder-restoreone\/reports\/<\/code> (or the path configured for reports on your install).  <\/li>\n<li><strong>Schedules and settings<\/strong> \u2014 Options and scheduled events are stored in your WordPress database like other plugins.<\/li>\n<\/ul>\n\n<p><strong>Diagnostics<\/strong><\/p>\n\n<ul>\n<li><strong>Version \/ build heartbeat<\/strong> \u2014 After an upgrade, the plugin may write a one-line informational entry to the local <strong>Logs<\/strong> directory (same server, no remote host) noting the active plugin version and build id. This is for support troubleshooting only.<\/li>\n<\/ul>\n\n<p>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 <code>wp_upload_dir()<\/code> and path helpers derived from your install) rather than hard-coded internal constants, so custom <code>wp-content<\/code> or uploads layouts can be reflected correctly where your host allows.<\/p>\n\n<p><strong>Third parties<\/strong><\/p>\n\n<p>The free plugin does <strong>not<\/strong> upload your backup contents, database, or logs to third-party APIs or clouds. That statement matches <strong>External services<\/strong> above and the FAQ entries on external data and local <code>wp-cron<\/code> loopback.<\/p>\n\n<p>Optional <strong>add-ons<\/strong> (separate plugins or extensions, if you install and activate them) could send specific categories of data to remote storage or services only when you enable and configure those extensions; the base RestoreOne plugin does not do that on its own.<\/p>\n\n<p><strong>Retention and deletion<\/strong><\/p>\n\n<p>You can delete backup archives from the <strong>Backups<\/strong> screen, remove or download logs from <strong>Logs<\/strong>, and adjust retention-related options where provided.<\/p>\n\n<p><strong>Uninstall (<code>uninstall.php<\/code>)<\/strong> removes plugin-owned <strong>options<\/strong>, <strong>transients<\/strong> (including timeout rows), <strong>dynamic job-lock option rows<\/strong>, and <strong>scheduled cron hooks<\/strong> whose names start with <code>museder_restoreone_<\/code>. It does <strong>not<\/strong> 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.<\/p>\n\n<p>On <strong>Multisite<\/strong>, uninstall walks sites in <strong>batches<\/strong> (100 IDs per query) instead of loading the entire network at once. Very large networks should still use a <strong>maintenance window<\/strong> so uninstall is not interrupted by web-server timeouts.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>museder-restoreone<\/code> folder (or ZIP) to the <code>\/wp-content\/plugins\/<\/code> directory via FTP or through the \u201cUpload Plugin\u201d screen in your WordPress admin.<\/li>\n<li>Activate the plugin through the \u201cPlugins\u201d menu in WordPress.<\/li>\n<li>Go to the <strong>Museder RestoreOne<\/strong> menu in your admin sidebar.<\/li>\n<li>Open the <strong>Backups<\/strong> or <strong>Restore<\/strong> page and create your first backup.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20does%20the%20backup%20archive%20contain%3F\"><h3>What does the backup archive contain?<\/h3><\/dt>\n<dd><p>Each backup archive includes:<\/p>\n\n<ul>\n<li><code>database.ndjson<\/code> \u2014 a structured export of your WordPress database (plugin-owned format).  <\/li>\n<li><code>meta.json<\/code> \u2014 metadata about when and how the backup was created.  <\/li>\n<li><code>wp-content\/<\/code> \u2014 your themes, plugins, and uploads.<\/li>\n<\/ul>\n\n<p>Together, these files are enough to recreate your site on the same or another server.<\/p><\/dd>\n<dt id=\"does%20compatibility%20with%20third-party%20backup%20formats%20imply%20an%20official%20partnership%3F\"><h3>Does compatibility with third-party backup formats imply an official partnership?<\/h3><\/dt>\n<dd><p><strong>No.<\/strong> RestoreOne may document or implement <strong>technical compatibility<\/strong> with certain third-party archive or migration formats so you can move data between tools on <strong>your own server<\/strong>. That compatibility is <strong>not<\/strong> an endorsement, partnership, or affiliation with those projects unless explicitly stated elsewhere by the authors.<\/p><\/dd>\n<dt id=\"are%20there%20any%20file%20size%20limits%3F\"><h3>Are there any file size limits?<\/h3><\/dt>\n<dd><p>Yes. For safety and compatibility, <strong>single files larger than 2GB are skipped<\/strong> during backup. This means they will not be included in the backup ZIP and will not be restored.<\/p>\n\n<p>Sites larger than 2GB in total size can still be backed up and restored successfully as long as each individual file is smaller than 2GB.<\/p>\n\n<p>When files are skipped, the backup completion message shows the skip reasons and examples.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20mysqldump%20is%20not%20available%3F\"><h3>What happens if mysqldump is not available?<\/h3><\/dt>\n<dd><p>Museder RestoreOne does not require <code>mysqldump<\/code>. Database backup\/restore is implemented in pure PHP using WordPress database APIs.<\/p><\/dd>\n<dt id=\"what%20if%20ziparchive%20is%20not%20enabled%20on%20my%20server%3F\"><h3>What if ZipArchive is not enabled on my server?<\/h3><\/dt>\n<dd><p>If your server does not have the <code>ZipArchive<\/code> PHP extension, the plugin will automatically use WordPress\u2019 built-in PclZip library to create and extract archives.<\/p>\n\n<p>PclZip can be <strong>slower<\/strong> and more memory- or disk-sensitive on very large sites than <code>ZipArchive<\/code>. If a host blocks reading WordPress core\u2019s <code>wp-admin\/includes\/class-pclzip.php<\/code> (for example via <code>open_basedir<\/code>), backup or restore may fail with a clear error in <strong>Logs<\/strong> \u2014 use the <code>museder_restoreone_core_admin_include_path<\/code> filter if your layout is non-standard (see FAQ below).<\/p><\/dd>\n<dt id=\"how%20does%20chunked%20restore%20upload%20work%20over%20rest%3F\"><h3>How does chunked restore upload work over REST?<\/h3><\/dt>\n<dd><p>Large archive uploads use the plugin\u2019s <strong>authenticated<\/strong> REST API (<code>museder-restoreone\/v2<\/code>). Chunk bytes are streamed from the HTTP request body (<code>php:\/\/input<\/code>) <strong>only for that request<\/strong>, assembled into temporary files under your WordPress uploads area, and <strong>never forwarded<\/strong> to third-party URLs. Multipart uploads use PHP\u2019s normal uploaded-file handling instead. All chunk routes require <code>manage_options<\/code> and a valid REST nonce.<\/p><\/dd>\n<dt id=\"will%20scheduled%20backups%20and%20email%20always%20run%3F\"><h3>Will scheduled backups and email always run?<\/h3><\/dt>\n<dd><p>Scheduled backups depend on <strong>WordPress cron<\/strong> (or your host\u2019s <strong>system cron<\/strong> if <code>DISABLE_WP_CRON<\/code> is enabled). Email notifications depend on your server\u2019s <strong><code>wp_mail<\/code><\/strong> configuration (SMTP plugin, host mail relay, etc.). If cron or mail is blocked, use <strong>Settings \u2192 Send Test Email<\/strong>, check <strong>Logs<\/strong>, and configure host cron \/ mail as needed.<\/p><\/dd>\n<dt id=\"can%20i%20run%20a%20full%20restore%20%28execute%29%20on%20a%20very%20large%20archive%3F\"><h3>Can I run a full restore (execute) on a very large archive?<\/h3><\/dt>\n<dd><p>Very large restores may hit <strong>PHP time limits<\/strong>, <strong>web server timeouts<\/strong>, or <strong>disk space<\/strong> constraints on shared hosting. The Restore wizard supports <strong>validate<\/strong> and <strong>dry run<\/strong> steps so you can verify an archive before a full <strong>execute<\/strong>. For huge sites, prefer a <strong>staging clone<\/strong> or <strong>WP-CLI<\/strong>-driven restore where your host allows long-running PHP.<\/p><\/dd>\n<dt id=\"where%20are%20the%20logs%20stored%3F\"><h3>Where are the logs stored?<\/h3><\/dt>\n<dd><p>All logs are stored under:<\/p>\n\n<pre><code>wp-content\/uploads\/museder-restoreone\/logs\/\n<\/code><\/pre>\n\n<p>You can view or download the latest logs directly from the <strong>Logs<\/strong> page in the Museder RestoreOne admin menu.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20plugins%20during%20restore%3F\"><h3>What happens to plugins during restore?<\/h3><\/dt>\n<dd><p>Optional <strong>safe mode<\/strong> (chosen in the Restore screen) saves a snapshot of the active plugin list and sets an admin notice so you can verify the site before clearing the marker. RestoreOne does <strong>not<\/strong> automatically deactivate or reactivate other plugins; you manage plugins in WordPress as usual. <strong>Exit Safe Mode<\/strong> only clears the marker and the stored snapshot.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20send%20data%20to%20external%20services%3F\"><h3>Does this plugin send data to external services?<\/h3><\/dt>\n<dd><p>No. This plugin runs entirely on your server and does not send backup contents or site data to any external API or cloud service as part of the free base plugin.<\/p>\n\n<p>The <strong>Offline readiness \/ local rules<\/strong> scan on the Dashboard uses <strong>local heuristics<\/strong> only (no remote AI service is invoked by the shipped free build).<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20make%20http%20requests%20to%20my%20own%20site%3F\"><h3>Does the plugin make HTTP requests to my own site?<\/h3><\/dt>\n<dd><p>Sometimes. To help scheduled tasks run promptly, the plugin may send a short, non-blocking HTTP request to your own site's <code>wp-cron.php<\/code> (a local loopback). That stays on your server, does not transmit backup contents to third parties, and is a common WordPress pattern. If <code>DISABLE_WP_CRON<\/code> is enabled, your host may rely on system cron instead.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20expose%20my%20backup%20files%20publicly%3F\"><h3>Does this plugin expose my backup files publicly?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"does%20museder%20restoreone%20support%20wordpress%20multisite%3F\"><h3>Does Museder RestoreOne support WordPress Multisite?<\/h3><\/dt>\n<dd><p>Not as a formally supported configuration in this release. The plugin is built and QA\u2019d primarily for <strong>single-site<\/strong> WordPress. Multisite networks may behave differently across subsites, uploads paths, and roles; use on Multisite only after your own testing on a <strong>staging copy<\/strong> of the network.<\/p><\/dd>\n<dt id=\"can%20i%20use%20a%20custom%20languages%20directory%3F\"><h3>Can I use a custom languages directory?<\/h3><\/dt>\n<dd><p>Yes, advanced sites can override the detected languages directory with the <code>museder_restoreone_languages_dir<\/code> filter. Return an absolute path without a trailing slash, or return an empty string to skip language-directory handling.<\/p><\/dd>\n<dt id=\"can%20i%20use%20a%20custom%20mu-plugins%20directory%3F\"><h3>Can I use a custom mu-plugins directory?<\/h3><\/dt>\n<dd><p>Yes, advanced sites can override the detected must-use plugins directory with the <code>museder_restoreone_mu_plugins_dir<\/code> 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.<\/p><\/dd>\n<dt id=\"what%20if%20my%20wordpress%20core%20admin%20include%20files%20are%20in%20a%20non-standard%20location%3F\"><h3>What if my WordPress core admin include files are in a non-standard location?<\/h3><\/dt>\n<dd><p>Most sites do not need any changes. For unusual server layouts where core admin API files cannot be found automatically, developers can use the <code>museder_restoreone_core_admin_include_path<\/code> 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.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.7.268<\/h4>\n\n<ul>\n<li>Restore: make <code>zip_archive_has_wp_core()<\/code> public so preflight can detect full-site archives without a fatal error (BUG-SUN-001).<\/li>\n<li>Restore bootstrap: register WordPress stubs before <code>bootstrap_root()<\/code>; add <code>esc_attr()<\/code> stub; define <code>trailingslashit<\/code> before <code>ABSPATH<\/code> (BUG-SUN-003, BUG-SUN-004).<\/li>\n<\/ul>\n\n<h4>2.7.267<\/h4>\n\n<ul>\n<li>Restore (Approach B): <strong>site profile<\/strong> detection (existing \/ fresh \/ no core), preflight blocks, and Step 2 <strong>restore order<\/strong>, <strong>scope<\/strong>, <strong>wp-config mode<\/strong> (backup \/ keep \/ merge), and <strong>pause other plugins<\/strong> (default on).<\/li>\n<li>Restore: <strong>populated sites<\/strong> require a pre-restore snapshot; default order <strong>database then files<\/strong> (user can switch to files-first).<\/li>\n<li>Restore: <strong>fresh \/ empty<\/strong> profiles default to <strong>files then database<\/strong> with UI notices (including DB overwrite on fresh installs).<\/li>\n<li>Restore: <strong>empty docroot<\/strong> full-site restores can use <strong><code>museder-restoreone-restore-bootstrap.php<\/code><\/strong> (copy to site root) for loopback file slices before WordPress core exists.<\/li>\n<li>Restore: ZIP restores use a <strong>two-phase file stage<\/strong> (wp-content, then WordPress core and site root files when present in the archive).<\/li>\n<li>Restore: includes <strong>2.7.265<\/strong> mid-restore plugin isolation, restore token, and safe-plugin reapply after restore.<\/li>\n<li>Restore: writes a fallback <strong>.htaccess<\/strong> when missing after permalink flush (Apache).<\/li>\n<\/ul>\n\n<h4>2.7.262<\/h4>\n\n<ul>\n<li>Backup reliability: when <strong>PclZip<\/strong> compatibility repack is active, the async job runner <strong>no longer keeps a long-lived <code>ZipArchive<\/code> handle<\/strong> on the same <code>.zip<\/code> file (PclZip and ZipArchive were both mutating the archive, making <code>close()<\/code> extremely slow on large sites and risking central-directory corruption).<\/li>\n<li>Backup verification: post-close archive checks now resolve ZIP entry names more robustly (<code>zip_archive_has_entry()<\/code> \u2014 forward slashes, optional <code>.\/<\/code> prefix, and <code>ZipArchive::FL_NOCASE<\/code> when available) so <strong>false \u201cverification failed\u201d<\/strong> results are less likely to trigger a full repack.<\/li>\n<\/ul>\n\n<h4>2.7.261<\/h4>\n\n<ul>\n<li>Developer \/ review automation (not shipped in the WordPress.org ZIP): WP-CLI matrices for <strong>all registered <code>wp_ajax_museder_restoreone_*<\/code> actions<\/strong>, <strong>REST routes<\/strong> under <code>museder-restoreone\/v1<\/code> + <code>v2<\/code>, and <strong><code>admin_post_museder_restoreone_*<\/code> downloads<\/strong> (capability + nonce \/ referer expectations); nginx <strong>reverse-proxy<\/strong> smoke in front of the stock Apache WordPress image; <strong>ZIP clean install<\/strong> + Plugin Check; <strong>Multisite<\/strong> 2-site stack + network uninstall option\/cron verification; <strong>mail pipeline<\/strong> smoke (<code>wp_mail<\/code> \/ <code>Email_Handler::test_email<\/code> reaches PHPMailer); <strong>PHPCS<\/strong> tooling (<code>phpcs.xml.dist<\/code> + <code>tools\/phpcs<\/code> Composer kit) with <code>run-phpcs-summary.sh<\/code>.<\/li>\n<li>Documentation: <code>docs\/2026-05-06__v2.7.261__readme-key-features__admin-ui-map.md<\/code> maps readme <strong>Key features<\/strong> to admin <code>page=<\/code> slugs for manual review.<\/li>\n<li>Maintenance: restore job AJAX handlers that \u201cclean\u201d output now use <strong><code>ob_clean()<\/code><\/strong> instead of <strong><code>ob_end_clean()<\/code><\/strong> so they flush stray bytes <strong>without<\/strong> popping the whole output-buffer stack (same idea for REST chunk <code>prepare_request_environment()<\/code>). Behavior for real browsers is unchanged; this avoids breaking nested buffers in automated tests and CLI.<\/li>\n<\/ul>\n\n<h4>2.7.260<\/h4>\n\n<ul>\n<li>Security: REST chunk v2 <strong><code>upload_id<\/code><\/strong> limited to <strong>UUID v4<\/strong> (same format as <code>wp_generate_uuid4()<\/code>); <code>status<\/code> \/ <code>chunk<\/code> \/ <code>finalize<\/code> \/ <code>abort<\/code> and temp directory helpers reject garbage ids; cleanup skips non-UUID folders under <code>v2-uploads<\/code>.<\/li>\n<li>Security: <strong><code>museder_restoreone_get_chunk_path()<\/code><\/strong> second argument now uses <strong><code>museder_restoreone_safe_path_join()<\/code><\/strong> (no traversal via relative fragments).<\/li>\n<li>Security: <strong>WPress<\/strong> <code>safe_join()<\/code> final check uses <strong>directory-prefix boundary<\/strong> (aligned with other path helpers).<\/li>\n<li>Review UX: admin script globals <strong><code>MusederRestoreOneAddon<\/code><\/strong> (primary) with <strong><code>MusederRestoreOnePro<\/code><\/strong> kept as an alias for backward compatibility; strings unchanged.<\/li>\n<li>UI: fixed <strong><code>[data-bl-theme=\"dark\"]<\/code><\/strong> selectors in <code>admin-style.css<\/code> that were escaped incorrectly so dark-theme list\/table header styles apply.<\/li>\n<li>Multisite: <strong><code>uninstall.php<\/code><\/strong> processes sites in <strong>batches<\/strong> to reduce memory spikes on large networks (readme Privacy note updated).<\/li>\n<li>Developer: <code>docs\/2026-05-06__v2.7.260__\u7aef\u9ede\u77e9\u9663__REST-AJAX-AdminPost.md<\/code> \u2014 hook \u2192 capability \u2192 nonce \/ <code>permission_callback<\/code> matrix for reviewers.<\/li>\n<\/ul>\n\n<h4>2.7.259<\/h4>\n\n<ul>\n<li>Security: <code>museder_restoreone_safe_path_join()<\/code> now uses a <strong>trailing-slash directory prefix<\/strong> check; log path resolution and admin download handlers (<code>logs<\/code>, <code>reports<\/code>, restore-job <code>database.sql<\/code>) validate <strong><code>realpath()<\/code> + prefix<\/strong> to avoid ambiguous <code>strpos<\/code> matches.<\/li>\n<li>Review UX: neutral copy for optional <strong>add-on<\/strong> placeholders (<code>MusederRestoreOnePro<\/code> \/ admin UI modal); Dashboard \u201cAI\u201d strings describe <strong>local \/ offline<\/strong> scan behavior only.<\/li>\n<li>Documentation: readme <strong>External services<\/strong> (loopback <code>wp-cron.php<\/code>, local <code>assets\/vendor<\/code> JS\/CSS), <strong>Privacy \/ uninstall<\/strong> aligned with <code>uninstall.php<\/code>, FAQ on <strong>third-party format compatibility<\/strong> (no endorsement).<\/li>\n<li>Maintenance: added root <strong><code>uninstall.php<\/code><\/strong> (options, transients, job-lock rows, <code>museder_restoreone_*<\/code> crons only \u2014 <strong>no<\/strong> backup\/log\/report file deletion). <code>create-package.sh<\/code> ships <code>uninstall.php<\/code> in the ZIP.<\/li>\n<li>Developer tooling: <code>tools\/functional-test\/<\/code> adds REST permission smoke, <code>safe_path_join<\/code> traversal checks, external-URL scan script, and uninstall manifest verification (still <strong>not<\/strong> included in the WordPress.org ZIP).<\/li>\n<li>Vendor: restored <strong><code>assets\/vendor\/chart.4.5.1.min.js<\/code><\/strong> alongside <code>chart.4.5.1.js<\/code>; expanded <code>assets\/vendor\/README.txt<\/code> (versions, licenses, sources).<\/li>\n<\/ul>\n\n<h4>2.7.258<\/h4>\n\n<ul>\n<li>Security: <code>museder_restoreone_get_backup_path()<\/code> now compares backup directory roots with a <strong>trailing-slash boundary<\/strong> after <code>realpath()<\/code> normalization, preventing ambiguous prefix matches between similarly named directories.<\/li>\n<li>Multisite: when WordPress Multisite is enabled, RestoreOne admin screens show a <strong>non-blocking<\/strong> notice that Multisite is <strong>experimental<\/strong> (readme stance unchanged).<\/li>\n<li>Documentation: FAQ entries for <strong>PclZip performance<\/strong>, <strong>REST chunk \/ <code>php:\/\/input<\/code><\/strong>, <strong>cron and mail dependencies<\/strong>, and <strong>large-archive restore limits<\/strong>; Privacy notes optional local <strong>build\/version log<\/strong> heartbeat after upgrades.<\/li>\n<li>Developer tooling: added <code>tools\/functional-test\/<\/code> 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.<\/li>\n<li>Email: test email body no longer uses emoji (broader mail client compatibility).<\/li>\n<\/ul>\n\n<h4>2.7.257<\/h4>\n\n<ul>\n<li>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).<\/li>\n<li>Documentation: Readme feature line for schedules now matches optional scheduling (no longer implies a minimum number of schedules).<\/li>\n<li>Maintenance: Removed unused legacy template <code>templates\/restore-page.php<\/code> (Restore admin screen uses <code>page-restore.php<\/code> only) to avoid mixed-language placeholder strings in the distributed tree.<\/li>\n<\/ul>\n\n<h4>2.7.256<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>Developer filters: added <code>museder_restoreone_core_admin_include_path<\/code> for non-standard WordPress directory layouts; invalid or unreadable filtered paths are ignored.<\/li>\n<li>Documentation: FAQ now explains custom languages, mu-plugins, and core admin include path filters for advanced non-standard installs.<\/li>\n<\/ul>\n\n<h4>2.7.255<\/h4>\n\n<ul>\n<li>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 (<code>wp_upload_dir()<\/code>, plugin path helpers) and graceful fallbacks.<\/li>\n<li>Backup scope: language and mu-plugin directory prefixes are now resolved through plugin helpers and filters (<code>museder_restoreone_languages_dir<\/code>, <code>museder_restoreone_mu_plugins_dir<\/code>) instead of <code>WP_LANG_DIR<\/code> \/ <code>WPMU_PLUGIN_DIR<\/code>.<\/li>\n<li>Restore\/upload helpers: core admin include loading is centralized in <code>museder_restoreone_get_core_admin_include_path()<\/code> and avoids <code>ABSPATH<\/code> path concatenation; missing core helpers fail gracefully instead of fataling.<\/li>\n<\/ul>\n\n<h4>2.7.254<\/h4>\n\n<ul>\n<li>REST: Chunk upload (<code>includes\/class-chunk-handler-v2.php<\/code>) <code>permission_check<\/code> now uses the same two-step REST nonce pattern as v2 restore (<code>check_permissions<\/code>): <code>X-WP-Nonce<\/code> then <code>rest_nonce<\/code> parameter, empty token vs <code>wp_verify_nonce<\/code> as separate <code>WP_Error<\/code> branches; HTTP <strong>401<\/strong> for invalid\/missing nonce and shared <code>museder_restoreone_invalid_nonce<\/code> \/ <code>museder_restoreone_forbidden<\/code> codes with v2 restore.<\/li>\n<li>REST: Free AI REST <code>permission_check<\/code> nonce failures now return <strong>401<\/strong> with <code>museder_restoreone_invalid_nonce<\/code> (aligned with v2 restore; same user-facing message).<\/li>\n<li>Readme: added <strong>== Privacy ==<\/strong> (data locations, third parties, optional add-ons, retention) and explicit <strong>Multisite<\/strong> stance in Description + FAQ.<\/li>\n<li>Security hygiene: added <code>index.php<\/code> sentinels under <code>includes\/<\/code>, <code>includes\/wpress\/<\/code>, <code>templates\/<\/code>, <code>assets\/<\/code> (+ <code>assets\/css\/<\/code>, <code>assets\/js\/<\/code>), and <code>languages\/<\/code> to avoid directory listing on misconfigured hosts.<\/li>\n<\/ul>\n\n<h4>2.7.253<\/h4>\n\n<ul>\n<li>Compliance \/ Plugin Check: PclZip fallback now loads WordPress core\u2019s PclZip file instead of shipping a duplicate <code>includes\/vendor\/pclzip<\/code> copy, so the broader <code>plugin-check.ruleset.xml<\/code> scan is not dominated by third-party PHPCS violations in bundled library code.<\/li>\n<li>Documentation: Clarifies that changelog lines mentioning <code>tests\/<\/code> or <code>tools\/docker\/<\/code> refer to the public development repository only; those paths are not part of the distributed plugin ZIP from WordPress.org.<\/li>\n<\/ul>\n\n<h4>2.7.252<\/h4>\n\n<ul>\n<li>Developer \/ WordPress Plugin Check: Report download <code>wp_die()<\/code> branches use per-status literal <code>response<\/code> codes with inline <code>esc_html()<\/code> \/ <code>esc_html__()<\/code> so <code>OutputNotEscaped<\/code> passes under Plugin Check.<\/li>\n<li>Developer: <code>tests\/php-regression\/final_review_248_regression.php<\/code> uses <code>esc_html()<\/code> on CLI output and wraps checks in <code>museder_restoreone_final_review_248_regression_run()<\/code> to satisfy prefix \/ escaping static analysis.<\/li>\n<li>Docker sync (<code>tools\/docker\/setup.sh<\/code>): exclude root <code>.DS_Store<\/code> from the plugin tarball so Plugin Check does not flag hidden files in <code>wp-content\/plugins<\/code>.<\/li>\n<\/ul>\n\n<h4>2.7.251<\/h4>\n\n<ul>\n<li>WordPress Plugin Check: Report download error path now passes HTTP status to <code>wp_die()<\/code> via the <code>response<\/code> args array (avoids <code>OutputNotEscaped<\/code> on a dynamic third-argument integer).<\/li>\n<\/ul>\n\n<h4>2.7.250<\/h4>\n\n<ul>\n<li>Security: NDJSON database import now applies the same table prefix allow-list as the SQL restore path before <code>DROP TABLE<\/code> \/ <code>replace()<\/code>; disallowed names are skipped and logged.<\/li>\n<li>Stability: <code>get_ai_recommendations()<\/code> checks <code>class_exists( 'Museder_Restoreone_AI_Service' )<\/code> before calling it (avoids fatal if an add-on filter is misconfigured).<\/li>\n<li>WordPress.org review: AI schedule recommendation errors use neutral codes\/messages (<code>addon_not_active<\/code>, <code>addon_service_missing<\/code>) instead of <code>pro_required<\/code>.<\/li>\n<li>REST (v2 restore): <code>check_permissions<\/code> validates <code>X-WP-Nonce<\/code> \/ <code>_wpnonce<\/code> in two steps (empty check, then <code>wp_verify_nonce<\/code>), matching the AI REST controller pattern.<\/li>\n<\/ul>\n\n<h4>2.7.249<\/h4>\n\n<ul>\n<li>WordPress.org strict review: AJAX <code>museder_restoreone_refresh_nonce<\/code> now requires a valid existing nonce before issuing a new one; admin JS sends the current nonce on refresh.<\/li>\n<li>AI (free): removed daily scan quota \/ <code>remaining<\/code> \/ <code>dailyScans<\/code> from the hosted build (local preview only; no trialware-style limits in API responses).<\/li>\n<li>Safe mode: readme, Restore\/Dashboard notices, restore options help text, and admin toasts now match implementation \u2014 snapshot + marker only; <strong>Exit Safe Mode<\/strong> clears the marker without claiming automatic plugin activation changes.<\/li>\n<\/ul>\n\n<h4>2.7.248<\/h4>\n\n<ul>\n<li>WordPress.org review: <code>add_option()<\/code> job locks now use an explicitly prefixed <code>$option_key<\/code> built from <code>OPTION_LOCK_PREFIX<\/code> at the call site (addresses static analysis \/ human review feedback on dynamic option names).<\/li>\n<li>WordPress.org guidelines: removed the free-tier limit of a single backup schedule; multiple local schedules are allowed for all users.<\/li>\n<li>Schedules: cron pattern, exclude paths, and retention policy fields are saved for all installs (local features; not gated on a separate add-on).<\/li>\n<li>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 <code>class_exists()<\/code> guard on cloud upload.<\/li>\n<li>Admin log download: <code>check_admin_referer()<\/code> runs immediately after resolving the log basename and before reading the file from disk.<\/li>\n<\/ul>\n\n<h4>2.7.247<\/h4>\n\n<ul>\n<li>Security &amp; WordPress.org review: Added explicit <code>check_ajax_referer()<\/code> calls in admin AJAX handlers (UI, restore, logs, settings, email) so tooling and reviewers can see nonce verification in each handler.<\/li>\n<li>Backup download (<code>admin-post<\/code>): For nonce-based links, <code>check_admin_referer()<\/code> now runs before reading <code>$_GET['file']<\/code>; signed-token downloads unchanged. Clearer error when the filename is missing after a valid nonce.<\/li>\n<li>Report download: Replaced missing Pro controller with <code>Museder_Restoreone_Restore_Report::download()<\/code> plus <code>check_admin_referer( 'museder_restoreone_download_report' )<\/code>, path confinement under the reports directory, and safe streaming headers.<\/li>\n<li>Backup jobs: Clarified comments for dynamic <code>add_option()<\/code> lock keys (no invalid PHPCS ignore).<\/li>\n<\/ul>\n\n<h4>2.7.246<\/h4>\n\n<ul>\n<li>Admin UI: improved text contrast when using dark appearance (<code>data-bl-theme=\"dark\"<\/code>) \u2014 Restore Center step cards, glass cards, and status colors align with theme tokens (<code>--text-dark<\/code>, <code>--surface<\/code>, <code>--glass-*<\/code>).<\/li>\n<li>Restore Center: progress track uses a deeper neutral background; percentage label uses a subtle text shadow so it stays readable at low fill levels.<\/li>\n<li>Safe mode notices (Restore + Dashboard) use <code>var(--text-muted)<\/code> so body copy follows the active theme.<\/li>\n<li>Legacy restore wizard (restore.css): completed-step label uses a brighter green in dark mode.<\/li>\n<\/ul>\n\n<h4>2.7.245<\/h4>\n\n<ul>\n<li>WordPress.org review follow-up: readme \u2014 single Changelog section (removed duplicate header); FAQ documents local <code>wp-cron.php<\/code> loopback requests. Code \u2014 <code>trigger_restore_job()<\/code> formatting in class-restore-handler.php; AI REST API namespace aligned to <code>museder-restoreone\/v1<\/code> for consistency with the plugin slug.<\/li>\n<\/ul>\n\n<h4>2.7.244<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.7.243<\/h4>\n\n<ul>\n<li>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).<\/li>\n<\/ul>\n\n<h4>2.7.242<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.7.223<\/h4>\n\n<ul>\n<li>Compliance: Reworked deprecated download handler to avoid bootstrapping WordPress and route downloads via admin-post.php.<\/li>\n<li>Compliance: Documented external services with plain Terms\/Privacy URLs for review tooling.<\/li>\n<li>Security: Added explicit nonce checks in key AJAX handlers for clearer automated detection.<\/li>\n<li>Security: Hardened restore SQL import with a conservative allow\/deny statement strategy.<\/li>\n<li>Compatibility: Reduced reliance on hard-coded WP_* directory constants by using wp_upload_dir()-derived paths where possible.<\/li>\n<\/ul>\n\n<h4>2.7.220<\/h4>\n\n<ul>\n<li>WP.org compliance hardening (nonce\/cap checks, sanitization\/escaping, uploads storage under wp_upload_dir).<\/li>\n<li>S3: migrate cURL usage to WordPress HTTP API (wp_remote_request) with multipart upload support.<\/li>\n<li>Restore reliability fixes (mysqldump stderr handling, file ops portability, progress UI smoothing).<\/li>\n<\/ul>\n\n<h4>2.7.218<\/h4>\n\n<ul>\n<li>Internal testing build.<\/li>\n<\/ul>\n\n<h4>2.7.17<\/h4>\n\n<ul>\n<li>Code Quality: Fixed remaining AlternativeFunctions errors in class-chunk-handler-v2.php (fopen, rename, ini_set)<\/li>\n<li>Security: Enhanced NonceVerification and ValidatedSanitizedInput fixes in class-ui.php - changed phpcs:ignore to phpcs:disable\/enable for better tool recognition<\/li>\n<li>Code Quality: Fixed fread error in class-ui.php - changed phpcs:ignore to phpcs:disable\/enable for better tool recognition<\/li>\n<\/ul>\n\n<h4>2.7.16<\/h4>\n\n<ul>\n<li>Code Quality: Added phpcs:ignore comments for all AlternativeFunctions in class-restore.php (fopen, fclose, fread, fwrite, unlink, rename)<\/li>\n<li>Code Quality: Added phpcs:ignore comments for all AlternativeFunctions in class-backup.php (fopen, fwrite, fclose, unlink)<\/li>\n<li>Code Quality: Added phpcs:ignore comments for AlternativeFunctions in class-ai1wm-converter.php (fopen, fread, fclose)<\/li>\n<li>Code Quality: Added phpcs:ignore comments for all AlternativeFunctions in class-restore-handler.php (fopen, fclose, unlink, rename)<\/li>\n<li>Security: Fixed NonceVerification and ValidatedSanitizedInput warnings in class-restore-handler.php<\/li>\n<li>Code Quality: Added phpcs:ignore comments for DevelopmentFunctions (set_time_limit, ini_set) in class-restore.php and class-backup.php<\/li>\n<\/ul>\n\n<h4>2.7.15<\/h4>\n\n<ul>\n<li>Code Quality: Added phpcs:ignore comments for AlternativeFunctions in class-chunk-handler-v2.php (fopen, fclose, fwrite, unlink, rename, fread)<\/li>\n<li>Code Quality: Fixed fread error in class-ui.php - added proper phpcs:ignore comment<\/li>\n<li>Code Quality: Fixed unlink comment format in class-chunk-handler-v2.php - changed from file_system_operations_unlink to unlink_unlink<\/li>\n<li>Code Quality: Added phpcs:ignore comment for error_log in class-chunk-handler-v2.php<\/li>\n<\/ul>\n\n<h4>2.7.14<\/h4>\n\n<ul>\n<li>Security: Fixed NonceVerification warnings - added phpcs:ignore comments for all AJAX handlers that use verify_ajax_request()<\/li>\n<li>Security: Fixed ValidatedSanitizedInput warnings - added proper validation and sanitization comments for $_FILES and $_POST inputs<\/li>\n<li>Code Quality: Fixed PreparedSQL error in class-estimate-size.php - added phpcs:ignore comment for prepared query<\/li>\n<li>Code Quality: Added phpcs:ignore comments for necessary AlternativeFunctions (readfile, rename, unlink, fopen, chmod) in backup\/restore operations<\/li>\n<\/ul>\n\n<h4>2.7.13<\/h4>\n\n<ul>\n<li>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<\/li>\n<li>Code Quality: Improved escaping for all exception data array values to ensure complete security compliance<\/li>\n<\/ul>\n\n<h4>2.7.12<\/h4>\n\n<ul>\n<li>Security: Fixed ExceptionNotEscaped issues in class-chunk-handler.php - all exception array values are now properly sanitized and escaped<\/li>\n<li>Code Quality: Added missing translators comments for all __() functions with placeholders<\/li>\n<li>Code Quality: Fixed OutputNotEscaped issues in templates - all output values are now properly escaped using absint() and esc_html()<\/li>\n<li>Code Quality: Excluded create-package.sh from plugin package (development tool only)<\/li>\n<\/ul>\n\n<h4>2.7.11<\/h4>\n\n<ul>\n<li>Security: Fixed json_decode() sanitization issues - all JSON-decoded arrays are now properly sanitized using recursive array_map() and sanitize_text_field()<\/li>\n<li>Security: Fixed REST API permission_callback - all REST API routes now use proper permission checks (manage_options + nonce verification) instead of '__return_true'<\/li>\n<li>Security: Added ABSPATH checks to download-handler.php to prevent direct file access<\/li>\n<li>Code Quality: Replaced all parse_url() calls with wp_parse_url() for WordPress compatibility<\/li>\n<li>Code Quality: Replaced all mkdir() calls with wp_mkdir_p() for WordPress compatibility<\/li>\n<li>Code Quality: Removed all inline  and  tags from templates - now using wp_add_inline_style() and wp_add_inline_script() in enqueue_assets()<\/li>\n<li>WordPress Compliance: All changes maintain existing functionality while meeting WordPress.org Plugin Directory guidelines<\/li>\n<\/ul>\n\n<h4>2.7.10<\/h4>\n\n<ul>\n<li>Feature: Added Backup Size Estimation feature - estimate database and file sizes before creating backups<\/li>\n<li>Enhancement: Database size estimation using information_schema queries for fast, non-blocking database size calculation<\/li>\n<li>Enhancement: File size scanning with asynchronous batch processing (3000 files per batch) to prevent timeouts on large sites<\/li>\n<li>Enhancement: Smart caching system - scan results cached for 48 hours to avoid repeated scans<\/li>\n<li>Enhancement: Real-time progress tracking with visual progress bar during file scanning<\/li>\n<li>Enhancement: Large site detection - shows warning when estimated backup size exceeds 1GB with recommendations for chunk mode<\/li>\n<li>Enhancement: Excludes backup directories, log directories, cache folders, and system files (.git, .svn, .DS_Store) from size calculation<\/li>\n<li>UX: Added \"Estimated Backup Size\" card on Backups page showing database size, file size, and total estimated size<\/li>\n<li>UX: \"Re-scan Size\" button allows manual refresh of size estimates<\/li>\n<li>Performance: Optimized file scanning using opendir\/readdir instead of RecursiveIteratorIterator for better memory efficiency<\/li>\n<li>Performance: Each scan batch limited to 1.5 seconds execution time to prevent server overload<\/li>\n<li>Security: All AJAX endpoints require manage_options capability and nonce verification<\/li>\n<li>Security: File scanning only accessible to administrators and only on plugin admin pages<\/li>\n<\/ul>\n\n<h4>2.7.09<\/h4>\n\n<ul>\n<li>Enhancement: Added PHP native extraction fallback for .wpress files when tar command fails. Attempts to use gzopen() for gzip-compressed files.<\/li>\n<li>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.<\/li>\n<li>Fix: Enhanced .wpress file extraction error handling to provide clearer diagnostic information when all extraction methods fail.<\/li>\n<\/ul>\n\n<h4>2.7.08<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.7.07<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>Fix: Improved file format detection by reading file headers to determine the correct extraction method before attempting extraction.<\/li>\n<li>Fix: Fixed issue where restore would immediately complete at 100% when .wpress file format was not gzip-compressed tar.<\/li>\n<\/ul>\n\n<h4>2.7.06<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>Fix: Improved error handling for .wpress file extraction failures - provides specific error messages when tar command is unavailable or extraction fails.<\/li>\n<li>Enhancement: Updated All-in-One WP Migration converter to indicate that .wpress files can be restored directly without conversion.<\/li>\n<li>Enhancement: Enhanced archive extraction logic to detect .wpress files and attempt tar extraction before falling back to ZIP methods.<\/li>\n<\/ul>\n\n<h4>2.7.05<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>Fix: Improved error handling for archive extraction failures - added detailed logging and better error messages for .wpress and ZIP file extraction issues.<\/li>\n<li>Fix: Added automatic All-in-One WP Migration backup conversion in restore service execution flow to handle .wpress files properly.<\/li>\n<li>Enhancement: Enhanced error messages for common restore failure scenarios (extraction failures, database errors, etc.) with more actionable information.<\/li>\n<li>Enhancement: Improved archive extraction error handling with detailed logging for ZipArchive and PclZip failures.<\/li>\n<\/ul>\n\n<h4>2.7.04<\/h4>\n\n<ul>\n<li>Enhancement: Added Safe Mode after restore \u2014 records active plugins and shows an admin notice; Exit Safe Mode clears the marker (no automatic plugin activation changes).<\/li>\n<li>Enhancement: Enhanced URL search-replace functionality - now handles http\/https, www\/non-www, and subdirectory path variations automatically for better cross-domain migration support.<\/li>\n<li>Enhancement: Added restore completion hooks - <code>backup_lite_after_restore<\/code> and <code>backup_lite_after_restore_safe_mode<\/code> hooks allow other plugins to integrate with restore workflow.<\/li>\n<li>Enhancement: Improved diagnostic logging - added detailed logs for database import (siteurl\/home changes), URL replacement pairs, and safe mode marker handling for easier troubleshooting.<\/li>\n<li>Security: All new features follow WordPress coding standards and security best practices.<\/li>\n<\/ul>\n\n<h4>2.7.03<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>Fix: Optimized SHA1 calculation - large files (&gt;500MB) skip SHA1 calculation during prepare_session to prevent timeout during file analysis step.<\/li>\n<li>Fix: Enhanced error handling with proper exception catching and sanitization following WordPress coding standards.<\/li>\n<\/ul>\n\n<h4>2.7.02<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>Fix: Added file existence checks after conversion to ensure converted files are valid before proceeding with restore session preparation.<\/li>\n<li>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.<\/li>\n<li>Enhancement: Added @plugin-check comments to clarify security handling and code compliance with WordPress Plugin Check standards.<\/li>\n<\/ul>\n\n<h4>2.7.01<\/h4>\n\n<ul>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>Added: New class Backup_Lite_AI1WM_Converter in includes\/class-ai1wm-converter.php for handling All-in-One backup conversion.<\/li>\n<li>Added: Documentation for All-in-One conversion feature in docs\/AI1WM-CONVERSION.md and docs\/AI1WM-IMPLEMENTATION.md.<\/li>\n<\/ul>\n\n<h4>2.6.126<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.125<\/h4>\n\n<ul>\n<li>Updated plugin header: Plugin URI and Author URI set for WordPress.org; plugin name, description, author, and WordPress version requirements updated.<\/li>\n<\/ul>\n\n<h4>2.6.124<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.123<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.122<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.121<\/h4>\n\n<ul>\n<li>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().<\/li>\n<\/ul>\n\n<h4>2.6.120<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.119<\/h4>\n\n<ul>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.118<\/h4>\n\n<ul>\n<li>WordPress Plugin Check compliance: Continued improvements for file system operations and exception handling.<\/li>\n<\/ul>\n\n<h4>2.6.117<\/h4>\n\n<ul>\n<li>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().<\/li>\n<li>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.<\/li>\n<\/ul>\n\n<h4>2.6.116<\/h4>\n\n<ul>\n<li>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).<\/li>\n<li>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.<\/li>\n<\/ul>\n\n<p>(Older changelog entries are maintained in the project repository.)<\/p>","raw_excerpt":"A lightweight WordPress backup &amp; restore plugin focused on compatibility, single-file site snapshots, and clean restore workflows.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/263980","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=263980"}],"author":[{"embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/artherslin"}],"wp:attachment":[{"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=263980"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=263980"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=263980"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=263980"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=263980"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ro.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=263980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}