lb_plus-1.0.x-dev/src/Controller/DuplicateBlock.php

src/Controller/DuplicateBlock.php
<?php

namespace Drupal\lb_plus\Controller;

use Drupal\layout_builder\Section;
use Drupal\lb_plus\LbPlusRebuildTrait;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\lb_plus\SectionStorageHandler;
use Drupal\Core\Controller\ControllerBase;
use Drupal\layout_builder\SectionComponent;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\layout_builder\SectionStorageInterface;
use Drupal\layout_builder\Plugin\Block\InlineBlock;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
 * Returns responses for Layout Builder + routes.
 */
class DuplicateBlock extends ControllerBase {

  use LbPlusRebuildTrait;

  protected UuidInterface $uuid;
  protected LayoutPluginManagerInterface $layout;
  protected EventDispatcherInterface $eventDispatcher;
  protected PluginManagerInterface $pluginManagerBlock;
  protected SectionStorageHandler $sectionStorageHandler;
  protected LayoutTempstoreRepositoryInterface $tempstoreRepository;

  public function __construct(LayoutTempstoreRepositoryInterface $tempstore_repository, SectionStorageHandler $section_storage_handler, LayoutPluginManagerInterface $layout, PluginManagerInterface $plugin_manager_block, EventDispatcherInterface $event_dispatcher, UuidInterface $uuid) {
    $this->sectionStorageHandler = $section_storage_handler;
    $this->tempstoreRepository = $tempstore_repository;
    $this->pluginManagerBlock = $plugin_manager_block;
    $this->eventDispatcher = $event_dispatcher;
    $this->layout = $layout;
    $this->uuid = $uuid;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('layout_builder.tempstore_repository'),
      $container->get('lb_plus.section_storage_handler'),
      $container->get('plugin.manager.core.layout'),
      $container->get('plugin.manager.block'),
      $container->get('event_dispatcher'),
      $container->get('uuid')
    );
  }

  /**
   * Duplicate's a block.
   */
  public function duplicate(SectionStorageInterface $section_storage = NULL, $delta = NULL, $region = NULL, $uuid = NULL, $nested_storage_path = NULL) {
    $current_section_storage = $this->sectionStorageHandler->getCurrentSectionStorage($section_storage, $nested_storage_path);
    $section = $current_section_storage->getSection($delta);
    $component = $section->getComponent($uuid);
    $block_plugin = $component->getPlugin();
    $configuration = $block_plugin->getConfiguration();
    $this->cloneBlock($block_plugin, $configuration);

    // Place the cloned block next to the original.
    $cloned_component = new SectionComponent($this->uuid->generate(), $region, ['id' => $block_plugin->getPluginId()], $component->get('additional'));
    $cloned_component->setConfiguration($configuration);
    $section->insertAfterComponent($component->getUuid(), $cloned_component);
    $section_storage = $this->sectionStorageHandler->updateSectionStorage($section_storage, $nested_storage_path, $current_section_storage);

    return $this->rebuildAndClose($section_storage, $nested_storage_path);
  }

  /**
   * Clone block.
   *
   * Recursively traverses nested layouts and clones blocks and then updates
   * the plugin configuration.
   *
   * @param \Drupal\Core\Block\BlockPluginInterface $block_plugin
   *   The block plugin to clone.
   * @param array $configuration
   *   The plugin configuration.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\TypedData\Exception\ReadOnlyException
   */
  public function cloneBlock(BlockPluginInterface $block_plugin, array &$configuration) {
    if ($block_plugin instanceof InlineBlock) {
      // Create a block_content clone.
      $block_content = $this->sectionStorageHandler->getBlockContent($block_plugin);
      $cloned_block_content = $block_content->createDuplicate();
      if ($this->sectionStorageHandler->isLayoutBlock($block_plugin)) {
        // Duplicate all the nested entities within the layouts.
        $cloned_sections = [];
        foreach ($block_content->layout_builder__layout->getSections() as $delta => $original_section) {
          $cloned_sections[$delta] = $this->cloneSection($original_section);
        }
        $block_content->layout_builder__layout->setValue($cloned_sections);
      }
      $configuration['block_serialized'] = serialize($cloned_block_content);
    }
  }

  /**
   * Clone section.
   *
   * @param \Drupal\layout_builder\Section $section
   *   The section to clone.
   *
   * @return \Drupal\layout_builder\Section
   *   The deep cloned section.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\TypedData\Exception\ReadOnlyException
   */
  public function cloneSection(Section $section) {
    $components = $section->getComponents();
    foreach ($components as $uuid => $component) {
      $block_plugin = $component->getPlugin();
      $configuration = $block_plugin->getConfiguration();
      $this->cloneBlock($block_plugin, $configuration);

      // Replace the component with the cloned one.
      $cloned_component = new SectionComponent($this->uuid->generate(), $component->getRegion(), ['id' => $block_plugin->getPluginId()], $component->get('additional'));
      $cloned_component->setConfiguration($configuration);
      $section->insertAfterComponent($uuid, $cloned_component);
      $section->removeComponent($uuid);
    }

    return $section;
  }

}

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

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