Migrating Users from Drupal 7 to WordPress

These two Content Management Systems handle users differently, here's how to migrate them.

Migrating Users from Drupal 7 to WordPress
Shawn Wernig
November 27, 2024
by Shawn Wernig

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.

Step 1:

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:

  1. users
  2. profile_fields
  3. profile_values

With some mysql-fu, we can extract the core fields we need to create the users on WordPress. These would be:

  1. The users name
  2. The users role
  3. The users email
  4. The users password
  5. Any custom fields from the profile_fields and profile_values table.

I like to prepare this as a CSV file.

Step 2:

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.

Step 3

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:

  1. Intercept a login attempt
  2. See if the user account trying to log in has a d7_pw user meta
  3. If they do, and the password in the login attempt matches the d7_pw
  4. Update the user_pass to the provided password
  5. Remove the d7_pw user meta (to prevent running this again)
  6. Let the user log in as normal

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);
Eggplant Studios - Custom Website Design and Development
Creating custom web solutions and happy clients since 2002
COPYRIGHT ©
2024
Eggplant Studios
- ALL RIGHTS RESERVED
LOGIN