Good morning.

I am looking for a way to create a user account programmatically in Drupal 8.

If someone knows how to, please let me know.

Thank you.

Comments

thruthesky’s picture

$user = User::create([ ... ]);
$user->setPassword(...);
$user->enforceIsNew();
$user->set('...','....');
$user->save();
lguigo’s picture

thanks

rabithk’s picture

Can any one please share the code with example data for creating a new user in Drupal 8 by custom module .

rabithk’s picture

Example code for user registration :
$values = array(
'field_first_name' => 'Test First name',
'fieldt_last_name' => 'Test Last name',
'name' => 'test',
'mail' => 'test@test.com',
'roles' => array(),
'pass' => 'password',
'status' => 1,
);
$account = entity_create('user', $values);
$account->save();

creamfreash’s picture

In which file should I insert this code? and where the credentials are stored? How can I reach them ?

NuWans’s picture

creamfreash’s picture

In which file should I insert this code? and where the credentials are stored? How can I reach them ?

ryan.gibson’s picture

You would add this code into a custom module. Check here for more information on creating custom modules in Drupal 8.

The credentials for the user are stored in the users table of the database, but you'd access the user data by loading the user in code, not directly with a sql query.

creamfreash’s picture

Thanks a lot for your answer. Am I doing it right? I want to create some users, when the module is installed. So I inserted the code into my_module.install file in hook_install() function? Am I supposed to see newly created users inside of the box (People->List) after module installation? Or at least be able to log in the system with name and pass?

Because seems it doesn't work, maybe I should add some more code?

Shashwat Purav’s picture

The module code would help to understand the problem.

Thank You,
Shashwat Purav

creamfreash’s picture

Oh, sorry. I have used the above mentioned code in my my_module.install file

function my_module_install() {

$values = array(
'name' => 'test',
'mail' => 'test@test.com',
'pass' => 'password',
'status' => 1,
);
$account =
entity_create('user', $values);
$account->save();
return $account;

}

But after module installation nothing happens. The user is neither created and visible inside of the box, nor record in db is created.

creamfreash’s picture

Finally!!!

This worked for me

use Drupal\user\Entity\User;

function my_module_install() {

$user = User::create(array(
'name' => 'test',
'mail' => 'test@test.com',
'pass' => 'password',
'status' => 1,
));
$user -> save();

}

Shashwat Purav’s picture

Following code is tested to create new user programmatically using custom module.

<?php
/**
 * @file
 * Install file for MYMODULE module.
 */

/**
 * Implements hook_install.
 */
function MYMODULE_install() { 
  $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
      $user = \Drupal\user\Entity\User::create();

  //Mandatory settings
      $user->setPassword('test');
      $user->enforceIsNew();
      $user->setEmail('test@test.com');
      $user->setUsername('test'); //This username must be unique and accept only a-Z,0-9, - _ @ .

  //Optional settings
      $user->set("init", 'email');
      $user->set("langcode", $language);
      $user->set("preferred_langcode", $language);
      $user->set("preferred_admin_langcode", $language);
      //$user->set("setting_name", 'setting_value');
      $user->activate();

  //Save user
      $res = $user->save();
}

When you install your module, this code would create user "test" with password "test" and email "test@test.com". Flush and rebuild the cache and check "admin/people" for newly created user.

Thank You,
Shashwat Purav

jasom’s picture

In the case you wish to create more then one user account the code inside function MYMODULE_install() will looks like this:

$language = \Drupal::languageManager()->getCurrentLanguage()->getId();

$user = \Drupal\user\Entity\User::create();
//Mandatory settings
$user->setPassword('test');
$user->enforceIsNew();
$user->setEmail('test@test.com');
$user->setUsername('test');
//Optional settings
$user->activate();
//Save user
$res = $user->save();

$user = \Drupal\user\Entity\User::create();
//Mandatory settings
$user->setPassword('test2');
$user->enforceIsNew();
$user->setEmail('test2@test2.com');
$user->setUsername('test2');
//Optional settings
$user->activate();
//Save user
$res = $user->save();

Mervin McDougall’s picture

The above code works well for the most part. However, I have noticed for Drupal 8, Drupal does not enforce Uniqueness on the email field nor the username field in the database. Consequently, it will be necessary to do a check before creating the user otherwise you will result in multiple users having the same email address or possibly username. I encountered this issue while doing an import from an unsorted CSV where there were duplicate entries for users.  Including the following before creating the user should verify the account dosen't already exist

    if (user_load_by_mail($email) !== FALSE OR
        user_load_by_name($username) !== FALSE)
    {
      return;
    }

