At the beginning of the "Krampus" weekend, which became famous in the rest of the world thanks to the movie, I show you, how to realize hiding the username and only use e-mail address in user registration and login instead in Drupal 8. We had to accomplish this yesterday in a current Drupal 8 project. Having only a few hours left to delivery date and still some open issues to solve, we needed a quick solution.

Unfortunately, the D8 version of the Email Registration module is currently not mature - having the last commit on the beginning of April let me fear that the functionality of the module is actually broken at the moment.However, instead of trying and patching the module, we came to the decision, that it would be enough to simply ensure that the username equals the e-mail address of each account. So our plan was easy enough: hide the username field from the registration form, add a custom validation and/or submit handler to set the username to the value of the entered e-mail address upon registration. That would satisfy our needs.

Pitfalls

Our first plan was to simply add a validation handler, that runs before all other validation handlers, in order to fill the username value before core raises a validation error. Unluckily for us, we soon saw, that D8 is built too solid for such dirty tricks.

If you add a custom validation handler at first position within user_register_form, a LogicException will be raised, as entity validation must always come first. After a bit of trying and researching we came to the decision, that the only way to succeed here, would be to set a temporary value to the username at first to satisfy the required constraint of the username, and then set the value after entity validation, but before saving the user account. With the help of the new Random utility class, this problem was solved within only a few lines of code:


/**
 * Implements hook_form_FORM_ID_alter() for user_register_form.
 */
function THEME_OR_MODULE_NAME_form_user_register_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['account']['name']['#access'] = FALSE;
  $random = new \Drupal\Component\Utility\Random();
  $form['account']['name']['#default_value'] = $random->name();

  array_unshift($form['actions']['submit']['#submit'], 'THEME_OR_MODULE_NAME_autofill_username_in_register_form');
}

/**
 * Custom submit callback for user_register_form.
 */
function THEME_OR_MODULE_NAME_autofill_username_in_register_form(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $mail = $form_state->getValue('mail');
  $form_state->setValue('name', $mail);
}

Conclusion

As you can see, this goal is very easy to achieve. However, if you need a 100% bullet proof solution, you'd need to take other scenarios also into account: what if the user wants to change his/her e-mail address? You can either disallow to change the address or you'd have to also change the username upon changing the e-mail address.

Update 9.12.2015

See the first comment from chx for a better solution: we could also hide the field from the form, but instead of the submit hook, use hook_entity_create() and hook_entity_presave() instead

Update 20.6.2016

Thanks to another great comment by Johannes Schmidt, there's another great alternative solution, which reads very nicely. So please give that a try: https://gist.github.com/johannez/161f8f488368c41f1d92aeb2245ece7f

Kommentare10

Klartext

  • Keine HTML-Tags erlaubt.
  • Zeilenumbrüche und Absätze werden automatisch erzeugt.
  • Website- und E-Mail-Adressen werden automatisch in Links umgewandelt.
Der Inhalt dieses Feldes wird nicht öffentlich zugänglich angezeigt.

chx

vor 8 years 4 months

This is a very Drupal 7 way!
This is a very Drupal 7 way! Instead you should use hook_user_entity_create to set the name and then hook_user_entity_presave to copy the value over.
thanks for the hint!

I haven't thought of this new hook at that moment.. but this sounds good - thanks!

makeonlineshop

vor 8 years 3 months

Logintobogan for drupal 8
Hello, I am still waiting for logintobogan for drupal 8 but the currect version is not working. Do you know any other module that could help ? Thanks.
what functionality do you need?

Logintoboggan offers several customizations of the login/registration process, including a quite ugly pre-styled form. What kind of feature do you need? As mentioned in the article, there's Email Registration as well, despite I doubt, that it's working as expected as well.

Johannes

vor 7 years 9 months

Alternative solution
Hallo Andreas, I was in a similar situation and needed something simple to allow login with the email address. Still those nice modules are not ready for Drupal 8 yet. However, I didn't want to replace the user name with the email all together and wanted to give the user the option to login with both. Hope you might find this useful until those modules are ready: https://gist.github.com/johannez/161f8f488368c41f1d92aeb2245ece7f Cheers, Johannes
nice alternative!

Thanks! That's really a nice solution. Will update my post and mention this!

hkauer

vor 6 years 9 months

The solution provided by chx
The solution provided by chx does not work because the value from the entity is only used in the form if the user is already logged in. I used your form_alter to fill the field. The second part with hook_user_presave() as suggested by chx works fine. I know this is a very old article and an old solution by chx. But maybe sometime also other people stumble upon the solution and have trouble to get it working.
thank you for your feedback

Well, you're right. This post is from 8.0.x days. Some things may have changed. I haven't needed this since then, so I don't have an opinion on that.

Have you looked at the solution provided by Johannes in the comments above (june 2016)? Never tried, but looks promising as well.

marco

vor 5 years 11 months

email_registration Module
https://www.drupal.org/project/email_registration does the job also.

Patrick Kenny

vor 3 years 1 month

For anyone coming here in
For anyone coming here in 2021, use the Email Registration module, not this code. Drupal exposes usernames by default, so unless you are extremely careful, if you use the code here you will leak the users' email addresses everywhere. For example, in json:api, simply going to the user endpoint will reveal all usernames.