I had originally started a thread on the wordpress.org help forums for plugins and hacks (located here: http://wordpress.org...13583?replies=1 may have been the incorrect area) but it has been over 30 hours now and I have yet to receive a response of any sort so I thought I would post this here.
Here is the associated code (sorry it is commented heavily due to requirements of the people I am doing it for):
<?php
/*
Plugin Name: Clone Blog
Description: Allows you to easily clone a wpmu blog.
Author: amath
License: (Events: GNU General Public License 2.0 (GPL) http://www.gnu.org/licenses/gpl.html)
*/
// The above was required, DO NOT REMOVE!
// FOR DEBUG PURPOSES ONLY!
// SET TRUE TO HAVE ADDITIONAL OUTPUT WHEN CLONING
// SET TO FALSE WHEN NOT DEBUGGING!!!!!!!
// Default value: false
define("CLONE_DEBUG", false);
// IF USING THIS PLUGIN ON A LIVE SITE SET CLONE_LIVE TO true
// IF NOT ON A LIVE SITE (CLONE_LIVE = false) NO UPDATE/ INSERTION QUERIES WILL BE DONE
// Default value: true
define("CLONE_LIVE", true);
// To add the clone blog option to the site admin menu
add_action('admin_menu', 'cloneAddBlogMenuPage');
// The hook calls this function:
function cloneAddBlogMenuPage() {
// Use workdpress's function to add a new menu item
// parent, page_title, menu_title, access_level, file, function
add_submenu_page('wpmu-admin.php', 'Clone Blog', 'Clone Blog', 10, 'cloneblog', 'clone_blog_init');
// end function
}
// The function to be called when the menu item "Clone Blog" is clicked on.
function clone_blog_init(){
// Set an initial content variable, we will be echoing this at the end of the function.
$cloneContent = "Blog ID: " . $_POST['blogId'] . "<br/>";
// If we have post data, and we have a blog ID set (something to clone),
// and we have a path set lets do it (clone the blog).
if($_POST && isset($_POST['blogId']) && isset($_POST['path'])){
// We want access to the database so tell the function that $wpdb is a global variable
global $wpdb;
// set the clone's ID equal to one more than the number of blogs
$cloneId = 1+get_blog_count();
// Get the path information from the POST data
$path = $_POST['path'];
// Split the path apart to get an array of directories
$pathParts = explode("/", $path);
// Take the last directory (in an array such as this: /amath/courses/1350/) and set it to the course number (ie: 1350)
$courseNum = $pathParts[3];
// Get the list of blogs (in a serialized format) from the database
$unserializedBlogList = unserialize($wpdb->get_var("SELECT meta_value FROM wp_sitemeta WHERE meta_key = 'blog_list'"));
// set the current blog id to what was sent in (from POST)
$blogId = $_POST['blogId'];
// set a variable aside for later use
$cloneBlog;
// loop through each of the (now) unserialized blogs, call them $blogList for simplicity
foreach($unserializedBlogList AS $blogList){
/// If the blog's id is equal to the one we are cloning
if($blogList['blog_id'] == $blogId){
// set the clone blog variable (set aside directory before the loop) to the current blog we are looking at
$cloneBlog = $blogList;
// Break out of the loop, we are done looking
break;
// end if
}
//end for
}
unset($blogList); // clean up
// Update the clone blog's blog_id (set it equal to the clone id variable);
// NOTE - The blog_id is supposed to be a string, hence the concat in front.
$cloneBlog['blog_id'] = "" . $cloneId;
// Update the clone's path (for the first time)
$cloneBlog['path'] = $path;
// push the new cloned blog to the end of our blog array
$unserializedBlogList[] = $cloneBlog;
// serialize the blogs array and set it to FinalBlogList - for use later
$FinalBlogList = serialize($unserializedBlogList);
// commented out from debug
//die(var_dump($FinalBlogList));
// Create an array for all the queries we are about to create (so we can loop through them a little later easily)
$queryArray = array();
// Create all the queries to be done later on in the code.
// NOTE - All of these next few queries are done in the if(CLONE_LIVE) block below.
// They are defined here so we can output them when DEBUGGING.
// {
// wp_#_commentmeta
// Create the new table (for the clone) and copy EVERYTHING from the host's tables
$queryArray['commentMetaQuery'] = "CREATE TABLE IF NOT EXISTS wp_". $cloneId . "_commentmeta SELECT * FROM wp_" . $blogId . "_commentmeta";
//repeat previous for the next 8 tables
// {
// wp_#_comments
$queryArray['commentsQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_comments SELECT * FROM wp_" . $blogId . "_comments";
// wp_#_links
$queryArray['linksQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_links SELECT * FROM wp_" . $blogId . "_links";
// wp_#_options
$queryArray['optionsQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_options SELECT * FROM wp_" . $blogId . "_options";
// wp_#_postmeta
$queryArray['postMetaQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_postmeta SELECT * FROM wp_" . $blogId . "_postmeta";
// wp_#_posts
$queryArray['postsQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_posts SELECT * FROM wp_" . $blogId . "_posts";
// wp_#_term_relationships
$queryArray['termRelationshipsQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_term_relationships SELECT * FROM wp_" . $blogId . "_term_relationships";
// wp_#_term_taxonomy
$queryArray['termTaxonomyQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_term_taxonomy SELECT * FROM wp_" . $blogId . "_term_taxonomy";
// wp_#_terms
$queryArray['termsQuery'] = "CREATE TABLE IF NOT EXISTS wp_" . $cloneId . "_terms SELECT * FROM wp_" . $blogId . "_terms";
// }
// end repitition of the table cloning
// insert the blog to the wp_blogs table:
// NOTICE - The 'archived' value is the character zero ('0') and not the numeric value.
// If you try to a number of boolean it will truncate the field and the blog won't show up in a blog list.
$queryArray['blogQuery'] = $wpdb->prepare("INSERT INTO `wp_blogs` (`blog_id`, `site_id`, `domain`, `path`, `registered`, `last_updated`, `public`, `archived`, `mature`, `spam`, `deleted`, `lang_id`) VALUES(%d, 1, 'amath.colorado.edu', %s, '2010-05-28 22:17:59', '2010-06-08 20:34:48', 1, '0', 0, 0, 0, 0)", $cloneId, $path);
// Update the options table for the clone. Set the siteurl equal to the path passed in
$queryArray['updateQueryOne'] = "UPDATE wp_" . $cloneId . "_options SET option_value='http://amath.colorado.edu" . $path . "' WHERE option_name='siteurl'";
// update the options table for the clone. Set the home url to the path passed in.
$queryArray['updateQueryTwo'] = "UPDATE wp_" . $cloneId . "_options SET option_value='http://amath.colorado.edu" . $path . "' WHERE option_name='home'";
// update, set upload url to the course number
$queryArray['updateQueryThree'] = "UPDATE wp_" . $cloneId . "_options SET option_value='http://amath.colorado.edu/amath/courses/" . $courseNum . "/files' WHERE option_name='fileupload_url'";
// set upload path to the clone's id
$queryArray['updateQueryFour'] = "UPDATE wp_" . $cloneId . "_options SET option_value='wp-content/blogs.dir/" . $cloneId . "/files' WHERE option_name='upload_path'";
// set blog count the updated blog count (which coincides with clondId)
$queryArray['updateQueryFive'] = "UPDATE wp_sitemeta SET meta_value = " . $cloneId . " WHERE meta_key = 'blog_count'";
// update the list of blogs to the FinalBlogList from earlier.
$queryArray['updateQuerySix'] = "UPDATE wp_sitemeta SET meta_value = '" . $FinalBlogList . "' WHERE meta_key = 'blog_list'";
// change an option name to reflect the correct blog (the clone).
$queryArray['updateQuerySeven'] = "UPDATE wp_" . $clondId . "_options SET option_name = 'wp_" . $cloneId . "_user_roles' WHERE option_name = 'wp_" . $blogId . "_user_roles'";
// }
// End creating queries to be done.
foreach($queryArray AS $queryKey => $queryValue){
// if on a live site
if(CLONE_LIVE){
// make it so
$wpdb->query($queryValue);
// end if on live site
}
// if debugging
if(CLONE_DEBUG){
// add the query to our output buffer
$cloneContent .= $queryKey . ": " . $queryValue . "<br/>";
// end if debugging
}
} // end if CLONE_LIVE
unset($queryKey, $queryValue); // Clean up
// if we are live (otherwise there is no table wp_<CLONE_ID>_posts so a warning would be thrown.
if(CLONE_LIVE){
$updateQueryEight = ""; // for use in just a second.
$allPosts = $wpdb->get_results("SELECT guid, ID FROM wp_" . $cloneId . "_posts WHERE guid != ''", "ARRAY_A"); // get all the posts from our table
foreach($allPosts AS $post){ // loop through each post
$url = $post['guid'];
$courseParts = explode("courses", $url);
$urlParts = explode("/", $courseParts[1]);
// If the first character after courses is a slash we know the ourse number will be directly after that
if(substr($courseParts[1], 0, 1) == '/'){
// update the course number
$urlParts[1] = $courseNum;
// end if the first character was a slash
}
// otherwise
else{
// update the course number
$urlParts[0] = $courseNum;
// end else
}
// remake the url:
$urlConstructor = implode("/", $urlParts);
$courseParts[1] = $urlConstructor;
$finalURL = implode("courses", $courseParts);
// Update every post's guid
$wpdb->query("UPDATE wp_" . $cloneId . "_posts SET guid = '" . $finalURL . "' WHERER ID = " . $post['ID'] . "");
// if we are in debug mode
if(CLONE_DEBUG){
// add difference between the two URLs to our output buffer
$cloneContent .= $url . " -> " . $finalURL . "<br/>";
// end if CLONE_DEBUG
}
// end foreach $allPosts
}
unset($post); // Clean up
// Clear the clone's cache and recreate it.
refresh_blog_details($cloneId);
// Set the content to success.
$cloneContent .= "The blog was successfully cloned!<br/>Clone ID: " . $cloneId;
// end if CLONE_LIVE
}
// end if
}
// If we don't have any POST data
else{
// Get a list of the blogs, we want all of them
$cloneBlogList = get_blog_list(0, 'all');
// Start creating a form for the page
$cloneContent .= "<form action='#' method='post'><select name='blogId'>";
// loop through each of the blogs in the list, call each individual blog a "cloneBlog"
foreach($cloneBlogList AS $cloneBlog){
// for each of the cloneBlogs get their details;
$cloneBlogDetails = get_blog_details($cloneBlog['blog_id']);
// From their details and id we can create an option for the cloning process.
$cloneContent .= "<option value='" . $cloneBlog['blog_id'] . "'>" . $cloneBlogDetails->blogname . "</option>";
// end for
}
unset($cloneBlog); // clean up.
// Finish off the form
$cloneContent .= "</select><br/>New Blog Path: <input type='text' name='path'/><br/><input type='submit' value='Clone Blog'/></form>";
// end else
}
// output our buffer to the page
echo $cloneContent;
// end function
}
?>
Now, I feel it is important to state this is my first wordpress plugin of any sort, so there are probably API calls I could be using and am not currently.
At the moment it is set up using some blog-specific variables and options (given that I need it to work for my client first), but I hope to be able to get a generic build of it once it is completed.
Any help or insight would be greatly appreciated.

New Topic/Question
Reply



MultiQuote




|