Moveable Import Script

This is a script to import moveable type entries into a textpattern system. You will need to use the export feature of your moveable type install to build an export file before continuing.

I’ve tested the script as best I can, and I believe that it should now run with out error on any TXP install. However, if you have problems please post them in the textpattern forum. You can also get in touch with me at my website.

The script should import your entries, and the corresponding comments on those entries, the primary category for an entry, and the users associated with entries. You will need to go an clean up users created by the script as they will have a default password, email address, etc.

Also, be aware that textile will be applied to all of your entries. If you were formatting your posts in MT yourself, this may cause you problems. Please set the forum above for a possible fix.

You may want to backup your database before proceeding, incase you are unhappy with how the script imported your posts.

I now turn things over to the good people at Word Press:

Howdy! We're about to begin the process to import all of your Movable Type entries into [Textpattern]. It's pretty easy, but it can possible take a little bit of time so be patient. Before we get started, you need to edit this file (import-mt.php) and change one line so we know where to find your MT export file. Look for the line that says:

define('MTEXPORT', '');

and change it to

define('MTEXPORT', '/path/to/your/import.txt');

You have to do this manually for security reasons.

If you've done that and you’re all ready, let's go! Remember that the import process may take a minute or so if you have a large number of entries and comments. Think of all the rebuilding time you'll be saving once it's done. :)

On our test system, importing a blog of 1189 entries and about a thousand comments took 18 seconds.

The importer is smart enough not to import duplicates, so you can run this multiple times without worry if for whatever reason it doesn't finish.

That should be that. If you have any problems please raise them in the textpattern forum.

