Migrating from Drupal to WordPress

Well, it finally happened. After months of frustration with Drupal as a blog tool, I gave up and decided it was time to move over to WordPress.

I’m sure as a CMS system Drupal can be quite wonderful, but for running and managing a simple blog site, I have yet to come across a better platform than WordPress.

However the migration of the database content from one system to another had it’s ups and downs. Fortunately for me, not many people read this blog, so I only had to migrate the posts data from one database to the other.

Below is the script I wrote to do so, in the hopes that this might save someone else the hassle of writing it themselves.

P.S. This was for a Drupal 6 to WordPress 2.8.2 migration. If it doesn’t work for you because you are working with different versions of either Drupal or WordPress, drop me a line and I will try to modify it for you.

	* Setup database constants
	define('DRUPAL', 'phpdevec_drpl1');
	define('WORDPRESS', 'phpdevec_wordpress');
	define('URL', 'http://www.php-developer.co.za/');
	* Setup server constants
	define("SERVER", "localhost");
	define('USER', 'username');
	define('PASSWORD', 'password');

	* debug function outputs data
	function debug($data){
		echo '<pre>';
		echo '</pre>';

	* Connect to server and database
	function connect($db) {
		// database connection
		$conn = mysql_connect(SERVER, USER, PASSWORD);
		if (!$conn) {
			//connection to server failed
			die("Cannot connect to server");
			return false;

		$dbSelected = mysql_select_db($db, $conn);
		if(!$dbSelected) {
			// database connection failed
			die("Cannot connect to database");
			return false;
		return $conn;

	* Close database connection
	function disconnect($conn){
		if ($conn){
			// connection exists to close
			if (!mysql_close($conn)){
				// database connection failed
				die("Cannot close database connection");
				return false;
			return true;
		// default return in case the original connection failed
		return true;

	* Generic SQL SELECT, checks type
	* @param string $sql query
	* @param string $type object or assoc
	* @return mixed $return array of rows if select or true/false if insert/update/delete

	function sql($sql, $database, $type = 'assoc'){
		$return = '';

		// check database connection
		$connection = connect($database);
		if (!$connection){
			$return = false;

		$sql = ltrim($sql);
		$query_type = substr($sql, 0, 6);

		// run query
		$rst = mysql_query($sql);

		if (!$rst){
			// query failed for some reason
			die("Error in MySQL query: " . $sql);
			$return = false;
		}else {

			if (strtoupper($query_type) == "SELECT"){
				// query was SELECT
				$return = array();
				$rows = mysql_num_rows($rst);

				switch($type) {
					case 'assoc' : // return as assoc array
						while($row = mysql_fetch_array($rst)) {
							// gather rows
							$return[] = $row;
					default : //return as object
					while($row = mysql_fetch_object($rst)) {
						// gather rows
						$return[] = $row;
			}else {
				// query was INSERT, UPDATE OR DELETE
				$queryType = 'UPDATE';
				if (mysql_insert_id()){
					// query was INSERT
					$id = mysql_insert_id();
					$queryType = 'INSERT';
					$return = $id;
				}else {
					$rows = mysql_affected_rows();
					$return = $rows;

		// disconnect from database

		//return rows / whether insert/update/delete successful
		return $return;

	$sql = "SELECT n.*, nv.body as content FROM node as n LEFT JOIN node_revisions as nv on n.nid = nv.nid WHERE n.type = 'blog'";

	$nodes = sql($sql, DRUPAL);


	$Nodes = array();

	foreach ($nodes as $node){
		$nId = $node['nid'];
		$sql = "SELECT * FROM comments WHERE nid = '$nId'";
		$comments = sql($sql, DRUPAL);
		$node['comments'] = $comments;
		$Nodes[] = $node;


	foreach ($Nodes as $node){
		//publish draft

		$two_hours = 2*3600;
		$date = $node['created'];
		$gmt_date = $date - $two_hours;
		$modified = $node['changed'];
		$gmt_modified = $modified - $two_hours;

		$post_date = date('Y-m-d H:i:s', $date);
		$post_date_gmt = date('Y-m-d H:i:s', $gmt_date);
		$post_modified = date('Y-m-d H:i:s', $modified);
		$post_modified_gmt = date('Y-m-d H:i:s', $gmt_modified);

		$post_title = mysql_escape_string($node['title']);
		$post_content = mysql_escape_string($node['content']);
		$post_name = strtolower(str_replace(array(' ', '.'), array('-', ''), $post_title));

		$status = $node['status'] == '1' ? 'publish' : 'draft';

		$sql = "INSERT INTO phpdevec_posts SET
			post_author = 1,
			post_date = '$post_date',
			post_date_gmt = '$post_date_gmt',
			post_content = '$post_content',
			post_title = '$post_title',
			post_status = '$status',
			comment_status = 'open',
			ping_status = 'open',
			post_name = '$post_name',
			post_modified = '$post_modified',
			post_modified_gmt = '$post_modified_gmt',
			post_parent = '0',
			menu_order = '0',
			post_type = 'post',
			comment_count = 0";

		$id = sql($sql, WORDPRESS);

		if (!$id){
			die('An error occured adding the data to the database');


		if (!empty($comments)){
			foreach ($comments as $comment){

		$guid = URL . "?p=$id";

		$sql = "UPDATE phpdevec_posts SET guid = '$guid' WHERE ID = '$id'";

		$updated_rows = sql($sql, WORDPRESS);

		if (!$updated_rows){
			die('An error occured updating record no '. $id);

Riding on Rails

I’ve decided to spend less of my free time on blogging and more on learning new things. I had planned to change this site to run on WordPress, but have decided instead to learn Ruby on Rails.

From what I can see it is (in many ways) similar to CakePHP (which I love) but with more of a command line/linux approach. Also it’s a new and interesting language to learn, so I’m sure there will be some exciting challenges along the way.

I don’t know where this new road will take me, but if its anything like CakePHP, I’m sure it will be fun. (yes, only geeks find coding fun!)

In other (u)interesting news, the FCK Editor helper I wrote has been used as part of someone else’s cake-bake-enhanced project.

To be honest I think it’s kinda cool, my first CakePHP helper and people are actually finding it worthwhile…time to write some more…