mercury_editor-2.0.x-dev/src/Element/MercuryEditorComponentOutline.php

src/Element/MercuryEditorComponentOutline.php
<?php

namespace Drupal\mercury_editor\Element;

use Drupal\Core\Template\Attribute;
use Drupal\mercury_editor\DialogService;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Render\Element\RenderElementBase;
use Drupal\mercury_editor\MercuryEditorTempstore;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\layout_paragraphs\LayoutParagraphsLayout;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\layout_paragraphs\LayoutParagraphsComponent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;

/**
 * Element that renders the Mercury Editor component outline.
 *
 * @RenderElement("mercury_editor_component_outline")
 */
class MercuryEditorComponentOutline extends RenderElementBase implements ContainerFactoryPluginInterface {

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    protected LayoutParagraphsLayoutTempstoreRepository $layoutParagraphsTempstore,
    protected EntityTypeManagerInterface $entityTypeManager,
    protected LayoutPluginManagerInterface $layoutPluginManager,
    protected RendererInterface $renderer,
    protected EntityTypeBundleInfoInterface $entityTypeBundleInfo,
    protected MercuryEditorTempstore $tempstore,
    protected DialogService $dialogSettings,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('layout_paragraphs.tempstore_repository'),
      $container->get('entity_type.manager'),
      $container->get('plugin.manager.core.layout'),
      $container->get('renderer'),
      $container->get('entity_type.bundle.info'),
      $container->get('mercury_editor.tempstore_repository'),
      $container->get('mercury_editor.dialog'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    return [
      '#entity' => NULL,
      '#pre_render' => [
        [$this, 'preRender'],
      ],
      '#attributes' => [
        'class' => [
          'me-component-outline',
        ],
      ],
    ];
  }

  /**
   * Pre-render callback: renders the outline.
   *
   * @param array $element
   *   The render array for the element.
   *
   * @return array
   *   The render array for the element.
   */
  public function preRender(array $element) {
    $entity = $element['#entity'];
    $element['#type'] = 'container';
    // $element['#attached']['library'][] = 'mercury_editor/component_outline';
    $element['components'] = [];

    if ($entity) {
      $ids = $this->tempstore->getLayoutParagraphsFieldIds($entity);
      foreach ($ids as $id) {
        $layout = $this->layoutParagraphsTempstore->getWithStorageKey($id);
        $field_name = $layout->getFieldName();
        $field_definition = $entity->getFieldDefinition($field_name);
        $label = $field_definition->getLabel() ?: $field_name;
        $element['component-tree'][] = [
          '#type' => 'component',
          '#component' => 'mercury_editor:component-outline',
          '#props' => [
            'items' => $this->componentTree($layout, $layout->getRootComponents()),
            'mercury_editor_id' => $entity->uuid(),
            'layout_id' => $layout->id(),
            'field_label' => $label,
            'attributes' => new Attribute([
              'data-mercury-editor-id' => $entity->uuid(),
              'data-layout-id' => $layout->id(),
            ]),
          ],
        ];
      }
    }
    return $element;
  }

  /**
   * Builds a tree structure of components and their children.
   *
   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout
   *   The layout to render.
   * @param array $components
   *   A list of components to process.
   *
   * @return array
   *   A hierarchical array representing the component tree.
   */
  protected function componentTree(
    LayoutParagraphsLayout $layout,
    array $components,
  ) {
    $items = [];
    /** @var \Drupal\layout_paragraphs\LayoutParagraphsComponent $component */
    foreach ($components as $component) {
      $entity = $component->getEntity();
      $label = $this->getBundleLabel($entity);
      if ($component->isLayout()) {
        $section = $layout->getLayoutSection($entity);
        $layout_plugin_id = $section->getLayoutId();
        $definition = $this->layoutPluginManager->getDefinition($layout_plugin_id);
        $label .= ' - ' . $definition->getLabel();
      }
      $attributes = new Attribute([
        'data-uuid' => $component->getEntity()->uuid(),
        'data-type' => $entity->bundle(),
        'data-is-layout' => $component->isLayout() ? 'true' : 'false',
      ]);
      if ($component->isLayout()) {
        $attributes->setAttribute('data-layout', $layout_plugin_id);
      }
      $item = [
        'id' => $component->getEntity()->uuid(),
        'entity' => $component->getEntity(),
        'type' => 'component',
        'data-type' => $entity->bundle(),
        'parent_uuid' => $component->getParentUuid(),
        'sibling_uuid' => $component->getEntity()->uuid(),
        'region_id' => $component->getRegion(),
        'is_layout' => $component->isLayout(),
        'label' => $label,
        'attributes' => $attributes,
      ];
      if ($component->isLayout()) {
        $item['children'] = $this->layoutRegions($component, $layout);
      }
      $items[] = $item;
    }
    return $items;
  }

  /**
   * Processes layout regions to include in the component tree.
   *
   * @param \Drupal\layout_paragraphs\LayoutParagraphsComponent $component
   *   The component to process.
   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout
   *   The layout to process.
   *
   * @return array
   *   A list of regions with their components.
   */
  protected function layoutRegions(LayoutParagraphsComponent $component, LayoutParagraphsLayout $layout) {
    $section = $layout->getLayoutSection($component->getEntity());
    $layout_plugin_id = $section->getLayoutId();
    $definition = $this->layoutPluginManager->getDefinition($layout_plugin_id);
    $regions = $definition->getRegions();

    $items = [];
    foreach ($regions as $id => $region) {
      $components = $section->getComponentsForRegion($id);
      $items[] = [
        'id' => $id,
        'region_id' => $id,
        'parent_uuid' => $component->getEntity()->uuid(),
        'sibling_uuid' => '',
        'type' => 'region',
        'label' => $region['label'],
        'children' => $this->componentTree($layout, $components),
        'attributes' => new Attribute([
          'data-region' => $id,
        ]),
      ];
    }
    return $items;

  }

  /**
   * Get the bundle label for the entity.
   *
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity to get the bundle label for.
   *
   * @return string|null
   *   The bundle label, or NULL if the entity does not have a bundle.
   */
  protected function getBundleLabel($entity) {
    $entity_type_id = $entity->getEntityTypeId();
    $bundle = $entity->bundle();
    $bundle_entity_type = \Drupal::entityTypeManager()
      ->getDefinition($entity_type_id)
      ->getBundleEntityType();

    if ($bundle_entity_type) {
      $bundle_entity = \Drupal::entityTypeManager()
        ->getStorage($bundle_entity_type)
        ->load($bundle);
      return $bundle_entity ? $bundle_entity->label() : NULL;
    }

    return NULL;
  }

}

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

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