Form decortaor drush generator

Created on 30 May 2025, 7 days ago

Problem/Motivation

It would be nice to be able to generate a form decorator using drush generate.

πŸ“Œ Task
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡©πŸ‡ͺGermany Harlor Berlin

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Harlor
  • Merge request !15Init FormDecoratorGenerator β†’ (Open) created by Harlor
  • πŸ‡©πŸ‡ͺGermany Harlor Berlin
  • πŸ‡©πŸ‡ͺGermany Peter Majmesku πŸ‡©πŸ‡ͺDΓΌsseldorf

    The code looks good and is the common way to generate Drush commands in Drupal. Checked other Drush generate commands and it looks like the proper way to do it.

    I tried to do the same what I already have with the Drush generate command. The form decorator does not get applied. The following code was the generated result:

    
    declare(strict_types=1);
    
    namespace Drupal\ulf_tfa\FormDecorator;
    
    use Drupal\Core\Form\FormStateInterface;
    use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
    use Drupal\Core\Session\AccountProxyInterface;
    use Drupal\form_decorator\Attribute\FormDecorator;
    use Drupal\form_decorator\FormDecoratdorBase;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    /**
     * My form decorator.
     */
    #[FormDecorator('tfa_base_overview')]
    final class TfaBaseOverviewFormDecorator extends FormDecoratorBase implements ContainerFactoryPluginInterface {
    
      /**
       * The constructor.
       */
      public function __construct(
        array $configuration,
        $plugin_id,
        $plugin_definition,
        private readonly AccountProxyInterface $currentUser,
      ) {
        parent::__construct($configuration, $plugin_id, $plugin_definition);
      }
    
      /**
       * {@inheritdoc}
       */
      public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
        return new static(
          $configuration,
          $plugin_id,
          $plugin_definition,
          $container->get('current_user'),
        );
      }
    
      /**
       * {@inheritdoc}
       */
      public function buildForm(array $form, FormStateInterface $form_state, ...$args) {
        $form = $this->inner->buildForm($form, $form_state, ...$args);
    
        $form['disable_tfa'] = [
          '#type' => 'checkbox',
          '#title' => $this->t('Woohoo Disable Two-Factor Authentication'),
          '#description' => $this->t('By disabling two-factor authentication for your account, you won\'t be asked for two-factor authentication setup anymore. If you would like to re-enable it, you can do so in your user account settings.'),
          '#weight' => -10,
          '#default_value' => FALSE,
        ];
    
        return $form;
      }
    
      /**
       * {@inheritdoc}
       */
      public function validateForm(array &$form, FormStateInterface $form_state) {
        $this->inner->validateForm($form, $form_state);
        // Validate your magic
      }
    
    }
    
    

    Can you implement the

    applies()

    method for the generated class, too? That way the form decorator would be applied on the given form. That would be awesome. :)

  • πŸ‡©πŸ‡ͺGermany Harlor Berlin

    I'm not sure why the generated form decorator did not get applied. Can you give details what went wrong?

    Currently the applies method is added if the user does not choose a specific form_id or hook_form_alter equivalent. I mean we could just always generate the applied method. That would be fine for me.

  • πŸ‡©πŸ‡ͺGermany Peter Majmesku πŸ‡©πŸ‡ͺDΓΌsseldorf

    Form ID is "tfa_base_overview". I want that the form decorator decorates the form. It does not. If this can be somehow resolved with the applies method, that would be fine. I do not know how to implement that. If I add this method to the generated class, then the decorator is applied for any form.

      /**
       * {@inheritdoc}
       */
        public function applies(): bool {
          return TRUE;
        }
    
  • πŸ‡©πŸ‡ͺGermany Harlor Berlin

    Ah yeah - currently you would have to use:

    #[FormDecorator('tfa_base_overview_alter')]
    

    The background was that I thought it might be convenient when one can read the attribute just like the hook_form_alter:

    #[FormDecorator(hooK: 'tfa_base_overview_alter')]
    

    But I'm actually not really happy with that...

  • πŸ‡©πŸ‡ͺGermany Harlor Berlin
  • πŸ‡©πŸ‡ͺGermany Peter Majmesku πŸ‡©πŸ‡ͺDΓΌsseldorf

    I've double checked the form id like that:

    /**
     * Implements hook_form_alter().
     */
    function nice_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
      dump($form_id);
    }
    

    The dumped form id is:

    tfa_base_overview

    Then I've tried to change the FormDecorator attribute value:

    #[FormDecorator('tfa_base_overview_alter')]
    final class TfaBaseOverviewFormDecorator extends FormDecoratorBase implements ContainerFactoryPluginInterface {
    

    Unfortunately the form does not get applied.

    I need to implement this:

      /**
       * {@inheritdoc}
       */
        public function applies(): bool {
          return TRUE;
        }
    
  • πŸ‡©πŸ‡ͺGermany Harlor Berlin

    Sorry I meant:

    #[FormDecorator('form_tfa_base_overview_alter')]
    
  • πŸ‡©πŸ‡ͺGermany Harlor Berlin

    I think the interviewer could offer 3 options:

    1: Decorate a specific form ID
    2: Decorate a form based on a hook_form_FORM_ID_alter hook_form_alter...
    3: Use a custom applies method

Production build 0.71.5 2024