layout_builder_kit-8.x-1.x-dev/src/Plugin/Block/LBKTab/LBKTab.php

src/Plugin/Block/LBKTab/LBKTab.php
<?php

namespace Drupal\layout_builder_kit\Plugin\Block\LBKTab;

use Drupal\block\Entity\Block;
use Drupal\block_content\Entity\BlockContent;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityTypeBundleInfo;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Plugin\DataType\ConfigEntityAdapter;
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
use Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage;
use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
use Drupal\layout_builder_kit\Plugin\Block\LBKBaseComponent;
use Drupal\node\Entity\Node;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a 'LBKTab' block.
 *
 * @Block(
 *  id = "lbk_tab",
 *  admin_label = @Translation("Tab (LBK)"),
 * )
 */
class LBKTab extends LBKBaseComponent implements ContainerFactoryPluginInterface {

  /**
   * Drupal\Core\Entity\EntityTypeManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Drupal\Core\Config\ConfigManagerInterface definition.
   *
   * @var \Drupal\Core\Config\ConfigManagerInterface
   */
  protected $configManager;

  /**
   * Drupal\Core\Routing\CurrentRouteMatch class.
   *
   * @var \Drupal\Core\Routing\CurrentRouteMatch
   */
  protected $currentRouteMatch;

  /**
   * Drupal\Core\Extension\ModuleHandlerInterface class.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * Drupal\Core\Entity\EntityFieldManager class.
   *
   * @var \Drupal\Core\Entity\EntityFieldManager
   */
  protected $entityFieldManager;

  /**
   * Drupal\Core\Entity\EntityTypeBundleInfo class.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfo
   */
  protected $entityTypeBundleInfo;

