3

I want disable the user register form depending some conditions. The user go to the "/user/register" page, and he must see 'Registration is disable because ...'.

From my "form_user_register_form_alter" hook, I don't find anywhere how can I disable all the form programmatically (I mean removing all fields form). I think I can unset all form elements, but I feel that is an ugly way.

Is there a method (from the FormStateInterface class) or a Drupal function (for the form variable) to properly disable the form?

This is my most recent tentative.

function mycustommodule_limit_form_user_register_form_alter(&$form, FormStateInterface $form_state){
  if (...) {
    $form['#access'] = FALSE; // Drupal 7 (ugly?) way
    drupal_set_message('This form is disable because...');
  }
}

When I go to the /user/register form, the form is disable ! but I get this error.

Notice: Undefined index: #markup in Drupal\Core\Render\RenderCache->getCacheableRenderArray() (line 323 of core/lib/Drupal/Core/Render/RenderCache.php).

screenshot

I would like to hide/remove Create new account too.

3 Answers 3

3

The D8 way to do this is to write a custom access check.

This is the one which now checks the access for the user register form:

src/Access/RegisterAccessCheck.php

<?php

namespace Drupal\user\Access;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Access check for user registration routes.
 */
class RegisterAccessCheck implements AccessInterface {

  /**
   * Checks access.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The currently logged in account.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(AccountInterface $account) {
    $user_settings = \Drupal::config('user.settings');
    return AccessResult::allowedIf($account->isAnonymous() && $user_settings->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY)->cacheUntilConfigurationChanges($user_settings);
  }

}

user.services.yml

services:
  access_check.user.register:
    class: Drupal\user\Access\RegisterAccessCheck
    tags:
      - { name: access_check, applies_to: _access_user_register }

user.routing.yml

user.register:
  path: '/user/register'
  defaults:
    _entity_form: 'user.register'
    _title: 'Create new account'
  requirements:
    _access_user_register: 'TRUE'

Put these files in a module and change user to mymodule and choose a custom class name.

To successfully override the route in mymodule.routing.yml you have to adjust the module weight. Or instead change the access settings of the existing route in a RouteSubscriber, which is a bit more work to do, but the better solution.

2
  • There isn't a simplest way haha ? Thank for your detailed answer, Ill try that ;) Commented Dec 4, 2016 at 16:38
  • This answer is pretty good and should be the most voted one. Please consider upvoting it as it provides valuable information.
    – jbarrio
    Commented Mar 22, 2021 at 10:00
3

A simple way to do it in Drupal 8 hook_form_alter:

$form = [
  '#parents' => [],
  '#markup' => t('Access Denied.'),
];

If you have errors with the above solution, you can try to modify an existing form:

  $form['#access'] = FALSE;
  $form['#markup'] = t('Access Denied.');
  $form['#cache'] = [
    'contexts' => [],
    'max-age' => 0,
  ];
1
  • Not sure why the first method would throw errors but it worked for me. Thanks
    – JFC
    Commented Sep 4, 2020 at 2:42
-1

You can create a form template and show a form or some markup according to some conditions. In your_theme.theme or your_module.module file add this:

/**
 * Implements hook_theme().
 */
function your_theme_theme($existing, $type, $theme, $path) {
  $theme = array('user_register_form' =>
          array(
    'render element' => 'form',
    'path' => drupal_get_path('theme', 'your_theme') . '/templates',
    'template' => 'user-register-form'
  ));
}

Create user-register-form.html.twig.

Define some condition (it is just for example as i don't know how and what condition you want to add) in hook_form_FORM_ID_alter

function your_theme_form_YOUR_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($some_variable == 'some condition') {
       $form['condition'] = TRUE;
   }

}

In your template file:

{% if form.condition %}

<p>Registration is disable because ..</p>

{% else %}
   {{ form.some_field_1 }} 
   {{ form.some_field_2 }} 
   {{ form }}
{% endif %}
1
  • You shouldn't be altering functionality at the theme layer.
    – colan
    Commented Feb 2, 2023 at 15:47

Your Answer

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

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