How do I programmatically disable a form? 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(&amp;$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).





  


I would like to hide/remove Create new account too.
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

&lt;?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-&gt;isAnonymous() &amp;&amp; $user_settings-&gt;get('register') != USER_REGISTER_ADMINISTRATORS_ONLY)-&gt;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.