  /**
   * Constructs a new tab object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $pluginId
   *   The pluginId for the plugin instance.
   * @param string $pluginDefinition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The EntityTypeManagerInterface service.
   * @param \Drupal\Core\Config\ConfigManagerInterface $configManager
   *   The ConfigManagerInterface service.
   * @param \Drupal\Core\Routing\CurrentRouteMatch $currentRouteMatch
   *   The CurrentRouteMatch service.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The ModuleHandlerInterface service.
   * @param \Drupal\Core\Entity\EntityFieldManager $entityFieldManager
   *   The EntityFieldManager service.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfo $entityTypeBundleInfo
   *   The EntityTypeBundleInfo service.
   */
  public function __construct(
    array $configuration,
    $pluginId,
    $pluginDefinition,
    EntityTypeManagerInterface $entityTypeManager,
    ConfigManagerInterface $configManager,
    CurrentRouteMatch $currentRouteMatch,
    ModuleHandlerInterface $moduleHandler,
    EntityFieldManager $entityFieldManager,
    EntityTypeBundleInfo $entityTypeBundleInfo
  ) {
    parent::__construct($configuration, $pluginId, $pluginDefinition, $currentRouteMatch, $entityTypeBundleInfo);
    $this->entityTypeManager = $entityTypeManager;
    $this->configManager = $configManager;
    $this->currentRouteMatch = $currentRouteMatch;
    $this->moduleHandler = $moduleHandler;
    $this->entityFieldManager = $entityFieldManager;
    $this->entityTypeBundleInfo = $entityTypeBundleInfo;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
    return new static(
      $configuration,
      $pluginId,
      $pluginDefinition,
      $container->get('entity_type.manager'),
      $container->get('config.manager'),
      $container->get('current_route_match'),
      $container->get('module_handler'),
      $container->get('entity_field.manager'),
      $container->get('entity_type.bundle.info')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'lbk_tab' => [
        'tab_content' => [],
      ],
      'tabs_default_text' => $this->t('No tabs.'),
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $formState) {
    $config = $this->getConfiguration();

    $form['#prefix'] = '<div class="lbk-tab--component">';
    $form['#tree'] = TRUE;

    $form['items_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Tabs'),
      '#prefix' => '<div id="items-fieldset-wrapper">',
      '#suffix' => '</div>',
      '#weight' => 0,
    ];

    if (!$formState->has('items')) {
      $formState->set('items', $config['lbk_tab']['tab_content']);
    }

    $tabs = $formState->get('items');
    $numTabs = count($tabs);
    for ($i = 0; $i < $numTabs; $i++) {
      $tab_value = 'Tab ' . ($i + 1);
      if (isset($tabs[$i]['name_tab'])) $tab_value = $tabs[$i]['name_tab'];

      // Tab label.
      $form['items_fieldset']['items'][$i]['name_tab'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Tab @index label', ['@index' => $i + 1]),
        '#default_value' => $tab_value,
        '#maxlength' => 64,
        '#size' => 64,
        '#weight' => 0,
      ];

      // Which type of tab are we adding?
      if ($tabs[$i]['type'] === 'custom_text') {
        // Custom text tab.
        $tab_text = '';
        if (isset($tabs[$i]['text_format']['value'])) $tab_text = $tabs[$i]['text_format']['value'];

        $tab_text_format = '';
        if (isset($tabs[$i]['text_format']['format'])) $tab_text_format = $tabs[$i]['text_format']['format'];

        $form['items_fieldset']['items'][$i]['text_format'] = [
          '#type' => 'text_format',
          '#title' => $this->t('Rich text'),
          '#default_value' => $tab_text,
          '#format' => $tab_text_format,
          '#weight' => 10,
        ];

      }
      else {
        // Block tab.
        if ($tabs[$i]['type'] === 'block') {
          $tab_name = '';
          if (isset($tabs[$i]['name'])) $tab_name = $tabs[$i]['name'];

          $form['items_fieldset']['items'][$i]['name'] = [
            '#type' => 'select',
            '#title' => $this->t('Content Block'),
            '#options' => $this->getBlocks(),
            '#default_value' => $tab_name,
            '#weight' => 10,
          ];

        }
      }
    }

    // Remove last block button.
    if ($numTabs >= 1) {
      $form['items_fieldset']['items']['remove_item'] = [
        '#type' => 'submit',
        '#value' => $this->t('Remove last tab'),
        '#submit' => [[$this, 'removeLastBlock']],
        '#ajax' => [
          'callback' => [$this, 'removeLastBlockCallback'],
          'wrapper' => 'items-fieldset-wrapper',
        ],
        '#weight' => 20,
      ];
    }

    $form['items_fieldset']['actions'] = [
      '#type' => 'actions',
    ];

    // Add custom text block button.
    $form['add_custom_text'] = [
      '#type' => 'submit',
      '#value' => $this->t('Add custom text'),
      '#submit' => [[$this, 'addCustomText']],
      '#ajax' => [
        'callback' => [$this, 'addCustomTextCallback'],
        'wrapper' => 'items-fieldset-wrapper',
      ],
      '#weight' => 10,
      '#prefix' => '<div class="lbk-tab-buttons">',
    ];

    // Add block button.
    $form['add_block_tab'] = [
      '#type' => 'submit',
      '#value' => $this->t('Add block'),
      '#submit' => [[$this, 'addBlock']],
      '#ajax' => [
        'callback' => [$this, 'addBlockCallback'],
        'wrapper' => 'items-fieldset-wrapper',
      ],
      '#weight' => 10,
      '#suffix' => '</div>',
    ];

    $tab_default_text = '';
    if (isset($this->configuration['tabs_default_text'])) $tab_default_text = $this->configuration['tabs_default_text'];
    $form['tabs_default_text'] = [
      '#type' => 'textfield',
      '#title' => $this->t('"No tabs" text.'),
      '#default_value' => $tab_default_text,
      '#maxlength' => 64,
      '#size' => 64,
      '#weight' => 20,
    ];

    $form['#suffix'] = '</div>';
    $form['#attached']['library'] = ['layout_builder_kit/tab-styling'];

    return $form;
  }

  /**
   * Add custom text.
   *
   * @param array $form
   *   The array form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The FormStateInterface.
   */
  public function addCustomText(array &$form, FormStateInterface $formState) {
    $items = [];
    if ($formState->has('items')) {
      $items = $formState->get('items');
      $nextItem = count($items);
      $items[$nextItem]['type'] = 'custom_text';
    }
    else {
      $nextItem = count($items);
      $items[$nextItem]['type'] = 'custom_text';
    }

    $formState->set('items', $items);
    $formState->setRebuild();
  }

  /**
   * Add custom text (callback).
   *
   * @param array $form
   *   The array form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The FormStateInterface.
   *
   * @return mixed
   *   Return the form.
   */
  public function addCustomTextCallback(array &$form, FormStateInterface $formState) {
    return $form['settings']['items_fieldset'];
  }

