jimboobrien
9/20/2017 - 11:16 PM

WP-CLI script for moving a multi-site instance from one domain to another

WP-CLI script for moving a multi-site instance from one domain to another

<?php
/**
 * WP-CLI script for moving a multi-site instance from one domain to another
 * 
 * Example command usage: wp eval-file multisite-migrate.php old-domain.com new-domain.com
 * Note: Currently, this script doesn't update all domain references, such as in post content.  
 * At this time, it is primarily used when creating a local copy of a multi-site instance in 
 * order to ensure everything will load on a local dev domain.
 */

global $old_url, $new_url;

$old_url = array_shift( $args );
$new_url = array_shift( $args );

if( empty( $old_url ) || empty( $new_url ) ) {
	die( 'Please provide both an old domain and a new domain.' . PHP_EOF );
}

/**
 * Replace instances of the old url with the new url
 *
 * @param string $url
 * @return string
 */
function replace_url( $url ) {
	global $old_url, $new_url;
	$found = strpos( $url, $old_url );
	if ( false !== $found ) {
		echo "    From: {$url}" . PHP_EOL;
		$url = str_replace( $old_url, $new_url, $url );
		echo "    To: {$url}" . PHP_EOL;
	}
	return $url;
}

/**
 * @var wpdb $wpdb
 */
global $wpdb;

// Update wp-config.php
echo 'Updating DOMAIN_CURRENT_SITE in wp-config.php...' . PHP_EOL;
echo shell_exec( "sed -i.bak -e 's/{$old_url}/{$new_url}/' wp-config.php" );

// Update site domain
echo 'Updating site domain...' . PHP_EOL;
$site_domain = $wpdb->get_var( 
	$wpdb->prepare( "SELECT domain FROM {$wpdb->site} WHERE id = %d", $wpdb->siteid ) 
);
$wpdb->update(
	$wpdb->site,
	array( 'domain' => replace_url( $site_domain ) ),
	array( 'id' => $wpdb->siteid ),
	array( '%s' ),
	array( '%d' )
);

echo 'Updating site meta: siteurl...' . PHP_EOL;
$site_url = $wpdb->get_var(
	$wpdb->prepare(
		"SELECT meta_value FROM {$wpdb->sitemeta} WHERE meta_key = 'siteurl' AND site_id = %d",
		$wpdb->siteid
	)
);
$wpdb->update(
	$wpdb->sitemeta,
	array( 'meta_value' => replace_url( $site_url ) ),
	array( 'meta_key' => 'siteurl', 'site_id' => $wpdb->siteid ),
	array( '%s' ),
	array( '%s', '%d' )
);

echo 'Fetching blogs...' . PHP_EOL;

$blogs = $wpdb->get_results(
	$wpdb->prepare( "SELECT * FROM {$wpdb->blogs} WHERE site_id = %d", $wpdb->siteid )
);

foreach ( $blogs as $blog ) {

	$blog_id = $blog->blog_id;

	echo 'Switching to blog: ' . $blog_id . ' - ' . $blog->domain . '...' . PHP_EOL;

	if ( switch_to_blog( $blog_id ) ) {

		// Update domain mappings
		$domain_mapping_table = $wpdb->base_prefix . 'domain_mapping';
		if ( $wpdb->get_var( "SHOW TABLES LIKE '{$domain_mapping_table}'" ) == $domain_mapping_table ) {
			echo 'Updating blog domain in domain mapping table...' . PHP_EOL;
			$dm_domain = $wpdb->get_var(
				$wpdb->prepare( "SELECT domain FROM {$domain_mapping_table} WHERE blog_id = %d", $blog_id )
			);
			$wpdb->update(
				$domain_mapping_table,
				array( 'domain' => replace_url( $dm_domain ) ),
				array( 'blog_id' => $blog_id ),
				array( '%s' ),
				array( '%d' )
			);
		}

		// Update blog domain
		echo 'Updating blog domain...' . PHP_EOL;
		$wpdb->update(
			$wpdb->blogs,
			array( 'domain' => replace_url( $blog->domain ) ),
			array( 'blog_id' => $blog_id ),
			array( '%s' ),
			array( '%d' )
		);

		// Update options
		$options = array(
			'home',
			'siteurl',
			'fileupload_url'
		);

		foreach ( $options as $option_name ) {
			echo 'Updating option: ' . $option_name . '...' . PHP_EOL;
			update_option( $option_name, replace_url( get_option( $option_name ) ) );
		}

	}

}