2

Drupal core 8.6.5

I am trying to change the user registration process to omit the username field and generate the username from the first name and last name.

Since I am new to Drupal and want to learn more I try to go without project modules for that task.

So far I set up a custom module and deactivated the username field. Now I should set a default value for it.

How can I set the username built of first name and last name before the process is going on?
And strip some blanks, unallowed characters, ...

I was thinking of hooking into function user_validate_name Is that possible?

My module so far:

<?php
use \Drupal\Core\Form\FormStateInterface;

/**
* Implements hook_form_FORM_ID_alter().
*/
function my_register_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id)
{   
    $form['account']['name']['#access'] = FALSE;
    $form['account']['name']['#default_value'] ='tbd'; und 
}

Thanks for your help!

2 Answers 2

2

This is an interesting case in Drupal 8. Previously we could look at the user registration form's validation processes, which in Form API were callback strings in the #validate property array (or attached to each element in the #element_validate property. Note that the Drupal term "element property" means an item in a form array prefixed with a "#".

A basic strategy is similar: alter the form's #validate property and add, not replace, a string referencing a valid PHP callable. Again, probably best to re-order validate callbacks for first-in, first-out.

// Probably best to add this as the first element of #validate
$form['#validate'][] = 'my_register_form_validate';

Then implement the function or callable.

function my_register_form_validate($form, FormStateInterface $formState) {
  // This should do the trick.
  $formState->setValue('name', $name);
  // But you might need to get the entity from form state storage?
}

But we also need to make sure that the user account form doesn't let you change user name, of it does, then add the same validation/form alter.

In Drupal 8, entities often have their properties validated not in the form but as part of Symfony Constraints as part of their Typed Data data definition. This is so that Drupal is more API-first rather than form-driven (like in Drupal 7).

So I think you're on the right track to look kind of into user_validate_name, but it appears to be unused except in the installer. I think that modifying the entity's base field definition and adding a new constraint would work too.

To do this implement hook_entity_base_field_info_alter. Also see the following question How to easily alter an entitys base field definition per bundle?.

function my_register_form_entity_base_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) {
  if ($entity_type->id() === 'user') {
    $fields['name']->getConstraints()
  }
}

Then implement a Constraint plugin and its corresponding ConstraintValidator class. The ConstraintValidator class might have a validate method like this:

public function validate($items, Constraint $constraint) {
  // The entity should be available on all fields as a parent typed data via FieldItemListInterface::getEntity method
  $entity = $items->getEntity();
  // Generate user name as say $name.
  $items->set($name);
}
0
1

Thanks for your help. Worked great for me.

I have already deactivated the possibility to change the username. If lastname changes (e.g. marriage) I want to keep the username.

<?php
use \Drupal\Core\Form\FormStateInterface;

/**
* Implements hook_form_FORM_ID_alter().
*/
function my_register_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
    $form['account']['name']['#access'] = FALSE;
    $form['account']['name']['#default_value'] = 'tbd';
    array_unshift($form['#validate'],'my_register_form_validate');

}

function my_register_form_validate($form, FormStateInterface $formState)
{
    $firstname = $formState->getValue('field_firstname');
    $lastname = $formState->getValue('field_lastname');
    $name = $firstname[0]['value'].$lastname[0]['value'];
    $formState->setValue('name', $name);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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