Skip to content

Instantly share code, notes, and snippets.

@mrazzari
Created May 29, 2012 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrazzari/2831366 to your computer and use it in GitHub Desktop.
Save mrazzari/2831366 to your computer and use it in GitHub Desktop.
Migrate a standalone WP database dump into a WP MultiSite install
<?php
if (count($argv) < 7){?>
WP-TO-MS-Import
Migrates a standalone WordPress database dump into a WP MultiSite install.
Author: @mrazzari, with thanks to @camilokawerin.
Author URL: http://ConVistaAlMar.com.ar
You found this at: https://gist.github.com/2831366
It's really a series of steps and best guesses, so maybe you'll have to edit it to suit your needs.
This script is meant to be idempotent: you can execute it many times, and still get the same results.
Won't break things if you run it twice.
It's not meant to address all possible situations and edge cases. "It works for me".
Bottom line: please read and review it carefully before executing it. And backup your data!
USAGE:
php migrate.php <dump_name.sql> <target_blog_id> <main_blog_hostname> <blog_url_old> <blog_url_new> <table_prefix_old>
dump_name: mysqldump file. Note that this script will modify it.
target_blog_id: a blog you've just created in your network, to be overwriten by this db dump.
main_blog_hostname: Host name of the main WP install.
blog_url_old: the site_url found in the db dump. If you enter a www-prefixed URL, both www and non-www URLs are replaced.
blog_url_new: the url of your new site. You may repeat the old URL here, if it's not changing.
table_prefix_old: the table prefix found in the DB dump. Usually wp_. If you weren't using one... this won't work!
EXAMPLE:
php migrate.php old-site.sql 2 blogs.example.com "http://www.old-site.com" "http://new-site.blogs.example.com" wp_
PREREQUISITES:
* Place this script next to wp-config.php (root folder of WP install)
* Also next to this, place the mysqldump file of your the old (standalone) blog.
* Your WP MS should be fully functioning.
* Using your network admin, create a new blog. Note its ID. You'll use it as target_blog_id.
<?php
return 0;
}
# Yeah argv ftw!
$dump = $argv[1];
$blogid = $argv[2];
$host = $argv[3];
$blog_url_old = $argv[4];
$blog_url_new = $argv[5];
$old_prefix = $argv[6];
# Set some context
set_time_limit(0);
ini_set( "memory_limit", "128M" );
# Load WordPress
$_SERVER['HTTP_HOST'] = $host;
require_once( 'wp-load.php');
echo "Replacing old table prefix with new one in the MySQL dump.\n";
$new_prefix = $table_prefix . $blogid . '_';
$cmd = sprintf('sed -i "s/\`%s/\`%s/gI" %s', $old_prefix, $new_prefix, $dump);
echo $cmd, "\n";
$out = shell_exec($cmd);
echo $out, "\n\n";
echo "Replacing old blog URL with the new blog URL.\n";
$blog_url_old_www_reg = str_replace("www.", "(www\.)?", $blog_url_old);
$cmd = sprintf('sed -i -r "s#%s#%s#gI" %s', $blog_url_old_www_reg, $blog_url_new, $dump);
echo $cmd, "\n";
$out = shell_exec($cmd);
echo $out, "\n\n";
echo "Replacing /wp-content/uploads/ with the WP MS location at /files/.\n";
$cmd = sprintf('sed -i -r "s#/wp-content/uploads/#/files/#gI" %s', $dump);
echo $cmd, "\n";
$out = shell_exec($cmd);
echo $out, "\n\n";
echo "Taking care of string lengths within serialized data.\n";
$newDump = "${dump}_tmp_replaced";
$reg = '#s:(\d+):\\\\"(.*?)\\\\";#sm';
echo "Searching $reg in $newDump and updating strlens.\n";
$handle = @fopen($dump, "r");
while (($newLine = fgets($handle, 4096)) !== false) {
$newLine = preg_replace_callback($reg, function($m){
return 's:' . strlen(stripslashes($m[2])) . ':\\"' . $m[2] . '\\";';
}, $newLine);
file_put_contents($newDump, $newLine, FILE_APPEND);
}
fclose($handle);
shell_exec("mv $newDump $dump");
echo "\n\n";
echo "Importing MySQL dump.\n";
$cmd = sprintf("mysql -u %s -h %s --password=%s %s < %s", DB_USER, DB_HOST, DB_PASSWORD, DB_NAME, $dump );
echo $cmd, "\n";
$out = shell_exec($cmd);
echo $out, "\n\n";
echo "Remapping users.\n";
$queries = Array();
$users = $table_prefix . 'users';
$usermeta = $table_prefix . 'usermeta';
$users_old = $new_prefix . 'users';
$usermeta_old = $new_prefix . 'usermeta';
# Delete any old users from a previous run of this script.
$old_users = "SELECT user_id FROM $usermeta WHERE meta_key = 'primary_blog' AND meta_value = $blogid";
$old_users = $wpdb->get_col($old_users);
if (count($old_users)){
$old_users = join(",", $old_users);
$queries[] = "DELETE FROM $users WHERE ID IN ($old_users)";
$queries[] = "DELETE FROM $usermeta WHERE user_id IN ($old_users)";
}
$autoinc = $wpdb->get_row("SHOW TABLE STATUS LIKE '${table_prefix}users'");
$autoinc = $autoinc->Auto_increment;
$source_domain = $wpdb->get_var("SELECT domain FROM ${table_prefix}blogs WHERE blog_id = $blogid");
# Disable key checks on the old users table.
$queries[] = "ALTER TABLE $users_old MODIFY COLUMN ID BIGINT(20) UNSIGNED NOT NULL, DROP PRIMARY KEY";
# Give incoming users fresh IDs.
$queries[] = "UPDATE $users_old SET ID = ID + $autoinc";
$queries[] = "UPDATE $usermeta_old SET user_id = user_id + $autoinc";
$queries[] = "UPDATE $usermeta_old SET meta_key = REPLACE(meta_key, '$old_prefix', '$new_prefix') WHERE meta_key LIKE '$old_prefix%'";
$queries[] = "UPDATE ${new_prefix}options SET option_name = '${new_prefix}user_roles' WHERE option_name = '${old_prefix}user_roles'";
$queries[] = "UPDATE ${new_prefix}posts SET post_author = post_author + $autoinc";
$queries[] = "UPDATE ${new_prefix}comments SET user_id = user_id + $autoinc WHERE user_id <> 0";
# Add missing metas.
$queries[] = "INSERT INTO $usermeta_old SELECT NULL, ID, 'primary_blog', $blogid FROM $users_old";
$queries[] = "INSERT INTO $usermeta_old SELECT NULL, ID, 'source_domain', '$source_domain' FROM $users_old";
# Import users.
$queries[] = "INSERT INTO ${table_prefix}users
SELECT ID, user_login, user_pass, user_nicename, user_email, user_url, user_registered, user_activation_key, user_status, display_name, 0, 0
FROM $users_old";
$queries[] = "INSERT INTO ${table_prefix}usermeta SELECT NULL, user_id, meta_key, meta_value FROM $usermeta_old";
# Tables you no longer need
$queries[] = "DROP TABLE $users_old";
$queries[] = "DROP TABLE $usermeta_old";
$wpdb->show_errors();
foreach ($queries as $query){
echo " ", $query, "\n";
$wpdb->query($query);
}
echo "\nDone. Go check your blog! :)\n";
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment