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
I haven't thought of this new hook at that moment.. but this sounds good - thanks!
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.
Thanks! That's really a nice solution. Will update my post and mention this!
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.