diff --git a/inc/site-exporter/class-site-exporter.php b/inc/site-exporter/class-site-exporter.php index 40491c410..8288106a0 100644 --- a/inc/site-exporter/class-site-exporter.php +++ b/inc/site-exporter/class-site-exporter.php @@ -168,30 +168,40 @@ public function maybe_protect_export_folder(): void { * Set up integration with the default WordPress Sites page. * * This allows exporting sites even before Ultimate Multisite is fully set up, - * making migration from other solutions easier. + * making migration from other solutions easier. In single-site (non-multisite) + * installs, a Tools > Export & Import menu page is registered instead of the + * network-admin Sites page integration. * * @since 2.5.0 * @return void */ private function setup_wordpress_sites_integration(): void { - // Add export action link to each site row - add_filter('manage_sites_action_links', [$this, 'add_wp_sites_row_actions'], 10, 2); + if ( is_multisite() ) { + // Add export action link to each site row + add_filter('manage_sites_action_links', [$this, 'add_wp_sites_row_actions'], 10, 2); - // Add bulk export action - add_filter('bulk_actions-sites-network', [$this, 'add_wp_sites_bulk_actions']); + // Add bulk export action + add_filter('bulk_actions-sites-network', [$this, 'add_wp_sites_bulk_actions']); - // Handle bulk export action - add_filter('handle_network_bulk_actions-sites-network', [$this, 'handle_wp_sites_bulk_action'], 10, 3); + // Handle bulk export action + add_filter('handle_network_bulk_actions-sites-network', [$this, 'handle_wp_sites_bulk_action'], 10, 3); - // Add admin menu page for export/import - add_action('network_admin_menu', [$this, 'add_wp_export_menu_page']); + // Add admin menu page for export/import (network admin) + add_action('network_admin_menu', [$this, 'add_wp_export_menu_page']); - // Handle direct export requests - add_action('admin_init', [$this, 'handle_direct_export_request']); + // Display admin notices (network admin) + add_action('network_admin_notices', [$this, 'display_export_notices']); + } else { + // Single-site: add Tools > Export & Import menu page + add_action('admin_menu', [$this, 'add_single_site_export_menu_page']); - // Display admin notices - add_action('network_admin_notices', [$this, 'display_export_notices']); + // Display admin notices in regular admin + add_action('admin_notices', [$this, 'display_export_notices']); + } + + // Handle direct export requests (works in both multisite and single-site) + add_action('admin_init', [$this, 'handle_direct_export_request']); // Enqueue scripts for WordPress sites page add_action('admin_enqueue_scripts', [$this, 'enqueue_wp_sites_scripts']); @@ -200,6 +210,11 @@ private function setup_wordpress_sites_integration(): void { /** * Add export action link to WordPress Sites page rows. * + * In multisite, the main site is excluded from the network Sites list because + * it is exported through the regular admin Tools > Export & Import page. + * In single-site installs this filter is never called (the network Sites page + * does not exist), so the guard is multisite-specific. + * * @since 2.5.0 * * @param array $actions Existing actions. @@ -208,8 +223,9 @@ private function setup_wordpress_sites_integration(): void { */ public function add_wp_sites_row_actions(array $actions, int $blog_id): array { - // Don't add for main site - if (is_main_site($blog_id)) { + // In multisite, skip the main site — it is exported from the regular admin + // Tools > Export & Import page to avoid confusion in the network admin. + if ( is_multisite() && is_main_site($blog_id) ) { return $actions; } @@ -284,7 +300,25 @@ public function handle_wp_sites_bulk_action(string $redirect_url, string $action } /** - * Add export/import menu page under Sites. + * Get the admin base URL for the export/import page. + * + * Returns the network admin Sites URL in multisite installations and the + * regular admin Tools URL in single-site installations. + * + * @since 2.5.1 + * @return string + */ + private function get_export_admin_base_url(): string { + + if ( is_multisite() ) { + return network_admin_url('sites.php'); + } + + return admin_url('tools.php'); + } + + /** + * Add export/import menu page under Sites (multisite network admin). * * @since 2.5.0 * @return void @@ -301,6 +335,339 @@ public function add_wp_export_menu_page(): void { ); } + /** + * Add export/import menu page under Tools for single-site installs. + * + * Registers a Tools > Export & Import page when the plugin is active on a + * plain (non-multisite) WordPress installation so that site owners can still + * export their site or import an export package without network admin access. + * + * @since 2.5.1 + * @return void + */ + public function add_single_site_export_menu_page(): void { + + add_management_page( + __('Export & Import', 'ultimate-multisite'), + __('Export & Import', 'ultimate-multisite'), + 'manage_options', + 'wu-site-export', + [$this, 'render_single_site_export_page'] + ); + } + + /** + * Render the export/import page for single-site WordPress installs. + * + * Shown at Tools > Export & Import when running outside of a multisite + * network. Supports exporting the current site and importing a ZIP package + * that was produced by a previous export. + * + * @since 2.5.1 + * @return void + */ + public function render_single_site_export_page(): void { + + $action = wu_request('action', ''); + + $exports = wu_exporter_get_all_exports(); + $pending_exports = function_exists('wu_exporter_get_pending') ? wu_exporter_get_pending() : []; + $pending_imports = wu_exporter_get_pending_imports(); + + ?> +
+ ' . esc_html($sitename) . '', + esc_html($site_url) + ); + ?> +
+ + ++ + + +
+| + | + |
|---|---|
| options[0] ?? __('Unknown', 'ultimate-multisite')); ?> | ++ |
| + | + |
|---|---|
| options[0] ?? '')); ?> | ++ + + + | +
+