Here is a database based procedure for porting Joomla to Drupal. It's got plusses (you can do tricks like concatenate fields, or change the case, do joins, or use other database functions) and minuses (perhaps not as simple as using a module, export and import).

I used Access, and created a new database, and an ODBC connection to my Drupal (test) database.

Then Import-Link Tables, and select all the tables. Answer some questions about which are the key fields of certain tables, and you will be able to browse your Drupal database.

First, create a vocabulary, i.e. vid=1

Here are some of the queries I used:

The bizarre where clauses are just because the Joomla data is perverted... some of the categories reference sections (which should be numeric section IDs) like "com_weblinks", so ignore those....

Import Taxonomies

-Insert the Sections into Term_data:

INSERT INTO term_data ( vid, name, description )
SELECT 1 AS Expr1, mos_sections.name, mos_sections.description
FROM mos_sections;

(the vid is a constant, 1)

Then insert the Sections into the Hierarchy, with Parent 0:
Sorry, overwrote it by accident....

Insert the Categories into the Term_data table:

INSERT INTO term_data ( vid, name, description )
SELECT 1 AS Expr1, mos_categories.name, mos_categories.description
FROM mos_categories
WHERE (((mos_categories.section)<"a" And
(mos_categories.section)<>"12" And (mos_categories.section)<>"7"));

For terms without parent, we must linked with themself

INSERT INTO term_hierarchy( tid, parent )
SELECT td.tid,0
FROM term_data td
WHERE td.tid NOT IN (SELECT th.tid FROM term_hierarchy th)

If you use pathauto module remember run Bulk generate aliases for terms that are not aliased

Again, vid is a constant, 1

-Insert the Categories into the Hierarchy

INSERT INTO term_hierarchy ( tid, parent )
SELECT term_data.tid, mos_categories.section
FROM term_data INNER JOIN mos_categories ON term_data.name =
mos_categories.name
WHERE (((term_data.tid)>7) AND ((mos_categories.section)<"a" And
(mos_categories.section)<>"12" And (mos_categories.section)<>"7"));

This gets the termid and the parent termid, which is what goes into the hierarchy.

If your Sections have moved around, you may have some Categories associated with the wrong section. It may be easier to just re-number (update the ID of the Section) rather than update all of the categories, which will likely be more numerous. Since the IDs are in a unique key, say you are swapping 1 and 3, make 1 like 999 or something, then switch the other one 3, to 1, then put 999 to 3, and when you refresh your Categories, things should line up better.

Import Nodes

Appending the Content to nodes_revisions per the node 80195, is really easy, once you realize that vid in this case is not the vocabularyid, but is a revisionid that must be unique across the entire database.

That query looks like this:

INSERT INTO node_revisions ( vid, uid, title, teaser, body ,log)
SELECT jos_content.id, 2 AS Expr2, jos_content.title, jos_content.introtext,
concat(jos_content.introtext,"<br>",jos_content.fulltext) AS Expr3, "Imported from joomla"
FROM joomla.jos_content;

Userid will be 2 to which you want to assign the content.

But nid in nodes_revisions is not autoincrement, which seems odd.

You can do essentially the same insert on nodes:

INSERT INTO node ( vid, type, title, uid )
SELECT mos_content.id, "story" AS Expr4, mos_content.title, 2 AS Expr2
FROM mos_content;

This importation don't handle i18n support, if you need set the language field with 'en' i.e:

INSERT INTO node ( vid, type, title, uid,language )
SELECT mos_content.id, "story" AS Expr4, mos_content.title, 2 AS Expr2, 'en'
FROM mos_content;

Then you just have to get the nodeid (nid) updated in node_revisions, which is easier, because we used the same id field from mos_content as the vid in both tables, so we use that to join the tables, and updated the node_revisions.nid with the node.nid:

UPDATE node INNER JOIN node_revisions ON node.vid = node_revisions.vid SET node_revisions.nid = [node].[nid];

There may be an issue with the vids being the same...Pro Drupal Development, p. 84, says vid has to be unique across nodes AND node revisions, so we may have to add 1000 or something to make them unique....haven't gotten there yet.

Import Joomla/Mambo Modules as Nodes

Sometimes Joomla used modules to represent content, for this reason depends of Joomla/Mambo implementation could be a good idea import modules with content and published.

INSERT INTO drupal.node_revisions(vid,uid,title,body,log)
SELECT id+57,2,title,content,'Imported from joomla' 
FROM joomla.jos_modules
where jos_modules.published = 1 and jos_modules.content != ''
INSERT INTO drupal.node ( vid, type, title, uid )
SELECT id+57,"story",title,2 
FROM joomla.jos_modules
where jos_modules.published = 1 and jos_modules.content != ''

