Search code examples
phpsymfonydrupaldrupal-8drupal-forms

Drupal 8 custom registration form


I try to build a custom registration form which should be displayed in a custom block and I don't want to insert the normal registration form and alter it via a hook or use an extension like form_block, because I want to learn the ways how drupal 8 works with forms.

My block looks like this:

<?php

namespace Drupal\ajax_registration_form\Plugin\Block;

use Drupal\ajax_registration_form\Form\AjaxRegistrationForm;
use Drupal\Core\Block\BlockBase;

/**
 * Provides a 'AjaxRegistrationBlock' block.
 *
 * @Block(
 *  id = "ajax_registration_block",
 *  admin_label = @Translation("Ajax registration block"),
 * )
 */
class AjaxRegistrationBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {

    $content = \Drupal::formBuilder()->getForm(AjaxRegistrationForm::class);

    return $content;
  }

}

My custom registration form looks like this:

<?php

namespace Drupal\ajax_registration_form\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\user\RegisterForm;



class AjaxRegistrationForm extends RegisterForm {


  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {

    return parent::form($form, $form_state);
  }
}

I just tried to extend the normal RegisterForm and in the first step I just wanted to return the parent form to see if it works. But it doesn't...

Error message:

Fatal error: Call to a member function getEntityTypeId() on null in /Users/*******/Sites/priv/radweiser/web/core/lib/Drupal/Core/Entity/EntityForm.php on line 77

I think it's the missing user entity in the form, but I don't know how I can "put" this entity in my form.


Solution

  • I found the solution in the code of the formblock module.

    I altered my block to something like this:

    <?php
    
    namespace Drupal\ajax_registration_form\Plugin\Block;
    
    use Drupal\Core\Annotation\Translation;
    use Drupal\Core\Block\Annotation\Block;
    use Drupal\Core\Block\BlockBase;
    use Drupal\Core\Entity\EntityFormBuilderInterface;
    use Drupal\Core\Entity\EntityManagerInterface;
    use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
    use Drupal\Core\Session\AccountInterface;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    /**
     * Provides a 'AjaxRegistrationBlock' block.
     *
     * @Block(
     *  id = "ajax_registration_block",
     *  admin_label = @Translation("Ajax registration block"),
     * )
     */
    class AjaxRegistrationBlock extends BlockBase implements ContainerFactoryPluginInterface {
    
    
      /**
       * The entity manager
       *
       * @var \Drupal\Core\Entity\EntityManagerInterface.
       */
      protected $entityManager;
    
      /**
       * The entity form builder
       *
       * @var \Drupal\Core\Entity\EntityManagerInterface.
       */
      protected $entityFormBuilder;
    
      /**
       * Constructs a new UserRegisterBlock plugin
       *
       * @param array $configuration
       *   A configuration array containing information about the plugin instance.
       * @param string $plugin_id
       *   The plugin_id for the plugin instance.
       * @param mixed $plugin_definition
       *   The plugin implementation definition.
       * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager
       *   The entity manager.
       * @param \Drupal\Core\Entity\EntityFormBuilderInterface $entityFormBuilder
       *   The entity form builder.
       */
      public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entityManager, EntityFormBuilderInterface $entityFormBuilder) {
        parent::__construct($configuration, $plugin_id, $plugin_definition);
        $this->entityManager = $entityManager;
        $this->entityFormBuilder = $entityFormBuilder;
      }
    
      /**
       * @inheritdoc
       */
      public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
        return new static(
          $configuration,
          $plugin_id,
          $plugin_definition,
          $container->get('entity.manager'),
          $container->get('entity.form_builder')
        );
      }
    
    
      /**
       * Implements \Drupal\block\BlockBase::build().
       */
      public function build() {
        $build = array();
    
        $account = $this->entityManager->getStorage('user') ->create(array());
        $build['form'] = $this->entityFormBuilder->getForm($account, 'register');
    
        $build['form']['account']['mail']['#description'] = t('');
        kint($build['form']['account']);
    
        return $build;
      }
    
      /**
       *Implements \Drupal\block\BlockBase::blockAccess().
       *
       * @param \Drupal\Core\Session\AccountInterface $account
       *
       * @return bool|\Drupal\Core\Access\AccessResult
       */
      public function blockAccess(AccountInterface $account) {
        return ($account->isAnonymous()) && (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY);
      }
    
    }
    

    Now I can alter the form and implement ajax logic using the Form Api (alter the mail input description as example)