/** * Move a blog from one network to another * * @since 1.3 * * @param integer $site_id ID of blog to move * @param integer $new_network_id ID of destination network */ function move_site($site_id, $new_network_id) { global $wpdb; // Get the site $site = get_blog_details($site_id); // Bail if site does not exist if (empty($site)) { return new WP_Error('blog_not_exist', __('Site does not exist.', 'wp-multi-network')); } // Main sites cannot be moved, to prevent breakage if (is_main_site_for_network($site->blog_id)) { return true; } // Cast new network ID $new_network_id = (int) $new_network_id; // Return early if site does not need to be moved if ($new_network_id === (int) $site->site_id) { return true; } // Store the old network ID for using later $old_network_id = (int) $site->site_id; $old_network = wp_get_network($old_network_id); // No change if ($old_network_id === $new_network_id) { return new WP_Error('blog_not_moved', __('Site was not moved.', 'wp-multi-network')); } // New network is not zero if (0 !== $new_network_id) { $new_network = wp_get_network($new_network_id); if (empty($new_network)) { return new WP_Error('network_not_exist', __('Network does not exist.', 'wp-multi-network')); } // Tweak the domain and path if needed // If the site domain is the same as the network domain on a subdomain // install, don't prepend old "hostname" if (is_subdomain_install() && $site->domain !== $old_network->domain) { $ex_dom = substr($site->domain, 0, strpos($site->domain, '.') + 1); $domain = $ex_dom . $new_network->domain; } else { $domain = $new_network->domain; } $path = substr($site->path, strlen($old_network->path)); // New network is zero (orphan) } else { // Mock a zero network object $new_network = new WP_Network((object) array('domain' => 'network.zero', 'path' => '/', 'id' => '0')); // Set domain & path to that of the current site $domain = $site->domain; $path = $site->path; } // Move the site is the blogs table $where = array('blog_id' => $site->blog_id); $update = array('site_id' => $new_network->id, 'domain' => $domain, 'path' => $path); $update_result = $wpdb->update($wpdb->blogs, $update, $where); // Bail if site could not be moved if (empty($update_result)) { return new WP_Error('blog_not_moved', __('Site could not be moved.', 'wp-multi-network')); } // Update old network count if (0 !== $old_network_id) { switch_to_network($old_network_id); wp_update_network_site_counts(); restore_current_network(); } // Update new network count if (0 !== $new_network_id) { switch_to_network($new_network_id); wp_update_network_site_counts(); restore_current_network(); } // Change relevant blog options $options_table = $wpdb->get_blog_prefix($site->blog_id) . 'options'; $old_domain = $old_network->domain . $old_network->path; $new_domain = $new_network->domain . $new_network->path; // Update all site options foreach (network_options_list() as $option_name) { $sql = "SELECT * FROM {$options_table} WHERE option_name = %s"; $prep = $wpdb->prepare($sql, $option_name); $option = $wpdb->get_row($prep); // No value, so skip it if (empty($option)) { continue; } $new_value = str_replace($old_domain, $new_domain, $option->option_value); update_blog_option($site->blog_id, $option_name, $new_value); } // Delete rewrite rules for site at old URL delete_blog_option($site_id, 'rewrite_rules'); // Site moved do_action('move_site', $site_id, $old_network_id, $new_network_id); }
/** * Metabox for assigning sites to a network * * @since 1.7.0 * * @param WP_Network $network */ function wpmn_edit_network_assign_sites_metabox($network = null) { // To $to = get_sites(array('network_id' => $network->id)); // From $from = get_sites(array('network__not_in' => array($network->id))); ?> <table class="assign-sites widefat"> <thead> <tr> <th><?php esc_html_e('Available Sites', 'wp-multi-network'); ?> </th> <th> </th> <th><?php esc_html_e('Network Sites', 'wp-multi-network'); ?> </th> </tr> </thead> <tr> <td class="column-available"> <p class="description"><?php esc_html_e('Subsites in other networks & orphaned sites without networks.', 'wp-multi-network'); ?> </p> <select name="from[]" id="from" multiple> <?php foreach ($from as $site) { ?> <?php if ((int) $site->site_id !== (int) $network->id && !is_main_site_for_network($site->blog_id)) { ?> <option value="<?php echo esc_attr($site->blog_id); ?> "> <?php echo esc_html(sprintf('%1$s (%2$s%3$s)', $site->name, $site->domain, $site->path)); ?> </option> <?php } ?> <?php } ?> </select> </td> <td class="column-actions"> <input type="button" name="unassign" id="unassign" class="button" value="←"> <input type="button" name="assign" id="assign" class="button" value="→"> </td> <td class="column-assigned"> <p class="description"><?php esc_html_e('Only subsites of this network can be reassigned.', 'wp-multi-network'); ?> </p> <select name="to[]" id="to" multiple> <?php foreach ($to as $site) { ?> <?php if ((int) $site->site_id === (int) $network->id) { ?> <option value="<?php echo esc_attr($site->blog_id); ?> " <?php disabled(is_main_site_for_network($site->blog_id)); ?> > <?php echo esc_html(sprintf('%1$s (%2$s%3$s)', $site->name, $site->domain, $site->path)); ?> </option> <?php } ?> <?php } ?> </select> </td> </tr> </table> <?php }
/** * Handle the request to reassign sites * * @since 1.7.0 * * @global object $wpdb */ private function reassign_sites_handler() { global $wpdb; // Coming in $to = isset($_POST['to']) ? $_POST['to'] : array(); // Orphaning out $from = isset($_POST['from']) ? $_POST['from'] : array(); // Bail early if no movement if (empty($to) && empty($from)) { return; } // Cast the network ID $network_id = (int) $_GET['id']; // Query for sites $sql = "SELECT * FROM {$wpdb->blogs}"; $prep = $wpdb->prepare($sql, (int) $_GET['id']); $sites = $wpdb->get_results($prep); // Loop through and move sites foreach ($sites as $site) { // Skip the main site of this network if (is_main_site_for_network($site->blog_id, $site->site_id)) { continue; } // Coming in if (in_array($site->blog_id, $to)) { move_site($site->blog_id, $network_id); // Orphaning out } elseif (in_array($site->blog_id, $from)) { move_site($site->blog_id, 0); } } }
/** * Metabox for assigning sites to a network * * @since 1.7.0 * * @param object $network * @global object $wpdb */ function wpmn_edit_network_assign_sites_metabox($network = null) { global $wpdb; // Get sites $sql = "SELECT * FROM {$wpdb->blogs}"; $sites = $wpdb->get_results($sql); foreach ($sites as $key => $site) { $table_name = $wpdb->get_blog_prefix($site->blog_id) . "options"; $sql = "SELECT * FROM {$table_name} WHERE option_name = %s"; $prep = $wpdb->prepare($sql, 'blogname'); $site_name = $wpdb->get_row($prep); $sites[$key]->name = stripslashes($site_name->option_value); } ?> <table class="assign-sites widefat"> <thead> <tr> <th><?php esc_html_e('Available Sites', 'wp-multi-network'); ?> </th> <th> </th> <th><?php esc_html_e('Network Sites', 'wp-multi-network'); ?> </th> </tr> </thead> <tr> <td class="column-available"> <p class="description"><?php esc_html_e('Subsites of other networks, and orphaned sites with no networks.', 'wp-multi-network'); ?> </p> <select name="from[]" id="from" multiple> <?php foreach ($sites as $site) { ?> <?php if ($site->site_id !== $network->id && !is_main_site_for_network($site->blog_id)) { ?> <option value="<?php echo esc_attr($site->blog_id); ?> "> <?php echo esc_html(sprintf('%1$s (%2$s%3$s)', $site->name, $site->domain, $site->path)); ?> </option> <?php } ?> <?php } ?> </select> </td> <td class="column-actions"> <input type="button" name="unassign" id="unassign" class="button" value="←"> <input type="button" name="assign" id="assign" class="button" value="→"> </td> <td class="column-assigned"> <p class="description"><?php esc_html_e('Only subsites of this network can be reassigned.', 'wp-multi-network'); ?> </p> <select name="to[]" id="to" multiple> <?php foreach ($sites as $site) { ?> <?php if ($site->site_id === $network->id) { ?> <option value="<?php echo esc_attr($site->blog_id); ?> " <?php disabled(is_main_site_for_network($site->blog_id)); ?> > <?php echo esc_html(sprintf('%1$s (%2$s%3$s)', $site->name, $site->domain, $site->path)); ?> </option> <?php } ?> <?php } ?> </select> </td> </tr> </table> <?php }
/** * Handle the request to reassign sites * * @since 2.0.0 */ private function handle_reassign_sites() { // Coming in $to = isset($_POST['to']) ? array_map('absint', (array) $_POST['to']) : array(); // Orphaning out $from = isset($_POST['from']) ? array_map('absint', (array) $_POST['from']) : array(); // Bail early if no movement if (empty($to) && empty($from)) { return; } // Cast the network ID $network_id = (int) $_GET['id']; // Setup sites arrays $moving_to = $moving_from = array(); // Query for sites in this network $sites_list = get_sites(array('network_id' => $network_id, 'fields' => 'ids')); // Moving out from current network foreach ($from as $site_id) { if (in_array($site_id, $sites_list, true)) { $moving_from[] = $site_id; } } // Moving into current network foreach ($to as $site_id) { if (!in_array($site_id, $sites_list, true)) { $moving_to[] = $site_id; } } // Merge into one array $moving = array_filter(array_merge($moving_to, $moving_from)); // Loop through and move sites foreach ($moving as $site_id) { // Skip the main site of this network if (is_main_site_for_network($site_id)) { continue; } // Coming in if (in_array($site_id, $to) && !in_array($site_id, $sites_list, true)) { move_site($site_id, $network_id); // Orphaning out } elseif (in_array($site_id, $from, true)) { move_site($site_id, 0); } } }
/** * Move a site to a new network * * @since 1.3 * * @param integer $site_id ID of site to move * @param integer $new_network_id ID of destination network */ function move_site($site_id = 0, $new_network_id = 0) { global $wpdb; // Get the site $site = get_blog_details($site_id); // Bail if site does not exist if (empty($site)) { return new WP_Error('blog_not_exist', __('Site does not exist.', 'wp-multi-network')); } // Main sites cannot be moved, to prevent breakage if (is_main_site_for_network($site->blog_id)) { return true; } // Cast new network ID $new_network_id = (int) $new_network_id; // Return early if site does not need to be moved if ($new_network_id === (int) $site->site_id) { return true; } // Move the site is the blogs table $where = array('blog_id' => $site->blog_id); $update = array('site_id' => $new_network_id); $result = $wpdb->update($wpdb->blogs, $update, $where); // Bail if site could not be moved if (empty($result)) { return new WP_Error('blog_not_moved', __('Site could not be moved.', 'wp-multi-network')); } // Update old network count if (0 !== $site->site_id) { switch_to_network($site->site_id); wp_update_network_site_counts(); restore_current_network(); } // Update new network count if (0 !== $new_network_id) { switch_to_network($new_network_id); wp_update_network_site_counts(); restore_current_network(); } // Refresh blog details refresh_blog_details($site_id); // Clean network caches clean_network_cache(array_filter(array($site->site_id, $new_network_id))); // Site moved do_action('move_site', $site_id, $site->site_id, $new_network_id); // Return the new network ID as confirmation return $new_network_id; }