I'm trying to import some users into Drupal programmatically as blocked. I found two methods to do this: user_save and drupal_execute. However, the first one doesn't send notification email with the link to reset the password while the other method does send the mail, but when clicking the link I get a denied access.

I tried the code in 2 environments (Ubuntu and Windows) with one fresh installation. Here is the code I'm actually using:

// register a new user
$form_state['values']['name'] = 'username';
$form_state['values']['mail'] = 'mail@example.com';

// generate and assign password
$pass = user_password(8);
$form_state['values']['pass'] = array (
    'pass1' => $pass,
    'pass2' => $pass
$form_state['values']['status'] = 0; // add user as blocked
$form_state['values']['notify'] = 1; // send notification with reset link
$form_state['values']['op'] = t('Create new account');

// check if user it's not already imported
$sql = "SELECT uid FROM {users} WHERE name = '%s'";
$result = db_query($sql, $form_state['values']['name'] );
$data = db_result($result);
if (!$data) {  // if the user does not exist, add it
    drupal_execute('user_register', $form_state);

The user is added correctly in the database as blocked, I receive the notification email but when I click on the reset link I get access denied (which, by the way, it's appearing twice: all the elements of my theme twice with the error as content; really nasty bug... don't know why, anyone?)

Here goes the second code:

// user details
$users = array(
    'name' => 'username',
    'pass' => user_password(8),
    'mail' => 'mail@example.com',
    'access' => '0',
    'status' => 0,
    'notify' => 1,
    'timezone' => 7200,
    'init' => 'mail@example.com'

$sql = "SELECT uid FROM {users} WHERE name = '%s'";
$result = db_query( $sql, $users['name'] );
$data = db_result( $result );
if (!$data)
    user_save( NULL, $users, NULL );

With this method, everything works fine but I don't get the email, which is pointless because the users are blocked.

I don't know if this is a hard question (only for Drupal gurus), but I would appreciate any help.

Thank you!


I'm assuming that you are wanting users to click on a link in the registration email to validate the address (this is configurable in your user settings)

You should set status=1 in the user as this is the default behavior and if it is 0 the login link will not work.

If you look at user_register_submit() there is code in it to send out emails.

I think you want

$account =  user_save( NULL, $users, NULL );
if($account) {
  _user_mail_notify('register_admin_created', $account);
else {
// Error code

at the end of your second method.

  • I already tried that: I receive the mail with but with no password (password: !password) and the reset link still shows access denied. If you're kind enough, please try it yourself with a custom module; thanks! – sergio May 13 '11 at 12:49
  • Played around a bit, I think you need to set status = 1 when you create the user. – Jeremy French May 13 '11 at 13:25
  • Did you try it with status = 1? It doesn't get access denied? – sergio May 13 '11 at 14:28
  • Tried locally changing a use from status 1 to 0 and got access denied, changed it to 1 again and login link worked. – Jeremy French May 13 '11 at 14:32
  • I tried with status = 1 and the link works; but with _user_mail_notify I get and email in which password: !password. I would like to use the second method because of the email explaining that the admin added the user. – sergio May 16 '11 at 8:01

Here's the final code:

// setup the details
$password = user_password(8);

$user = array(
    'name' => 'username',
    'pass' => $password, // field to save in the database
    'password' => $password, // required to send in notification mail
    'mail' => 'mail@example.com',
    'access' => '0',
    'status' => 1,
    'timezone' => 0,
    'init' => 'mail@example.com'

$sql = "SELECT uid FROM {users} WHERE name = '%s'";
$result = db_query( $sql, $user['name'] );
$data = db_result( $result );
if (!$data) {  // if the user does not exist
    $account = user_save( NULL, $user, NULL );

    // send notification
    if ($account) {
        // add profile fields
        $profile = array('profile_field' => 'Value');
        profile_save_profile($profile, $account, 'Profile Category');

        _user_mail_notify('register_admin_created', $account);
  • It may be better to post this as an edit to your question rather than an answer. – Jeremy French May 17 '11 at 12:05

Only users who have the permission of administer users can access pages that are associated with blocked accounts.

If you want to allow to the user who gets the email to access the page the link takes to, you would need to give permission to administer users to the anonymous user, as before to log in, the user who follows the link is an anonymous user. As this is highly not recommended, if you want that who gets the link is able to access the linked page, then you have to create the user account in the enabled status.

After all, as the user password has been set from the code, nobody knows the password (if you don't set a too easy one); it is perfectly useless to create a blocked account, considering that the user who needs to use it would not be able to use it, when it's blocked.

  • Thank you for the clarification. I understand the flow know. I thought that the user`s account will be unblocked by himself when confirming the e-mail address, but no, it's like you said. Now, the problem is, using _user_mail_notify I still get password: !password – sergio May 16 '11 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.