Import Users

INSERT INTO users(name,pass,mail,status)
SELECT ju.name,ju.email,ju.password,1
FROM joomla.jos_users ju

All users well be active, change the constant 1 to 0 if you want import as disabled users

Comments

dalinian’s picture

Building off of this approach, I came up with this method for creating nodes using sql queries for a joomla site on another server. This process will create nodes and link the original authors as the drupal authors. For this to work, however, you must import all joomla users to the drupal site.

NOTE: This method assumes a clean drupal installation, you will need to alter this if you already have content on your drupal site. Also this was performed on a Joomla 1.0.x site, 1.5 or 1.6 may have a different data structure.

Step 1 - Dump the joomla database

Dump the joomla database:

mysqldump -u USER -p joomla_dbname > joomla_dbname.sql;

Step 2 - Copy and Create the database on the drupal server

After copying the joomla_dbname.sql file to the drupal server, login to the drupal server and into the directory where you placed the joomla_dbname.sql file, then do the following (in linux (ms users, please switch)):

mysql -u USER -p
CREATE DATABASE joomla_todrup;
exit
mysql -u USER -p joomla_todrup < joomla_dbname.sql

You should now have an active joomla database on your drupal server.

Step 3 - Create users

I used the User Import module for this step. It is pretty straight forward, simply follow the directions.

Step 4 (optional)- Create a content type for your import

Rather than import all of the content into a default node type, I chose to create an new content type 'archive' for making this import. This decision was simply a step of convenience. You could easily import the content as any type you want. (see Step 5).

Step 5 - Create a temporary table for the import

This step takes place in the mysql> command line interface. I suppose you could write a script to accomplish this, but I chose not to. The temporary table will hold all the necessary information for creating nodes. You will need to change DRUPAL_DB_NAME to your specific drupal database name. You can find this at the mysql> prompt with 'show databases;'.

Also make sure to change "archive" as type to "your preferred content type" as type.

CREATE TEMPORARY TABLE DRUPAL_DB_NAME.joomla_nodes SELECT
UNIX_TIMESTAMP(joomla_todrup.jos_content.created) created,
UNIX_TIMESTAMP(joomla_todrup.jos_content.modified) changed,
concat(joomla_todrup.jos_content.introtext,"<!--break-->",joomla_todrup.jos_content.fulltext) body,
2 as format, "archive" as type,
joomla_todrup.jos_users.id juid, joomla_todrup.jos_content.title,
joomla_todrup.jos_content.id jnid, DRUPAL_DB_NAME.users.uid uid,
DRUPAL_DB_NAME.users.name FROM joomla_todrup.jos_users,
joomla_todrup.jos_content, DRUPAL_DB_NAME.users where
DRUPAL_DB_NAME.users.name = joomla_todrup.jos_users.username and
joomla_todrup.jos_content.created_by = joomla_todrup.jos_users.id;

Step 6 - Create the nodes on node table

INSERT INTO node (vid, title, type, uid, created, changed) select
jnid, title, type, uid, created, changed from joomla_nodes;

Step 7 - Create the nodes on node_revisions table

INSERT INTO node_revisions (nid, vid, uid, title, body, timestamp,
format) select node.nid, node.vid, node.uid, node.title, jodes.body,
node.created, joomla_nodes.format FROM node, joomla_nodes WHERE
joomla_nodes.jnid = node.vid;

You should now have all of your basic node content live on your drupal site.

Step 8 - Move joomla image directory

Copy the joomla images directory to DRUPAL_PATH/sites/default/files/images.

Step 9 - Rewrite image paths

This step is probably a little dangerous and may flub up some of your content; however, it worked for me. You will need to have drush installed on your system for this to work. In your drupal base path create a file "modify-drupal-image-paths.php" with the following code in the file:

<?php
require_once './includes/bootstrap.inc';drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
user_load(1);
$sql = "SELECT nid FROM node_revisions";
$result = db_query($sql);
while($query = db_fetch_array($result)) {
    $node = node_load($query['nid']);
    $content = '"images';
    $replace = '"/sites/default/files/images';
    $node->body = str_replace($content, $replace, $node->body);
    node_save($node);
}

?>

From the command line, run

php -f modify-drupal-image-paths.php

You should now have all of your node content published on your drupal site and images should be displayed.

NOTE: The above process creates full html nodes. You may want to modify this and other settings.