block_editor-1.0.x-dev/src/Hook/ThemeHooks.php

src/Hook/ThemeHooks.php
<?php

namespace Drupal\block_editor\Hook;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\block_editor\Service\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Theme-related hooks for Block Editor.
 */
class ThemeHooks implements ContainerInjectionInterface {

  /**
   * The current route match.
   */
  protected RouteMatchInterface $routeMatch;

  /**
   * The Block Editor entity manager.
   */
  protected EntityManager $entityManager;

  /**
   * Constructs a new ThemeHooks instance.
   */
  public function __construct(RouteMatchInterface $route_match, EntityManager $entity_manager) {
    $this->routeMatch = $route_match;
    $this->entityManager = $entity_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('current_route_match'),
      $container->get('block_editor.entity_manager')
    );
  }

  /**
   * Implements hook_theme().
   *
   * Registers Block Editor form template.
   */
  #[Hook('theme')]
  public function theme(): array {
    return [
      'block_editor_form' => [
        'render element' => 'form',
        'template' => 'form--block-editor',
      ],
    ];
  }

  /**
   * Implements hook_theme_suggestions_page_alter().
   *
   * Adds Block Editor theme suggestions for edit and add form pages.
   */
  #[Hook('theme_suggestions_page_alter')]
  public function themeSuggestionsPageAlter(array &$suggestions, array $variables): void {
    $route_name = $this->routeMatch->getRouteName();

    // Check if this is a Block Editor route.
    if (!$route_name || !str_starts_with($route_name, 'block_editor.entity.')) {
      return;
    }

    // Extract entity type and bundle information.
    $info = $this->extractEntityInfo();
    if (!$info) {
      return;
    }

    ['entity_type_id' => $entity_type_id, 'bundle' => $bundle] = $info;

    // Add theme suggestions in order of specificity (least to most specific).
    // Most specific suggestions should be added last.
    $new_suggestions = [
      'page__block_editor',
      'page__' . $entity_type_id . '__block_editor',
      'page__' . $bundle . '__' . $entity_type_id . '__block_editor',
    ];

    // Insert before the last suggestion to maintain proper priority.
    array_splice($suggestions, -1, 0, $new_suggestions);
  }

  /**
   * Implements hook_theme_suggestions_html_alter().
   *
   * Adds Block Editor theme suggestions for HTML wrapper.
   */
  #[Hook('theme_suggestions_html_alter')]
  public function themeSuggestionsHtmlAlter(array &$suggestions, array $variables): void {
    $route_name = $this->routeMatch->getRouteName();

    // Check if this is a Block Editor route.
    if (!$route_name || !str_starts_with($route_name, 'block_editor.entity.')) {
      return;
    }

    // Extract entity type and bundle information.
    $info = $this->extractEntityInfo();
    if (!$info) {
      return;
    }

    ['entity_type_id' => $entity_type_id, 'bundle' => $bundle] = $info;

    // Add theme suggestions in order of specificity.
    $new_suggestions = [
      'html__block_editor',
      'html__' . $entity_type_id . '__block_editor',
      'html__' . $bundle . '__' . $entity_type_id . '__block_editor',
    ];

    // Insert before the last suggestion to maintain proper priority.
    array_splice($suggestions, -1, 0, $new_suggestions);
  }

  /**
   * Implements hook_theme_suggestions_block_editor_form_alter().
   *
   * Adds entity type and bundle-specific theme suggestions for Block Editor
   * forms.
   */
  #[Hook('theme_suggestions_block_editor_form_alter')]
  public function themeSuggestionsBlockEditorFormAlter(array &$suggestions, array $variables): void {
    // Get form element.
    $form = $variables['form'] ?? [];

    // Get entity type and bundle from form attributes.
    $entity_type_id = $form['#block_editor_entity_type'] ?? NULL;
    $bundle = $form['#block_editor_bundle'] ?? NULL;

    if (!$entity_type_id || !$bundle) {
      return;
    }

    // Add theme suggestions in order of specificity.
    $suggestions[] = 'form__block_editor';
    $suggestions[] = 'form__' . $entity_type_id . '__block_editor';
    $suggestions[] = 'form__' . $bundle . '__' . $entity_type_id . '__block_editor';
  }

  /**
   * Extracts entity type and bundle information from the current route.
   *
   * Works for both add and edit forms.
   *
   * @return array|null
   *   Array with 'entity_type_id' and 'bundle' keys, or NULL if not found.
   */
  protected function extractEntityInfo(): ?array {
    // For edit forms, the entity is already loaded.
    foreach ($this->routeMatch->getParameters() as $parameter) {
      if ($parameter instanceof ContentEntityInterface) {
        return [
          'entity_type_id' => $parameter->getEntityTypeId(),
          'bundle' => $parameter->bundle(),
        ];
      }
    }

    // For add forms, we need to get the entity type from the route.
    $route_name = $this->routeMatch->getRouteName();

    // Extract entity type from route name.
    // Pattern: block_editor.entity.{entity_type}.add_form or edit_form.
    if (preg_match('/^block_editor\.entity\.([^.]+)\.(add_form|edit_form)$/', $route_name, $matches)) {
      $entity_type_id = $matches[1];

      // For add forms, we need to get the bundle from route parameters.
      // Get the bundle parameter mapping from the entity manager's
      // configuration.
      $bundle_parameter_mapping = $this->entityManager->getSupportedEntityTypeMappings();

      if (isset($bundle_parameter_mapping[$entity_type_id])) {
        $bundle_param_name = $bundle_parameter_mapping[$entity_type_id];
        $bundle_id = $this->routeMatch->getParameter($bundle_param_name);

        if ($bundle_id) {
          return [
            'entity_type_id' => $entity_type_id,
            'bundle' => is_string($bundle_id) ? $bundle_id : $bundle_id->id(),
          ];
        }
      }
    }

    return NULL;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc