Skip to content
Snippets Groups Projects
LayoutBuilderIdsConfigureSection.php 5.23 KiB
Newer Older
Eric Bremner's avatar
Eric Bremner committed
<?php

namespace Drupal\layout_builder_ids\EventSubscriber;

use Drupal\Core\Form\FormStateInterface;
use Drupal\core_event_dispatcher\Event\Form\FormAlterEvent;
use Drupal\Core\StringTranslation\StringTranslationTrait;
Eric Bremner's avatar
Eric Bremner committed
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Drupal\layout_builder_ids\Service\LayoutBuilderIdsService;
Eric Bremner's avatar
Eric Bremner committed
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Component\Utility\Html;

/**
Eric Bremner's avatar
Eric Bremner committed
 * Add section id to layout builder sections.
Eric Bremner's avatar
Eric Bremner committed
 */
class LayoutBuilderIdsConfigureSection implements EventSubscriberInterface {

  use StringTranslationTrait;

  /**
   * Layout builder ids service.
   *
   * @var \Drupal\layout_builder_ids\Service\LayoutBuilderIdsService
   */
  protected $layoutBuilderIdsService;

  /**
   * Constructor for event subscriber for configure block.
   *
   * @param \Drupal\layout_builder_ids\Service\LayoutBuilderIdsService $layoutBuilderIdsService
   *   Layout builder ids service.
   */
  public function __construct(LayoutBuilderIdsService $layoutBuilderIdsService) {
    $this->layoutBuilderIdsService = $layoutBuilderIdsService;
  }

Eric Bremner's avatar
Eric Bremner committed
  /**
   * Alter form.
   *
   * @param \Drupal\core_event_dispatcher\Event\Form\FormAlterEvent $event
Eric Bremner's avatar
Eric Bremner committed
   *   The event.
   */
  public function alterForm(FormAlterEvent $event): void {
Eric Bremner's avatar
Eric Bremner committed

    // Get the form from the event.
    $form = &$event->getForm();

    // If we are on a configure section form, alter it.
    if ($form['#form_id'] == 'layout_builder_configure_section') {

      // These next two lines are needed until this issue gets fixed:
      // https://www.drupal.org/project/drupal/issues/3103812.
      // Once this issue gets fixed in core then we can use the
      // proper validate procedures.  Until then we need to add the
      // form id without the random value.
      $form_state = &$event->getFormState();
      $form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']);

Eric Bremner's avatar
Eric Bremner committed
      // Get the config for the section.
Eric Bremner's avatar
Eric Bremner committed
      $config = $event->getFormState()->getFormObject()->getLayout()->getConfiguration();
Eric Bremner's avatar
Eric Bremner committed

      // Add the section id to the configure form.
      $form['layout_settings']['layout_builder_id'] = [
        '#type' => 'textfield',
        '#title' => 'Section ID',
Eric Bremner's avatar
Eric Bremner committed
        '#default_value' => $config['layout_builder_id'] ?: NULL,
        '#description' => $this->t('Section ID is an optional setting which is used to support an anchor link to this block. For example, entering "feature" lets you link directly to this section by adding "#feature" to the end of the URL.</br>IDs should start with a letter, may only contain letters, numbers, underscores, hyphens, and periods, and should be unique on the page.'),
Eric Bremner's avatar
Eric Bremner committed
      ];

      // Add our custom submit handler.
      array_unshift(
        $form['#submit'],
        [
          $this,
          'layoutBuilderIdsConfigureSectionSubmitForm',
        ]
      );

      // Add the form validation for configure section.
      $form['#validate'][] = [
        $this,
        'layoutBuilderIdsConfigureSectionFormValidation',
      ];
    }
  }

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

    // Get the layout builder id from the form,
    // also put the id through the HTML getId to make sure
    // that we form a valid id.
    $layout_builder_id = Html::getId(
      $form_state->getValue(
        [
          'layout_settings',
          'layout_builder_id',
        ],
        NULL
      )
    );

    // Check if we have a duplicate id somewhere.
    $found_id = $this->layoutBuilderIdsService->layoutBuilderIdsCheckIds($layout_builder_id, $form_state, 'section');

    // If we have a duplicate id, then set the form error.
    if ($found_id) {

      // Set the form error on the layout builder id form element.
      $form_state->setError($form['layout_settings']['layout_builder_id'], 'There is already a block or section with the ID "' . $layout_builder_id . '".');
Eric Bremner's avatar
Eric Bremner committed
    }
  }

  /**
   * {@inheritdoc}
   */
  public function layoutBuilderIdsConfigureSectionSubmitForm(array &$form, FormStateInterface $form_state) {
Eric Bremner's avatar
Eric Bremner committed

    // Get the layout builder id from the form.
Eric Bremner's avatar
Eric Bremner committed
    $layout_builder_id = $form_state->getValue(
      [
        'layout_settings',
        'layout_builder_id',
      ],
      NULL
    );
Eric Bremner's avatar
Eric Bremner committed

    // If there is a layout builder id, store it.
    if ($layout_builder_id !== NULL) {

      // Get the layout.
      $layout = $this->getLayout($form_state);

      // Load in the config for this section.
      $configuration = $layout->getConfiguration();

      // Set the layout builder id in config variable.
      $configuration['layout_builder_id'] = Html::getId($layout_builder_id);

      // Set the config for this section.
      $layout->setConfiguration($configuration);
    }

  }

  /**
Eric Bremner's avatar
Eric Bremner committed
   * Get the layout object.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state object.
Eric Bremner's avatar
Eric Bremner committed
   */
  private function getLayout(FormStateInterface $form_state) {

    // Get the form object.
    $formObject = $form_state->getFormObject();

    return $formObject->getLayout();
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      HookEventDispatcherInterface::FORM_ALTER => 'alterForm',
    ];
  }
Eric Bremner's avatar
Eric Bremner committed

Eric Bremner's avatar
Eric Bremner committed
}