<?php
include_once "includes/bootstrap.inc";
include_once "includes/common.inc";
?>
<html>
<head>
  <title>Movable Type => Drupal Conversion</title>
  <!-- Based on original code by Tim Allman.   -->
  <!-- Revised by Morbus Iff, 2004-05-26, with -->
  <!-- path aliasing stolen from Scott Laird.  -->
  <!-- Send comments to morbus@disobey.com.    -->
</head><body>


<?php

// import-specific settings.
//
// there are different types of Drupal content: stories, pages,
// forums, blogs, etc. by default, your Movable Type imports
// will be classified as new stories within your Drupal
// content management system. you can change this over to
// "blog" if you'd like, but you'll have to ensure that you've
// enabled the "blog" module PRIOR to running this install.
$node->type        = "story"; 

// the vocabulary name is used to create a new taxonomy within
// your new Drupal installation. taxonomies and vocabularies are
// fancy terms for Movable Type categories. you can name the vocab
// here; you can also change it through Drupal at a later date.
$vocabulary['name']  = "Weblog Categories";

// newly imported authors are given an entirely random password -
// for them to login, you can instruct users to "Request new
// password" from the login block. If, on the other hand, you'd
// like to set a default password for everyone, do so here.
$author['pass']      = rand(1,66606660666066606660);

// generic settings that probably shouldn't
// be changed unless you have a clue bit.
$timezone            = preg_replace('!:!', '', "<$MTBlogTimezone$>");
$node->promote       = 1; // all nodes should have had main page status.
$author['status']    = 1; // all author's are enabled within the system.
$comment['pid']      = 0; // no comments have been threaded; no parents.

// let's begin this bad boy, eh?
echo "<h1>Movable Type => Drupal Conversion</h1>";


// ///////////////////////////////////////////////////////////////////////////
// define code in functions to minimize generated size of the import file.  //
// ///////////////////////////////////////////////////////////////////////////
function add_taxonomy_term($term) {
  global $vocabulary; $term['tid'] = NULL; $term['vid'] = $vocabulary['vid'];
  $term = taxonomy_save_term($term); // should probably do some error checking.
  echo "<li>Created new term '$term[name]' in '$vocabulary[name]'.</li>";

  // path loving. yum. stolen from Scott Laird.
  $term_link = ereg_replace('^http://[^/]+/', '', $term['permalink']);
  echo "<li>Linking taxonomy/page/or/$term[tid] to $term_link.</li>";
  path_set_alias("taxonomy/page/or/$term[tid]", $term_link);
}

function check_for_author($author) {
  global $node; // yum, yum, gimme some.
  $user = user_load(array(mail => $author['mail']));
  $user_uid = $user->uid; if (!$user_uid) {
    $author['rid'] = array(_user_authenticated_id());
    $user = user_save($account, $author);
    echo "<li>Created new user '$author[name]'.</li>";
  } else { echo "<li>Entry has known user '$author[name]'.</li>"; }
  $node->uid = $user->uid; // node author to uid.
}

// for the node validation, it's important NOT to use the return
// $node from _validate, and only check for $error. since we're 
// directly adding new entries to the database from previously
// unauthorized users (those MT folks we're importing), node_
// validate will fail the "is this user authorized?" check, and
// return bum data (notably, the entry's ->date and ->created).
function add_node($node) {
  node_validate($node, $error); // check existence of $error only.
  if (!$error) { $nid = node_save($node); } else { print_r($error); exit; } 
  echo "<li>Created new entry '". $node->title ."'.</li>";

  // path loving. yum. stolen from Scott Laird.
  $path_link = ereg_replace('^http://[^/]+/', '', $node->permalink);
  echo "<li>Linking node/view/$nid to $path_link.</li>";
  path_set_alias("node/view/$nid", $path_link);
  return $nid; // all done. keep on truckin'.
}

function add_term_to_node($term) {
  global $vocabulary, $nid;
  $matches = taxonomy_get_term_by_name($term);
  foreach ($matches as $match) {
    if ($match->vid == $vocabulary['vid']) {
      taxonomy_node_save($nid, array($match->tid));
      echo "<li>Entry is categorized as '$term'.</li>";
    }
  }
}

function add_comment_to_node($comment) {
  global $nid; // wow. I have to pee. huh. that's not cool.
  $comment['thread'] = "$comment[thread]/";
  $comment['cid']    = db_next_id("{comments}_cid");

  // woulda liked to use the API, but the timestamp needed to be
  // the original setting, not the time of the import. some other
  // issues here and there too (invalid e-mails that had been
  // accepted, the check for whether comments were enabled, etc.)
  db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, hostname, ".
           "timestamp, status, score, users, thread, name, mail, homepage) VALUES ".
           "(%d, %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s')",
           $comment['cid'], $nid, 0, 0, NULL, $comment['comment'], $comment['remote_addr'],
           $comment['timestamp'], 0, 0, "a:1:{i:0;i:0;}", $comment['thread'],
           $comment['name'], $comment['email'], $comment['URL']);
}