previous page to continue."); function checkauthor($author) { // Checks if an author exists, creates it if it doesn't, and returns author_id $user_id = safe_field("name","txp_users","RealName = '$author'"); if (!$user_id) { safe_query("INSERT INTO ".PFX."txp_users (name, pass, RealName, email, privs) VALUES ('$author', 'changeme', '$author','changeme@changeme.com','1')"); $user_id = safe_field("name", "txp_users", "name = '$author'"); echo "Created user '$author'. "; } return $user_id; } // Bring in the data $datalines = file(MTEXPORT); // Read the file into an array $importdata = implode('', $datalines); // squish it $posts = explode("--------", $importdata); $i = -1; echo "
    "; foreach ($posts as $post) { if ('' != trim($post)) { ++$i; unset($post_categories); $post = preg_replace("/(\r\n|\n|\r)/", "\n", $post); echo "
  1. Importing post... "; // Take the pings out first preg_match("|(-----\n\nPING:.*)|s", $post, $pings); $post = preg_replace("|(-----\n\nPING:.*)|s", '', $post); // Then take the comments out preg_match("|(-----\nCOMMENT:.*)|s", $post, $comments); $post = preg_replace("|(-----\nCOMMENT:.*)|s", '', $post); // Then take the keywords preg_match("|(-----\nKEYWORDS:.*)|s", $post, $keywords); $post = preg_replace("|(-----\nKEYWORDS:.*)|s", '', $post); // We want the excerpt preg_match("|-----\nEXCERPT:(.*)|s", $post, $excerpt); $excerpt = addslashes(trim($excerpt[1])); $post = preg_replace("|(-----\nEXCERPT:.*)|s", '', $post); // We're going to put extended body into main body with a more tag preg_match("|-----\nEXTENDED BODY:(.*)|s", $post, $extended); $extended = trim($extended[1]); if ('' != $extended) $extended = "\n\n$extended"; $post = preg_replace("|(-----\nEXTENDED BODY:.*)|s", '', $post); // Now for the main body preg_match("|-----\nBODY:(.*)|s", $post, $body); $body = trim($body[1]); $post_content = addslashes($body . $extended); $post = preg_replace("|(-----\nBODY:.*)|s", '', $post); // Grab the metadata from what's left $metadata = explode("\n", $post); foreach ($metadata as $line) { preg_match("/^(.*?):(.*)/", $line, $token); $key = trim($token[1]); $value = trim($token[2]); // Now we decide what it is and what to do with it switch($key) { case '': break; case 'AUTHOR': $post_author = checkauthor($value); break; case 'TITLE': $post_title = addslashes($value); echo ''.stripslashes($post_title).'... '; $post_name = $post_title; break; case 'STATUS': // "publish" and "draft" enumeration items match up; no change required $post_status = $value; if (empty($post_status)) $post_status = 'publish'; break; case 'ALLOW COMMENTS': $post_allow_comments = $value; if ($post_allow_comments == 1) { $comment_status = 1; } else { $comment_status = 0; } break; case 'CONVERT BREAKS': $post_convert_breaks = $value; break; case 'ALLOW PINGS': $post_allow_pings = trim($meta[2][0]); if ($post_allow_pings == 1) { $post_allow_pings = 'open'; } else { $post_allow_pings = 'closed'; } break; case 'PRIMARY CATEGORY': $category1 = addslashes($value); break; case 'CATEGORY': $post_categories[] = addslashes($value); break; case 'DATE': $post_date = strtotime($value); $post_date = date('Y-m-d H:i:s', $post_date); break; default: echo "\n$key: $value was not processed"; break; } // end switch } // End foreach // Let's check to see if it's in already $post_id = safe_field("ID", "textpattern", "Title = '$post_title' AND Posted = '$post_date'"); if ($post_id) { echo "Post already imported."; } else { $url_title = stripSpace($post_title); $body_html = $textile->textileThis($post_content); echo "inserting ".$url_title; safe_query( "INSERT INTO ".PFX."textpattern ( Posted, LastMod, AuthorID, Title, Body, Body_html, Excerpt, Category1, AnnotateInvite, Status, Section, Keywords, url_title) VALUES ('$post_date', '$post_date', '$post_author', '$post_title', '$post_content', '$body_html', '$excerpt','$category1', '$default_comment_invite', '$insert_with_status', '$insert_into_section', '$keywords', '$url_title')"); $post_id = safe_field("ID","textpattern","Title = '$post_title' AND posted = '$post_date'"); if ($category1 != '') { // See if the category exists yet $cat_name = safe_field("name","txp_category","name = '$category1'"); if (!$cat_name && '' != trim($category1)) { safe_query("INSERT INTO ".PFX."txp_category (name, type, parent) VALUES ('$category1', 'article', 'root')"); $cat_id = safe_field("name","txp_category","name = '$category1'"); } } // Now for comments $comments = explode("-----\nCOMMENT:", $comments[0]); foreach ($comments as $comment) { if ('' != trim($comment)) { // Author preg_match("|AUTHOR:(.*)|", $comment, $comment_author); $comment_author = addslashes(trim($comment_author[1])); $comment = preg_replace('|(\n?AUTHOR:.*)|', '', $comment); preg_match("|EMAIL:(.*)|", $comment, $comment_email); $comment_email = addslashes(trim($comment_email[1])); $comment = preg_replace('|(\n?EMAIL:.*)|', '', $comment); preg_match("|IP:(.*)|", $comment, $comment_ip); $comment_ip = trim($comment_ip[1]); $comment = preg_replace('|(\n?IP:.*)|', '', $comment); preg_match("|URL:(.*)|", $comment, $comment_url); $comment_url = addslashes(trim($comment_url[1])); $comment = preg_replace('|(\n?URL:.*)|', '', $comment); preg_match("|DATE:(.*)|", $comment, $comment_date); $comment_date = trim($comment_date[1]); $comment_date = date('Y-m-d H:i:s', strtotime($comment_date)); $comment = preg_replace('|(\n?DATE:.*)|', '', $comment); $comment_content = addslashes(trim($comment)); $comment_content = str_replace('-----', '', $comment_content); // Check if it's already there $discuss_id = safe_field("discussid","txp_discuss","posted = '$comment_date' AND message = '$comment_content'"); if (!$discuss_id) { safe_query("INSERT INTO ".PFX."txp_discuss (parentid, name, email, web, ip, posted, message, visible) VALUES ($post_id, '$comment_author', '$comment_email', '$comment_url', '$comment_ip', '$comment_date', '$comment_content', '1')"); echo " Comment added."; } } } } echo "
  2. "; flush(); // n } } // entries are all imported. Rebuild the category tree. safe_insert("txp_category", "name='root',parent='',type='article',lft=1,rgt=0"); rebuild_tree('root',1,'article'); ?>

All done. Have fun!