With Drupal 7 reaching end of life January 5, 2025 I've been working with many clients on this old CMS and bringing them over to WordPress. While it's easy to copy and paste the page content, moving users and their logins is much more difficult.
The first thing we need to do is pull the users out of the Drupal 7 database. Drupal stores its user data in three tables:
users
profile_fields
profile_values
With some mysql-fu, we can extract the core fields we need to create the users on WordPress. These would be:
profile_fields
and profile_values
table.I like to prepare this as a CSV file.
Now we have to import our CSV of Drupal 7 users into WordPress.
For this I like to use a Command since it may take some time to import your users, and doing it from the command line avoids any timeout issues.
Here’s the PHP script for the Command that I used:
if (class_exists('WP_CLI')) { WP_CLI::add_command('import_users', function ($args, $assoc_args) { $file = 'drupal7_users.csv' ; $handle = fopen( $file, 'r' ); if( ! $handle ) { WP_CLI::error( "$file cannot be opened."); die(); } while( ($data = fgetcsv($handle, 1000, ",")) !== FALSE ) { WP_CLI::line( 'Inserting user '.$data[1] ); wp_insert_user([ 'user_login' => $data[1], 'user_email' => $data[1], 'user_pass' => $data[2], 'user_nicename' => $data[3], 'display_name' => $data[3], 'role' => $data[4], 'meta_input' => [ 'drupal_id' => $data[5], 'd7_pw' => $data[6], ] ]); } WP_CLI::line('Complete!'); }); }
So in my terminal I run # wp import_users
from this projects directory, and that will run the above command.
This script will look for our CSV file of Drupal 7 users, and loop through each row, creating a new WordPress user for each. Pay close attention to the wp_insert_user
function and the array of data we send to it. If you’re using this code, remember to update the array indexes to match your specific CSV.
I want to draw your attention to to the meta_input[d7_pw]
user meta. We will be storing the Drupal 7 password here, for later.
Take a backup of your WP database before running the script above, just in case you need to restore it and run the command again to fix an import error.
Now that our Drupal 7 users have been imported, there’s just one problem: these users wont be able to login! Drupal 7 hashes its password differently than WordPress, and users will not be able to log in using their original passwords. You may be happy to generate everyone a new password, or ask them to use the password reset form, but for a seamless transition it would be great to allow them to use their Drupal 7 password. Here’s how we can do that:
d7_pw
user metad7_pw
user_pass
to the provided passwordd7_pw
user meta (to prevent running this again)Following these steps we can ensure that when a user tries to log in with their Drupal 7 password that we immediately capture that request. We then take their Drupal 7 password, re-hash it, and save it to the users
table – essentially updating their password to the Drupal 7 password. Lastly, as the login process continues, the user will be logged in normally.
Here’s the code you can place in a plugin, or in your theme’s functions.php
file:
/** * * Allow drupal users to log in with their password from before. * Then update it to a WP password hash. * */ add_action('wp_authenticate', function( $username, $password ){ // if these two variables are not present, we are not attempting a login! if( empty($username) || empty($password) ) return; // get the user $user = get_user_by('email', $username ); // If one doesn't exist, abort and let WP handle the rest. if( ! $user ) return; // get the old D7 password $d7pass = get_user_meta( $user->ID, 'd7_pw', true ); // If this user does not have a D7 pass in our system, abort and let WP handle the rest. if( ! $d7pass ) return; // Check if the user is trying to log in with their D7 pass if( md5( $password ) == $d7pass ) { // set the password for WP to this password provided wp_update_user([ 'ID' => $user->ID, 'user_pass' => $password ]); // remove the old password and also to prevent this script from running a second time. update_user_meta( $user->ID, 'd7_pw', null ); } }, 1, 2);