简体   繁体   中英

Drupal 6 user password import to Drupal 7

I don't really need to import any data into my D7 build other than users. I have (by SQL) imported my user data however, the D7 password encryption method is now different.

I'm not an expert by any stretch of the imagination and I've never used Drush, but I have come across this user_update_7000 code snippet found user.install ( http://api.drupal.org/api/drupal/modules--user--user.install/function/user_update_7000/7 )

<?php
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
$old_hash = md5('password');
$hash_count_log2 = 11;

$new_hash = user_hash_password($old_hash, $hash_count_log2);

if ($new_hash) {
  // Indicate an updated password.
  $new_hash  = 'U' . $new_hash;
}
?>

Where could I run this script in order to update the password field in my DB?

Thanks,

Steve

I think you can create a page named something like rehash.php (in your root, same place as update.php). Then, log in as administrator first, browse to this page second. See code below (most taken from user_update_7200 in the latest drupal 7 install)...

Worse case, you could create a simple custom module and put this code in there.

Please note that you should back things up first :

<?php
    // bootstrap stuff
    define('DRUPAL_ROOT', getcwd());

    include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

    require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');

    // Lower than DRUPAL_HASH_COUNT to make the update run at a reasonable speed.
    $hash_count_log2 = 11;

    //  Hash again all current hashed passwords.
    $has_rows = FALSE;

    // Update this many users
    $count = 1000;

    $result = db_query_range("SELECT uid, pass FROM {users} WHERE uid > 1 ORDER BY uid", 0, $count);
    foreach ($result as $account) {
      $has_rows = TRUE;
      $new_hash = user_hash_password($account->pass, $hash_count_log2);
      if ($new_hash) {
        // Indicate an updated password.
        $new_hash  = 'U' . $new_hash;
        db_update('users')
          ->fields(array('pass' => $new_hash))
          ->condition('uid', $account->uid)
          ->execute();
      }
    }
?>

I don't have enough points to add a comment, but I've made several refinements to hross' answer (and submitted a draft update).

Here's an improved script with documentation and the ability to specify a non-default users table for those doing manual Drupal 6 to 7 merges. It also incorporates jpb's checking.

<?php
  /**
   * Use this script to update Drupal 6 users password hashes to Drupal 7 specs.
   * 
   * Ensure you BACKUP YOUR USERS TABLE before using this script! If not your whole site! 
   * Name this file update_users.php and place in your Drupal root, same place as update.php
   *
   * - If you've manually inserted a new table into your database, change the $databasename below.
   * - If this does not run, ensure you are logged into your site as admin.
   * - If this does not run, check your drupal watchdog and/or PHP logs
   * - If you see this error "PDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'pass' at row 1:"
   *   you need to update your table's structure so that pass is a varchar(128).
   *
   * BACKUP, THIS MAY BREAK YOUR SITE AND EAT YOUR DATA!
   */

  echo "Starting. \r\n";

  // Change this if you've made a custom table
  $databasename = "users";

  // Update this many users
  $count = 1000;

  // bootstrap stuff
  define('DRUPAL_ROOT', getcwd());

  include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

  require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');

  // Lower than DRUPAL_HASH_COUNT to make the update run at a reasonable speed.
  $hash_count_log2 = 11;

  //  Hash again all current hashed passwords.
  $has_rows = FALSE;

  $result = db_query_range("SELECT uid, pass FROM {" . $databasename . "} WHERE uid > 10 ORDER BY uid", 0, $count);
  foreach ($result as $account) {
    $has_rows = TRUE;
    if (substr($account->pass, 0, 1) != 'U') {
      echo "updating account: " . $account->uid . " \r\n";
      $new_hash = user_hash_password($account->pass, $hash_count_log2);
      if ($new_hash) {
        // Indicate an updated password.
        $new_hash  = 'U' . $new_hash;
        db_update($databasename)
          ->fields(array('pass' => $new_hash))
          ->condition('uid', $account->uid)
          ->execute();
      }
    }
  }
  echo "Done.";
?>

This answer was perfect. I used it to update from a Drupal 5 site. I made a couple of changes to suit my purposes:

  1. I didn't limit the number of passwords that get updated. I wanted all of them updated, and the system I was updating had many more than 1,000 users.

  2. I added a check to make sure I wasn't updating a password twice. This way, if it times out (as it did for me) modifying all the passwords, I can rerun the rehash.php to complete the conversion. Be aware, though, that once a user logs in, the leading "U" is removed when the password is re-hashed.

     if (substr($account->pass, 0, 1) == 'U') { continue; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM