0

With some help I could create a route to an extended register form: as this form is an "entity form", my route have this type and the definition of this new form has been made in hook_entity_type_alter

The last part of the path of the route is a role name; and the user submitting this form (registering itself) should get this role.

Here is the code:

1-Extending the register form

class RegisterByRole extends RegisterForm
{
    public function form(array $form, FormStateInterface $form_state, $role = null)
    {
        $form = parent::form($form, $form_state);
        if ($role) {
            $form['test'] = [
                '#markup' => '<p>Test:' . $role
            ];
        }
        return $form;
    }
}

2-Adding a new entity form to the entity_type definition/annotation

function my_module_entity_type_alter(array &$entity_types) {
    $entity_types['user']->setFormClass('role_registration', 'Drupal\my_module\Form\RegisterByRole');
}

3-Creating the route

my_module.register:
  path: '/register/{role}'
  defaults:
    _entity_form: 'user.role_registration'
    _title: 'Register by role'
  requirements:
    _permission: 'access content'

Unfortunatly, the $role parameter is not transmitted...

1

With the help of 4k4 who have all the credit for this answer, I have created a controler which, in turn, build my register form (I no longer need to extend the register form). Before building the form, the controller must create a user and assign the role (coming from the parameter).

Here is the code

1-Create the route with rid as the parameter and a _controler key:

my_module.register:
  path: '/register/{rid}'
  defaults:
    _controller: '\Drupal\my_module\Controller\RegisterByRoleController::content'
    _title: 'Register by role'
  requirements:
    _permission: 'access content'    

2-Create the controller with rid as the parameter (src/Controller/...):

    public function content($rid=null) {

      $user_with_role = \Drupal\user\Entity\User::create();
      $roles = Role::loadMultiple();
      if ($rid && isset($roles[$rid])){
          $user_with_role->addRole($rid);
      }else{
          throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
      }

      $form = \Drupal::entityTypeManager()
      ->getFormObject('user', 'register')
      ->setEntity($user_with_role);

      $form_build=\Drupal::formBuilder()->getForm($form);

      //here is the trick I used to check the role
      $form_build['account']['roles'][$rid]['#checked']=TRUE;
      return $form_build;            
  }

Everything works well: the form is displayed, the rid is transmitted to the controller but the is still a problem:

The "transmitted" role's checkbox is not checked in the register form!

Any Hint?

I answer myself: it seems there is no way to achieve this "automatically", I will have to check "myself" the check boxes... see the last comment here: Default value for form entity

This is why is have added this line in the code $form_build['account']['roles'][$rid]['#checked']=TRUE;

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.