How you deal with the existence of a duplicate record is really up to you. You could update the record, save a record to watchdog, end the creation etc. Nevertheless a check needs to be put in place to avoid duplication of users.

lhridley’s picture

So, how would you create a user programmatically and suppress email notifications? We need to bulk create 1300 accounts and don't want emails going out to all of them.

Lisa Ridley
Product Manager / Tech Team Manager
PlanLeft LLC
https://www.planleft.com

rabithk’s picture

Hi Lisa,
Use the above comment code to create user programmatically, that will not trigger any email unless until you add code to sent email

If you want to send welcome email with out admin approval you can use
_user_mail_notify('register_no_approval_required', $user);
after user save

bitcookie’s picture

If you want to suppress account created emails, make sure the user's status field is set before you call the save method for the first time, and don't update it before consecutive calls to the save method.

_user_mail_notify is called every time a user is saved and the status is changed. So, just make sure that doesn't happen and it should not send.

It can also be useful to install something like the SMTP module, and disable it, to serve as another barrier for account created emails.

/*This will result in emails being sent*/

$account = User::create();
...
$account->save();

$account->set("status",1);
$account->save();

/*This will not send emails*/

$account = User::create();
...
$account->set("status",1);
$account->save();

$account->set("status",1);
$account->save();
leahtard’s picture

You can automatically set a password with the code below. This way, passwords are not in your codebase.

$user->setPassword(user_password());

Cheers, Leah

Cheers, Leah

robpowell’s picture

So this is cool but how does the end user get it to login? I am looking at something similar, create a user / password, and then send a one time login link.

dfdavis’s picture

This is a bit late but maybe useful to somebody:
Once the new user has been saved you can notify the them like this:

$user->save();
_user_mail_notify('register_admin_created',$user);
guptahemant’s picture

Hi
Can anyone suggest a way to also create a user profile programmatically after adding a user this way.

rabithk’s picture

For adding user profile fields :

use Drupal\user\Entity\User;

//Load user with user ID 
 $user = User::load($content['uid'];

//Update email Id
$user->setEmail($content['email']);

//Update username
$user->setUsername($content['email']);

//Update password reset 
    if (isset($content['password'])) {
      $user->setPassword($content['password']);
    }

//For User profile 
$user->set("field_first_name", isset($content['firstName']) ? $content['firstName'] : $user->field_first_name->value);
$user->set("field_last_name", isset($content['lastName']) ? $content['lastName'] : $user->field_last_name->value);

//Save user
$userss = $user->save();

//Where "$content" array contains all user profile data
guptahemant’s picture

thanks rabithk for your response.

nehajyoti’s picture

How to attach a new element to user object and update user object in D8 ?
I am using

$user = \Drupal::currentUser();
$user->save();

but gives - The d.8 page isn’t working . d.8 is currently unable to handle this request.

rabithk’s picture

Example of how to load current user and get out field data from user object.

// Load the current user.
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

// get field data from that user
$website = $user->get('field_website')->value;
$body = $user->get('body')->value;


$email = $user->get('mail')->value;
$name = $user->get('name')->value;
$uid= $user->get('uid')->value;
jeevav2011’s picture

// Load the current user.
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

// Get field data from that user.
$website = $user->get('field_website')->value;
$body = $user->get('body')->value;

// Some default getters include.
$email = $user->get('mail')->value;
$name = $user->get('name')->value;
$uid= $user->get('uid')->value;

nehajyoti’s picture

I need to set a new value. Something like $user->set("new_element"); $user->save();

rabithk’s picture

Yes . load the user , set the field value the same the user.

$user->set("field_first_name", isset($content['firstname']) ? $content['firstname'] : '');
//Save user
$users = $user->save();

nehajyoti’s picture

It gives me error as
InvalidArgumentException: Field field_first_name is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (line 474 of /Applications/MAMP/htdocs/drupal-8.0.x-dev/core/lib/Drupal/Core/Entity/ContentEntityBase.php).

rabithk’s picture

i just used an example "$user->set("field_first_name", "xyx"');" , you have to replace "field_first_name" with then field you want to change.

You can see the field MACHINE NAME inside "/admin/config/people/accounts/fields" page .

nehajyoti’s picture

What i need to do is, Create a custom form element on the login form and attach field to user object. So i need to set an element which is not a field already.

rabithk’s picture

I am not sure why you need a extra form field in user login form.

User Login form - In normal case we use to validate the user information that is already existing (Either with username or email ) , not to store user information .
We use "user registration form" to capture user profile information.
In Drupal 8 , you can create the field from admin login. if you do not want to display the field in user registration you can set "manage form display" to HIDDEN . This way it is easy to manage user entity.

sachinsuryavanshi’s picture

I want to create Role while enabling my Custom Module in D8.

How to achieve this?

Thanks

rabithk’s picture

use Drupal\user\Entity\User;

//Create a User
$user = User::create();
//Mandatory settings
$email = $form_state->getValue('mail');
$user->setPassword($form_state->getValue('pass'));
$user->enforceIsNew();
$user->setEmail($email);
$user->setUsername($email);//This username must be unique and accept only a-Z,0-9, - _ @ .
$user->activate();
$user->set('init', $email);

//Set Language
$language_interface = \Drupal::languageManager()->getCurrentLanguage();
$user->set('langcode', $language_interface->getId());
$user->set('preferred_langcode', $language_interface->getId());
$user->set('preferred_admin_langcode', $language_interface->getId());

//Adding default user roles

$userRolesArray = array(2,3);//role id
foreach ($userRolesArray as $key => $role) {
$user->addRole($role);
}

// Save has no return value so this cannot be tested.
// Assume save has gone through correctly.
$user1 = $user->save();

sachinsuryavanshi’s picture

Thanks, I have addedd Role with above chunk

figover’s picture

if you have role like Member, its machine name might be "member" , then use this machine name of the role instead of role id

vjsutar’s picture

use Drupal\user\Entity\User;

// Create user object.
$user = User::create();

//Mandatory settings
$user->setPassword("password");
$user->enforceIsNew();
$user->setEmail("email");
$user->setUsername("username"); //This username must be unique and accept only a-Z,0-9, - _ @ .
$user->addRole('role_name'); //E.g: authenticated
xangy’s picture

Anonymous or authenticated role ID must not be assigned manually.

Best,
Vishal Kumar

Gaurav_drupal’s picture

JeffC518’s picture

Thanks @rabithk for your responses on this topic. I was faced with a similar situation except I had to deal with a D6 -> D8 migration. The D6 site used the Profile module, so the fields were a bit different. I had a bunch of users that were in the DB, but many didn't have their profile information.

use Drupal\user\Entity\User;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryFactory;

use Drupal\membersonly\Iterator\LargeFile; // A custom class to handle C|T SV files

public function getUsers() {

	$this->loadCsvFile(); // loads fields from CSV from D6 site
	$fileData = $this->getRows(); // grabs rows of the data

        foreach ($fileData as $data) {
		$query = $this->queryFactory->get('user')
			->condition('mail', strtolower(trim($data['email'])), 'LIKE'); // UIDs do not match, use unique user mail field instead
		$result = $query->execute();
		if ( (count($result) && count($result) === 1) ) {
			$uid = current($result);

                        $user_object = User::load($uid);

			$db_email = $user_object->get('mail')->value;
			$db_profile_email = $user_object->get('profile_email_address')->value;
			$db_first_name = $user_object->get('profile_first_name')->value;
			$db_last_name = $user_object->get('profile_last_name')->value;

                        .... etc. 

                        $user_object->set('profile_first_name', $data['first_name']);
			$user_object->set('profile_last_name', $data['last_name']);
			$user_object->set('profile_address', $data['address']);

                        ... etc.

                        $status = $user_object->save(); // returns constant (1 = new, 2 = updated)
                }
        }
}

Notice the field names as profile_xxx_xxx instead of field_xxx_xxx. This was done quickly and isn't exactly terse, but it did the trick. Hope this might help someone.

jasonflaherty’s picture

//there was a d7 version of this codekarate had created a while back...

use Drupal\user\Entity\User;

$users = array(

'name'=>'email',
'name2'=>'email2',
...

);

foreach ($users as $name => $email) {
  //set up the user fields
    $user = User::create([
        'name' => $name,
        'mail' => $email,
        'pass' => user_password(),
        'status' => 1,
        'roles' => array('administrator'),
    ]);

    $user->save();
}

I looped through a user array like so...