Skip to content

Instantly share code, notes, and snippets.

@jphase
Created June 18, 2014 08:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jphase/029dec4ced280f268811 to your computer and use it in GitHub Desktop.
Save jphase/029dec4ced280f268811 to your computer and use it in GitHub Desktop.
WordPress Multisite Blog Copier
<?php
/*
Plugin Name: Multisite Blog Copy
Plugin URI: http://robido.com/multisite-blog-copy
Description: This is a plugin that copies multisite blogs (all their tables and files) and creates a new blog/site from it. This plugin also unserializes/reserializes and is meant for copying blogs from entirely different domain names.
Version: 1.0
Author: Jeff Hays (jphase)
Author URI: http://robido.com/blog
License: GPL2
*/
error_reporting(E_ALL^E_NOTICE^E_WARNING);
ini_set('display_errors', 1);
// Admin settings page
function mbc_admin_page(){
global $wpdb, $current_site;
$blogs = $wpdb->get_results("SELECT * FROM {$wpdb->blogs}");
if($_POST){
// Check for a blog and URL
if(isset($_POST['blogs']) && strlen($_POST['blogs']) > 0 && isset($_POST['URL']) && strlen($_POST['URL']) > 0){
// Setup defaults
switch_to_blog($_POST['blogs']);
$oldURL = str_replace('http://', '', get_bloginfo('url'));
$oldtitle = get_bloginfo('title');
$oldprefix = $wpdb->prefix;
$title = (isset($_POST['title']) && strlen($_POST['title']) > 0) ? $_POST['title'] : get_bloginfo('title');
// Grab all the tables we need to copy
$tables = $wpdb->get_results("SHOW TABLES FROM " . DB_NAME . " LIKE '{$wpdb->prefix}%'");
if(is_array($tables) && count($tables) > 0){
$copytables = array();
foreach($tables as $k=>$table){
$key = key((array)$table);
$copytables[] = $table->$key;
}
}
// Switch back to main blog
switch_to_blog(1);
$mainprefix = $wpdb->prefix;
// Insert new blog into blogs table
$wpdb->insert($wpdb->blogs, array(
'site_id' => $wpdb->siteid,
'domain' => $_POST['URL'],
'path' => '/',
'registered' => date('Y-m-d H:i:s'),
'last_updated' => date('Y-m-d H:i:s'),
'public' => 1,
'archived' => 0,
'mature' => 0,
'spam' => 0,
'deleted' => 0,
'lang_id' => 0
));
$blogID = $wpdb->insert_id;
// Insert new domain into domain mapping table
$wpdb->insert($wpdb->dmtable, array(
'blog_id' => $blogID,
'domain' => $_POST['URL'],
'active' => 1
));
// Loop through each of our tables and copy them
if(is_array($copytables) && count($copytables) > 0){
foreach($copytables as $copy){
// Copy table structure
$newtable = str_replace($oldprefix, $mainprefix.$blogID.'_', $copy);
$wpdb->query("CREATE TABLE `$newtable` LIKE `$copy`");
// Get rows from copied table
$rows = $wpdb->get_results("SELECT * FROM `$copy`");
if(is_array($rows) && count($rows) > 0){
foreach($rows as $j=>$row){
$row = get_object_vars($row);
// Bust rows into columns
foreach($row as $k=>$col){
// Find and replace all data
if(!is_serialized($col)){
// Regular data
$row[$k] = preg_replace('/'.$oldURL.'/', $_POST['URL'], $row[$k]);
$row[$k] = preg_replace('/'.$oldtitle.'/', $title, $row[$k]);
}else{
// Serialized data
$serial = unserialize($col);
foreach($serial as $i=>$data){
if(is_object($data)){
// Serialized object
$serial->$i = preg_replace('/'.$oldURL.'/', $_POST['URL'], $serial->$i);
$serial->$i = preg_replace('/'.$oldtitle.'/', $title, $serial->$i);
}else{
// Serialized array
$serial[$i] = preg_replace('/'.$oldURL.'/', $_POST['URL'], $serial[$i]);
$serial[$i] = preg_replace('/'.$oldtitle.'/', $title, $serial[$i]);
}
}
// Update row with new serialized object or array
$row[$k] = serialize($serial);
}
}
$rows[$j] = $row;
// Insert our replaced data into our new table
$wpdb->insert($newtable, $row);
}
}
}
// Copy files
if($_POST['files'] == 'on'){
$copyfrom = dirname(dirname(dirname(__FILE__))).'/blogs.dir/'.$_POST['blogs'];
$copyto = dirname(dirname(dirname(__FILE__))).'/blogs.dir/'.$blogID;
"Copying files from $copyfrom to $copyto<br>";
/* recurse_copy($copyfrom, $copyto, true); */
$fail = shell_exec( " cp -r -a $copyfrom $copyto 2>&1 " );
}
echo '<h4 style="color:00ff00;">Your blog was successfully copied. You can <a href="http://'.$_POST['URL'].'" target="_blank">see it here</a></h4>';
}
}
}
?>
<h2>Multisite Blog Copy</h2>
<form method="post">
<table>
<tbody>
<tr>
<td align="right" style="padding-right:1em;">Blog to Copy:</td>
<td>
<select name="blogs" style="width:100%">
<?php
if(is_array($blogs) && count($blogs) > 0){
foreach($blogs as $blog){
echo '<option value="'.$blog->blog_id.'">'.$blog->domain.'</option>';
}
}
?>
</select>
</td>
</tr>
<tr>
<td align="right" style="padding-right:1em;">New URL:</td>
<td><input name="URL" type="text" style="width:100%"></td>
</tr>
<tr>
<td align="right" style="padding-right:1em;">New Title:</td>
<td><input name="title" type="text" style="width:100%"></td>
</tr>
<tr>
<td align="right" style="padding-right:1em;">Copy Files:</td>
<td><input name="files" type="checkbox" checked="checked" style="width:100%"></td>
</tr>
<tr><td colspan="2"></td></tr>
<tr><td colspan="2"></td></tr>
<tr>
<td></td>
<td><input type="submit" value="Copy Blog" class="button button-primary"></td>
</tr>
</tbody>
</table>
</form>
<?php
}
// Admin submenu page
function mbc_submenu_page(){
// Add a submenu page in Network Admin > Sites
add_submenu_page('sites.php', 'Multisite Blog Copy', 'Multisite Blog Copy', 'manage_options', 'mbc_settings', 'mbc_admin_page');
}
add_action('network_admin_menu', 'mbc_submenu_page');
function recurse_copy($src, $dst, $debug=false) {
$dir = opendir($src);
if(!is_dir($dst)) mkdir($dst);
if($debug && !is_dir($dst)) echo "mkdir $dst<br>";
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
if($debug) echo '<strong>copying directory:</strong> ' . $src . '/' . $file . ' to ' . $dst . '/' . $file . '<br>';
recurse_copy($src . '/' . $file, $dst . '/' . $file, $debug);
} else {
if($debug) echo '<strong>copied file:</strong> ' . $src . '/' . $file . ' to ' . $dst . '/' . $file . '<br>';
copy($src . '/' . $file, $dst . '/' . $file);
}
}
}
closedir($dir);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment