display_builder-1.0.x-dev/src/Plugin/display_builder/Island/BlockLibraryPanel.php

src/Plugin/display_builder/Island/BlockLibraryPanel.php
<?php

declare(strict_types=1);

namespace Drupal\display_builder\Plugin\display_builder\Island;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\display_builder\Attribute\Island;
use Drupal\display_builder\IslandPluginBase;
use Drupal\display_builder\IslandType;
use Drupal\ui_patterns_overrides\SourcesBundlerInterface;

/**
 * Block library island plugin implementation.
 */
#[Island(
  id: 'block_library',
  label: new TranslatableMarkup('Blocks library'),
  description: new TranslatableMarkup('List of available Drupal blocks to use.'),
  type: IslandType::Library,
)]
class BlockLibraryPanel extends IslandPluginBase {

  private const HIDE_BLOCK = [
    'help_block',
    'system_messages_block',
    'htmx_loader',
    'broken',
    'system_main_block',
    'page_title_block',
  ];

  private const HIDE_SOURCE = [
    'block',
    'component',
  ];

  /**
   * {@inheritdoc}
   */
  public function label(): string {
    return 'Blocks';
  }

  /**
   * {@inheritdoc}
   */
  public function build(string $builder_id, array $data, array $options = []): array {
    $source_contexts = $this->configuration['contexts'] ?? [];

    $sources = $this->sourceManager->getDefinitionsForPropType('slot', $source_contexts);
    /** @var \Drupal\ui_patterns_overrides\SourcesBundlerInterface $block_source */
    $block_source = $this->sourceManager->createInstance('block', $this->configuration);

    return [
      $this->buildOtherSources($builder_id, $sources),
      $this->buildDrupalBlocks($builder_id, $block_source),
    ];
  }

  /**
   * Build other sources.
   *
   * @param string $builder_id
   *   Builder ID.
   * @param array $sources
   *   Array of source definitions.
   *
   * @return array
   *   Render array for the other sources section.
   */
  protected function buildOtherSources(string $builder_id, array $sources): array {
    $placeholders = [];

    foreach ($sources as $source_id => $definition) {
      if (\in_array($source_id, self::HIDE_SOURCE, TRUE)) {
        continue;
      }
      $data = [
        'source_id' => $source_id,
      ];
      $keywords = \sprintf('%s %s %s', $definition['id'], $definition['label'] ?? '', $definition['description'] ?? '');
      $build = $this->buildPlaceholderButton($definition['label'], $data, $keywords);
      $placeholders[] = $build;
    }

    return $this->buildDraggables($builder_id, $placeholders);
  }

  /**
   * Get Drupal block plugins.
   *
   * @param string $builder_id
   *   Builder ID.
   * @param \Drupal\ui_patterns_overrides\SourcesBundlerInterface $block_source
   *   The block source to build.
   *
   * @return array
   *   Array of block plugins, keyed by block ID with admin label as value.
   */
  protected function buildDrupalBlocks(string $builder_id, SourcesBundlerInterface $block_source): array {
    $definitions = $block_source->getOptions();
    $names = array_column($definitions, 'admin_label');
    array_multisort($names, \SORT_ASC, $definitions);
    $views_blocks = [];
    $menu_blocks = [];
    $other_blocks = [];

    foreach ($definitions as $block_id => $definition) {
      if (str_starts_with($block_id, 'views_block:')) {
        $views_blocks[$block_id] = $definition;
      }
      elseif (str_starts_with($block_id, 'system_menu_block:')) {
        $menu_blocks[$block_id] = $definition;
      }
      else {
        $other_blocks[$block_id] = $definition;
      }
    }
    $build = [
      $views_blocks ? $this->buildDrupalBlocksGroup($builder_id, $this->t('List (Views)'), $views_blocks, $block_source) : [],
      $menu_blocks ? $this->buildDrupalBlocksGroup($builder_id, $this->t('Menus'), $menu_blocks, $block_source) : [],
      $other_blocks ? $this->buildDrupalBlocksGroup($builder_id, $this->t('Others'), $other_blocks, $block_source) : [],
    ];
    $build = $this->buildDraggables($builder_id, $build);
    $build['#source_contexts'] = $this->configuration['contexts'] ?? [];

    return $build;
  }

  /**
   * Build a group of block placeholders.
   *
   * @param string $builder_id
   *   Builder ID.
   * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $title
   *   The group title.
   * @param array $definitions
   *   Block plugin definitions.
   * @param \Drupal\ui_patterns_overrides\SourcesBundlerInterface $block_source
   *   The block source to build.
   *
   * @return array
   *   A renderable array.
   */
  protected function buildDrupalBlocksGroup(string $builder_id, string|TranslatableMarkup $title, array $definitions, SourcesBundlerInterface $block_source): array {
    $build = [
      [
        '#type' => 'html_tag',
        '#tag' => 'h4',
        // We hide the group titles on search.
        '#attributes' => ['class' => 'db-filter-hide-on-search'],
        '#value' => $title,
      ],
    ];

    foreach ($definitions as $block_id => $definition) {
      if ($definition['provider'] === 'ui_patterns_blocks') {
        continue;
      }

      if (\in_array($block_id, self::HIDE_BLOCK, TRUE)) {
        continue;
      }
      $data = $block_source->getDataSkeleton($block_id);
      $keywords = \sprintf('%s %s %s', $definition['id'], $definition['admin_label'] ?? '', $definition['category'] ?? '');
      $block_preview_url = Url::fromRoute('display_builder.api_block_preview', ['block_id' => $block_id]);
      $build[] = $this->buildPlaceholderButtonWithPreview($builder_id, $definition['admin_label'], $data, $block_preview_url, $keywords);
    }

    return $build;
  }

}

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

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