  /**
   * Add block.
   *
   * @param array $form
   *   The array form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The FormStateInterface.
   */
  public function addBlock(array &$form, FormStateInterface $formState) {
    $items = [];
    if ($formState->has('items')) {
      $items = $formState->get('items');
      $nextItem = count($items);
      $items[$nextItem]['type'] = 'block';
    }
    else {
      $nextItem = count($items);
      $items[$nextItem]['type'] = 'block';
    }

    $formState->set('items', $items);
    $formState->setRebuild();
  }

  /**
   * Add block (callback).
   *
   * @param array $form
   *   The array form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The FormStateInterface.
   *
   * @return mixed
   *   Return the form.
   */
  public function addBlockCallback(array &$form, FormStateInterface $formState) {
    return $form['settings']['items_fieldset'];
  }

  /**
   * Remove last block.
   *
   * @param array $form
   *   The array form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The FormStateInterface.
   */
  public function removeLastBlock(array &$form, FormStateInterface $formState) {
    $items = [];
    if ($formState->has('items')) {
      $items = $formState->get('items');
      array_pop($items);
    }

    $formState->set('items', $items);
    $formState->setRebuild();
  }

  /**
   * Remove last block (callback).
   *
   * @param array $form
   *   The array form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The FormStateInterface.
   *
   * @return mixed
   *   Return the form.
   */
  public function removeLastBlockCallback(array &$form, FormStateInterface $formState) {
    return $form['settings']['items_fieldset'];
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $formState) {
    $this->configuration['tabs_default_text'] = $formState->getValue('tabs_default_text');

    // Set to empty before save all again.
    $this->configuration['lbk_tab']['tab_content'] = [];

    foreach ($formState->getValues() as $key => $value) {
      if ($key === 'items_fieldset') {
        if (isset($value['items'])) {
          $items = $value['items'];
          $tabs = $formState->get('items');
          if (is_array($tabs)) {
            for ($i = 0; $i < count($tabs); $i++) {
              if ($tabs[$i]['type'] === 'custom_text') {
                $this->configuration['lbk_tab']['tab_content'][$i]['type'] = 'custom_text';
                $this->configuration['lbk_tab']['tab_content'][$i]['name_tab'] = $items[$i]['name_tab'];
                $this->configuration['lbk_tab']['tab_content'][$i]['text_format']['value'] = $items[$i]['text_format']['value'];
                $this->configuration['lbk_tab']['tab_content'][$i]['text_format']['format'] = $items[$i]['text_format']['format'];
              }
              else {
                if ($tabs[$i]['type'] === 'block') {
                  $this->configuration['lbk_tab']['tab_content'][$i]['type'] = 'block';
                  $this->configuration['lbk_tab']['tab_content'][$i]['name_tab'] = $items[$i]['name_tab'];
                  $this->configuration['lbk_tab']['tab_content'][$i]['name'] = $items[$i]['name'];
                }
              }
            }
          }
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = parent::build();

    $tabs = [];
    $node = NULL;
    $renderedBlock = NULL;
    if (isset($this->configuration['lbk_tab']['tab_content'])) {
      for ($i = 0; $i < count($this->configuration['lbk_tab']['tab_content']); $i++) {
        if ($this->configuration['lbk_tab']['tab_content'][$i]['type'] === 'block') {
          $tabs[$i]['type'] = $this->configuration['lbk_tab']['tab_content'][$i]['type'];
          $tabs[$i]['name_tab'] = $this->configuration['lbk_tab']['tab_content'][$i]['name_tab'];

          // Render block.
          if ((int) $this->configuration['lbk_tab']['tab_content'][$i]['name'] > 0) {
            // Render block.
            $bid = $this->configuration['lbk_tab']['tab_content'][$i]['name'];
            $block = BlockContent::load($bid);
            if ($block instanceof BlockContent) {
              $renderedBlock = $this->entityTypeManager->getViewBuilder('block_content')->view($block);
            }
            else {
              if ($this->configuration['lbk_tab']['tab_content'][$i]['name'] == 'none') {
                $renderedBlock = $this->t("There is no any content block yet.");
              }
              else {
                $renderedBlock = $this->t("Sorry this Block was deleted.");
              }
            }
          }
          else {
            // Render fields.
            $field = $this->getField($this->configuration['lbk_tab']['tab_content'][$i]['name']);

            if (isset($field) && $field !== "") {
              $entityType = 'node';
              // Fields to render.
              $fields = [
                $field,
              ];

              // Get the Node entity object.
              if ($this->currentRouteMatch->getParameter('node')) {
                $node = $this->currentRouteMatch->getParameter('node');
              }
              else {
                $currentRoute = $this->currentRouteMatch;
                $sectionStorage = $currentRoute->getParameters()->get('section_storage');
                if ($sectionStorage instanceof OverridesSectionStorage) {
                  $context = $sectionStorage->getContext('entity');
                  if ($context instanceof EntityContext) {
                    $contextData = $context->getContextData();
                    if ($contextData instanceof EntityAdapter) {
                      $node = $contextData->getEntity();
                    }
                  }
                }
              }

              // Get the view for this Node entity object.
              $viewBuilder = $this->entityTypeManager->getViewBuilder($entityType);

              // Build the Node array to render.
              foreach ($fields as $field_name) {
                if ($node instanceof Node) {
                  if ($node->hasField($field_name) && $node->access('view')) {
                    $value = $node->get($field_name);
                    $renderedBlock = $viewBuilder->viewField($value, ["label" => "hidden"]);
                    $renderedBlock['#cache']['tags'] = $node->getCacheTags();
                  }
                  else {
                    $renderedBlock = $this->t('This field is not available for this content.');
                  }
                }
                else {
                  $renderedBlock = $this->t('Render this inside a node page that has this field.');
                }
              }
            }
            else {
              // Render content block.
              $blockEntity = Block::load($this->configuration['lbk_tab']['tab_content'][$i]['name']);
              $renderedBlock = $this->entityTypeManager
                ->getViewBuilder('block')
                ->view($blockEntity);
            }
          }
          $tabs[$i]['name'] = $renderedBlock;
        }
        else {
          $tabs[$i] = $this->configuration['lbk_tab']['tab_content'][$i];
        }
      }
    }

    $build['#theme'] = 'LBKTab';
    $build['#attached']['library'] = ['layout_builder_kit/tab-styling'];
    $build['#tabs_default_text']['#markup'] = $this->configuration['tabs_default_text'];
    $build['#tabs'] = $tabs;
    return $build;
  }

  /**
   * Get custom blocks.
   *
   * @return array
   *   Return array with custom blocks.
   */
  private function getContentBlocks() {
    $blocks = BlockContent::loadMultiple();

    $options = [];
    $labelOption = $this->t('Custom');

    if ($labelOption instanceof TranslatableMarkup) {
      foreach ($blocks as $value) {
        if ($value instanceof BlockContent) {
          $options[$labelOption->render()][$value->id()] = $value->label();
        }
      }
    }

    return $options;
  }

  /**
   * Get module blocks.
   *
   * @return array
   *   Return array with module blocks.
   */
  private function getContentPluginBlocks() {
    $blocksList = [];
    $labelOption = $this->t('Modules');

    // TODO: Use this in certain cases? If so, where do we store the block?
    //    $blockManager = \Drupal::service('plugin.manager.block');
    //    $contextRepository = \Drupal::service('context.repository');
    //    $definitions = $blockManager->getDefinitionsForContexts($contextRepository->getAvailableContexts());

    // Load all existing blocks.
    $blocks = Block::loadMultiple();

    $modules = $this->moduleHandler->getModuleList();

    if ($labelOption instanceof TranslatableMarkup) {
      foreach ($blocks as $block) {
        if ($block instanceof Block) {
          $dependenciesBlock = NULL;
          if (isset($block->getDependencies()['module'])) $dependenciesBlock = $block->getDependencies()['module'];
          if ($dependenciesBlock) {
            $system = FALSE;
            foreach ($dependenciesBlock as $dependencyBlock) {
              $module = $modules[$dependencyBlock];
              if ($module instanceof Extension) {
                if ($block->getPluginId() !== 'lbk_tab') {
                  $pathModuleArray = explode('/', $module->getPathname());
                  if (in_array('contrib', $pathModuleArray) || in_array('custom', $pathModuleArray)) {
                    $system = TRUE;
                  }
                }
              }
            }
            if ($system) {
              $blocksList[$labelOption->render()][$block->id()] = $block->label();
            }
          }
        }
      }
    }

    return $blocksList;
  }

  /**
   * Get system blocks.
   *
   * @return array
   *   Return array with system blocks.
   */
  private function getSystemPluginBlocks() {
    $blocksList = [];
    $labelOption = $this->t('System');

    $blocks = Block::loadMultiple();

    $modules = $this->moduleHandler->getModuleList();
    unset($modules['layout_builder_kit']);

    if ($labelOption instanceof TranslatableMarkup) {
      foreach ($blocks as $block) {
        if ($block instanceof Block) {
          $dependenciesBlock = NULL;
          if (isset($block->getDependencies()['module'])) $dependenciesBlock = $block->getDependencies()['module'];
          if ($dependenciesBlock) {
            $dependenciesBlock = $block->getDependencies()['module'];
            $system = FALSE;
            foreach ($dependenciesBlock as $dependencyBlock) {
              $module = $modules[$dependencyBlock];
              if ($module instanceof Extension) {
                $pathModuleArray = explode('/', $module->getPathname());
                if (in_array('core', $pathModuleArray)) {
                  $system = TRUE;
                }
              }
            }
            if ($system) {
              $blocksList[$labelOption->render()][$block->id()] = ucfirst($block->getTheme()) . ':' . $block->label();
            }
          }
        }
      }
    }

    return $blocksList;
  }

  /**
   * Get blocks of all types.
   *
   * @return array
   *   Return all blocks.
   */
  private function getBlocks() {
    $contentAndContentPluginBlocks = array_merge($this->getContentBlocks(), $this->getContentPluginBlocks());
    $allBlocks = array_merge($contentAndContentPluginBlocks, $this->getSystemPluginBlocks());

    $allFields = array_merge($allBlocks, $this->getNodeFields());

    return $allFields;
  }

  /**
   * Get node fields.
   *
   * @return array
   *   Return array of node fields.
   */
  private function getNodeFields() {
    $allFields = [];
    // Get the Current Route Match.
    $currentRoute = $this->currentRouteMatch;
    if ($currentRoute instanceof CurrentRouteMatch) {
      $sectionStorage = $currentRoute->getParameters()->get('section_storage');
      // Content Type page.
      if ($sectionStorage instanceof DefaultsSectionStorage) {
        $availableContexts = $sectionStorage->getContexts();
        $contextDisplay = $availableContexts['display'];
        if ($contextDisplay instanceof EntityContext) {
          $contextData = $contextDisplay->getContextData();
          if ($contextData instanceof ConfigEntityAdapter) {
            $contentInfo = $contextData->getEntity();
            if ($contentInfo instanceof LayoutBuilderEntityViewDisplay) {
              // Bundle 'page'.
              $bundle = $contentInfo->getTargetBundle();
              // Content Type 'node'.
              $entityTypeId = $contentInfo->getTargetEntityTypeId();

              $definitions = $this->entityFieldManager->getFieldDefinitions($entityTypeId, $bundle);
              foreach ($definitions as $fieldName => $fieldDefinition) {
                if (!empty($fieldDefinition->getTargetBundle()) && $fieldName !== 'layout_builder__layout') {
                  $allFields[$bundle][$bundle . '_' . $fieldName] = $bundle . ':' . $fieldDefinition->getLabel();
                }
              }
            }
          }
        }
      }
      else {
        // Bundle page.
        if ($sectionStorage instanceof OverridesSectionStorage) {
          $context = $sectionStorage->getContext('entity');
          if ($context instanceof EntityContext) {
            $contextData = $context->getContextData();
            if ($contextData instanceof EntityAdapter) {
              $node = $contextData->getEntity();
              if ($node instanceof Node) {
                $bundle = $node->bundle();

                $definitions = $this->entityFieldManager->getFieldDefinitions('node', $bundle);
                foreach ($definitions as $fieldName => $fieldDefinition) {
                  if (!empty($fieldDefinition->getTargetBundle()) && $fieldName !== 'layout_builder__layout') {
                    $allFields[$bundle][$bundle . '_' . $fieldName] = $bundle . ':' . $fieldDefinition->getLabel();
                  }
                }
              }
            }
          }
        }
        else {
          // Get fields for all bundles.
          $entityType = "node";

          $contentTypes = $this->entityTypeBundleInfo->getBundleInfo($entityType);

          foreach ($contentTypes as $key => $value) {
            $bundle = $key;

            $definitions = $this->entityFieldManager->getFieldDefinitions($entityType, $bundle);
            foreach ($definitions as $fieldName => $fieldDefinition) {
              if (!empty($fieldDefinition->getTargetBundle())) {
                $allFields[$value['label']][$bundle . '_' . $fieldName] = $value['label'] . ':' . $fieldDefinition->getLabel();
              }
            }
          }
        }
      }
    }

    return $allFields;
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginId() {
    return 'lbk_tab';
  }
}

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

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