Note that this article is for Joomla 1.5.x sites to be converted to Wordpress 3.2.x sites. I started with a Joomla 1.5 as the move from Joomla 1.6 or greater is a lot easier since it uses nested categories like Wordpress.
There are lots of commercial migrators out there and they all seem to have this problem. I'm really keen not to ask all my users to have to change their passwords but that is what the commercial applications are doing.
The script to transfer users
This is a free solution to at least get your user accounts all migrated. How you deal with the passwords can then be up to you. To use the following script, you need to change the my_wordpress_db to the name of your wordpress database and change my_joomla_db to the name of your joomla database. Note that your database user should have access to both databases in order for this to run smoothly:
INSERT INTO my_wordpress_db.wp_users (ID, user_login, user_nicename, user_email, user_url, user_registered, user_activation_key, user_status, display_name )
SELECT
a.id 'ID',
a.username 'user_login',
REPLACE(TRIM(LOWER(a.username)), ' ', '_') AS 'user_nicename',
a.email AS 'user_email',
' ' AS 'user_url',
a.registerDate AS 'user_registered',
' ' AS 'user_activation_key',
CASE a.block
WHEN 0 THEN 2
ELSE 0
END AS 'user_status', -- NOTE THAT THIS IS DEPRECATED IN WORDPRESS 3.X
a.name AS 'display_name'
FROM
my_joomla_db.jos_users a
ORDER BY
a.id;A bit more to do: PHP file
So I needed to do a loop and rather than complicate things with stored procedures and cursors, it's likely if you're using either Joomla or Wordpress that you have a PHP enabled server available. Here's code to top off the user migration, save it to an empty PHP file and upload/run it on your server:
please test before using!
<?php
// to run this script this user needs to be able to access both databases
$userName = "WordPressDB_sqluser";
$password = "MyUnguessablePassword";
$hostName = "localhost";
$database = "WordPressDB";
// Connect to the Database
if (!($link=mysql_connect($hostName, $userName, $password))) {
print(sprintf("error connecting to host %s, by user %s", $hostName, $userName));
exit();
}
//----------------
// Select the Database
if (!mysql_select_db($database, $link)) {
print(sprintf("Error in selecting %s database", $databaseName));
print(sprintf("error:%d %s", mysql_errno($link), mysql_error($link)));
exit() ;
}
$query='
SELECT
a.id \'user_id\',
REPLACE(TRIM(LOWER(a.username)), \' \', \'_\') AS \'user_nicename\',
a.email AS \'user_email\',
a.params AS \'user_params\',
CASE a.usertype
WHEN \'Super Administrator\' THEN 10
WHEN \'Administrator\' THEN 9
WHEN \'Manager\' THEN 8
WHEN \'Public Backend\' THEN 7
WHEN \'Publisher\' THEN 6
WHEN \'Editor\' THEN 5
WHEN \'Author\' THEN 4
WHEN \'Publisher\' THEN 3
WHEN \'Editor\' THEN 2
WHEN \'Author\' THEN 1
ELSE 0
END AS \'user_status\',
CASE a.block
WHEN 1 THEN 2
ELSE 0
END AS \'user_block\',
a.name AS \'display_name\'
FROM
my_joomla_db.jos_users a
ORDER BY
a.id;
';
$results = mysql_query( $query );
while ( $row = mysql_fetch_assoc( $results ) ) {
$this_id = $row['user_id'];
$this_name = $row['user_nicename'];
$this_email = $row['user_email'];
$this_status = $row['user_status'];
$this_block = $row['user_block'];
$this_params = $row['user_params'];
$this_dispname = $row['display_name'];
$wp_capabilities=($this_status==10)?'a:1:{s:13:"administrator";s:1:"1";}':'a:1:{s:10:"subscriber";s:1:"1";}';
$insert_query = '
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'first_name\', \' \' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'last_name\', \' \' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'nickname\', \''.$this_name.'\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'description\', \' \' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'rich_editing\', \'true\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'comment_shortcuts\', \'false\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'admin_color\', \'fresh\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'use_ssl\', 0 );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'show_admin_bar_front\', \'true\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'show_admin_bar_admin\', \'false\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'aim\', \' \' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'yim\', \' \' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'jabber\', \' \' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'wp_capabilities\', \''.$wp_capabilities.'\' );
INSERT INTO wp_usermeta ( user_id, meta_key, meta_value ) VALUES ( '.$this_id.', \'wp_user_level\', '.$this_status.' );
';
$insert_result = mysql_query ( $insert_query );
}
/*
if (!($result=mysql_query(sprintf($stmt), $link))) {
print(sprintf("Error in executing %s stmt", $stmt));
print(sprintf("error:%d %s", mysql_errno($link), mysql_error($link)));
exit();
}
*/
mysql_close($link);
//----------------
?>
Still to do for passwords
Joomla: MD5( password + salt )Wordpress: MD5( password ) _ Salt
Although one way, is it possible to extract the md5 of the Joomla password and process using wordpress script for passwords?
TO BE CONTINUED...
Thanks for the good script. I wish it worked for my Joomla 2.5 too
I'd like to recommend a cms2cms.com - it is a migration tool and works with all Joomla versions, that's a real time-saver. You get the content and users migrated (except for passwords) in minutes.
Also, it creates your categories and moves posts into them.
Good thinking Battman!
The core hack you suggest seems like the best idea I've heard so far on this. Not for the squeamish however and is likely to need to be repeated on future developments, but otherwise, the only solution I've seen so far.
Cheers!
Joe
Hi Kester,
Sorry but I'm not sure what you mean. The backslash then apostrophe in the PHP script is to escape the apostrophes. If you are running it directly in MySQL, then there is no need for escaping the apostrophes.
I have just tested the SQL part which works fine. I have also just tested the PHP script and this seems to be working ok. If you were running the PHP script in MySQL then this won't work. It may be possible from the bash/command prompt to run the PHP file (change the database connection details in the first variables (username, password, hostname, database)).
I hope that helps. You should really run the first SQL script and that will take you pretty close. The second part (PHP) is trying to determine exact access privileges per user.
Kind Regards,
Joe
A possible way to migrate Joomla passwords is to override Wordpress password check and extend it with Joomla's method. Copy the function wp_check_password from pluggable.php to a plugin and add the following lines to it:
if(strlen($hash) == (32+1+16)) // can be Joomla password
{
list($joohash, $salt) = explode(':', $hash);
$cryptpass = md5($password.$salt);
if ($joohash == $cryptpass) // Joomla password found
$hash = md5($password);
}
Hi Im a little new to sql. I was just wondering what is the purpose of having \'\' in the SELECT statement above. I tried running the script in mysql but it produced an error-" You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'user_id\', a.username AS \'user_nicename\', a.email AS \'user_email\', a.pa' at line 2"