// code stolen from trackback_receive.
function add_ping_to_node($ping) {
  global $nid; // wow. I have to pee. huh. that's not cool.
  $ping['thread']  = "$ping[thread]/";
  $ping['cid']     = db_next_id("{comments}_cid");
  $ping['excerpt'] = (strlen($ping['excerpt'] > 255) ? substr($ping['excerpt'], 0, 252) ."..." : $ping['excerpt']);
  $ping['name']    = ($ping['blog_name']) ? $ping['blog_name'] : $ping['url'];
  $comment  = "<strong>". t("TrackBack from %url", array("%url" => "<a href=\"$ping[url]\">$ping[name]</a>")) .":</strong><br />";
  $comment .= "<blockquote>$ping[excerpt]</blockquote>"; // all errors introduced are my own. beeyotch.

  // woulda liked to use the API, but the timestamp needed to be
  // the original setting, not time of the import. same with comments.
  // biggest change here is the addition of name/url as per CVS HEAD.
  db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, hostname, ".
           "timestamp, status, score, users, thread, name, mail, homepage) VALUES ".
           "(%d, %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s')",
           $ping['cid'], $nid, 0, 0, NULL, $comment, $ping['remote_addr'],
           $ping['timestamp'], 0, 0, "", $ping['thread'], $ping['name'],
           "", $ping['url']);
}

// ///////////////////////////////////////////////////////////////////////////
// first thing we do is import the categories of Movable Type (the "terms") //
// into the Drupal taxonomy ($vocabulary_name). if our vocabulary has been  //
// added already, we'll move on to entries (assuming multiple import runs). //
// ///////////////////////////////////////////////////////////////////////////
if (!taxonomy_get_vocabulary_by_name($vocabulary['name'])) {
echo "<h2>Importing Categories</h2><ul>"; echo "<li>Created new vocabulary '$vocabulary[name]'.</li>";
$vocabulary = taxonomy_save_vocabulary(array("name"=> $vocabulary['name'], "nodes" => array($node['type'])));

<MTCategories show_empty="1">
$term['name']         = "<$MTCategoryLabel$>";
$term['permalink']    = "<$MTCategoryArchiveLink$>";
$term['description']  = <<<CATEGORY_DESCRIPTION
<$MTCategoryDescription remove_html="1" $>
CATEGORY_DESCRIPTION;
add_taxonomy_term($term);

</MTCategories>  // if we're not creating a vocab, load the ID in. ugly hack, love me anyways. seriously.
echo "</ul>"; } else { $v = taxonomy_get_vocabulary_by_name($vocabulary['name']); $vocabulary['vid'] = $v[0]->vid; }

// ///////////////////////////////////////////////////////////////////////////
// now, let's import the entries. it'd be nice if we could import the       //
// authors first, but MT has no loopable author equivalent, so instead      //
// we have to do people when we learn about 'em during entry loop.          //
// ///////////////////////////////////////////////////////////////////////////
echo "<h2>Importing Entries</h2><ul>";

// depending on how you've configured
// your movable type entries, you should
// tweak these to be better represented.
//
// if you're running this script multiple
// times for large imports, [MTEntries] is
// where you'd set "lastn" and "offset". see
// your movable type manual for more info.
<MTEntries sort_order="ascend" lastn="100">
$node->title = <<<ENTRY_TITLE
<$MTEntryTitle remove_html="1"$>
ENTRY_TITLE;

$node->teaser = <<<ENTRY_TEASER
<$MTEntryExcerpt$>
ENTRY_TEASER;

$node->body = <<<ENTRY_BODY
<$MTEntryBody$><$MTEntryMore$>
ENTRY_BODY;

$author['name'] = "<$MTEntryAuthor$>";
$author['mail'] = '<$MTEntryAuthorEmail$>';
check_for_author($author); // add 'em?

$node->comment = 0; // comment status?
<MTEntryIfAllowComments>$node->comment = 1;
<MTEntryIfCommentsOpen>$node->comment = 2;
</MTEntryIfCommentsOpen></MTEntryIfAllowComments>

$node->permalink = "<$MTEntryPermalink$>";
$node->status    = strtolower('<$MTEntryStatus$>') == "publish" ? 1 : 0;
$node->created   = strtotime("<$MTEntryDate format="%Y-%m-%d %H:%M:%S"$> $timezone");
$node->changed   = strtotime("<$MTEntryModifiedDate format="%Y-%m-%d %H:%M:%S"$> $timezone");
$nid = add_node($node); // does validation.

<MTEntryCategories>
$term = "<$MTCategoryLabel$>";
add_term_to_node($term);

</MTEntryCategories>

$comment_count = 1;
<MTComments sort_order="ascend">
$comment['comment'] = <<<COMMENT_BODY
<$MTCommentBody remove_html="1"$>
COMMENT_BODY;

$comment['name']     = <<<COMMENT_NAME
<$MTCommentAuthor$>
COMMENT_NAME;

$comment['timestamp']   = strtotime("<$MTCommentDate format="%Y-%m-%d %H:%M:%S"$> $timezone");
$comment['remote_addr'] = "<$MTCommentIP$>";
$comment['email']       = "<$MTCommentEmail$>";
$comment['URL']         = "<$MTCommentURL$>";
$comment['thread']      = $comment_count;
add_comment_to_node($comment); $comment_count++;

</MTComments>

<MTPings sort_order="ascend">
$ping['title']       = <<<PING_TITLE
<$MTPingTitle$>
PING_TITLE;

$ping['excerpt']     = <<<PING_EXCERPT
<$MTPingExcerpt$>
PING_EXCERPT;

$ping['blog_name']   = <<<PING_BLOGNAME
<$MTPingBlogName$>
PING_BLOGNAME;

$ping['url']         = "<$MTPingURL$>";
$ping['timestamp']   = strtotime("<$MTPingDate format="%Y-%m-%d %H:%M:%S"$> $timezone");
$ping['remote_addr'] = "<$MTPingIP$>";
$ping['thread']      = $comment_count;
add_ping_to_node($ping); $comment_count++;

</MTPings>

$comment_count = 0;

</MTEntries>
echo "</ul>";

?>


</body>
</html>