layout_builder_paragraphs-1.0.x-dev/src/Controller/ChooseParagraphController.php

src/Controller/ChooseParagraphController.php
<?php

namespace Drupal\layout_builder_paragraphs\Controller;

use Drupal\layout_builder\Controller\ChooseBlockController;
use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
use Drupal\layout_builder\LayoutBuilderHighlightTrait;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Component\Serialization\Json;

/**
 * Defines a controller to choose a new block.
 *
 * @internal
 *   Controller classes are internal.
 */
class ChooseParagraphController extends ChooseBlockController {

  /**
   * {@inheritdoc}
   */
   public function build(SectionStorageInterface $section_storage, $delta, $region) {
    // Start with the parent form.
    $build = parent::build($section_storage, $delta, $region);

    // First, as we need the entity context, we check if that exists. Otherwise
    // return the original form.
    $context_values = $section_storage->getContextValues();
    if (empty($context_values['entity'])) return $build;
    // We only progress when the entity has specific paragraph reference field.
    // @TODO: make this more generic. E.g. check that that least there is
    // paragraph reference field, regardless of the name.
    $entity = $section_storage->getContextValue('entity');
    if (!$entity->hasField(PARAGRAPH_FIELD)) return $build;

    // Unset add block.
    if (isset($build['add_block'])) unset($build['add_block']);

    // Add choose paragraph link. It's assumed that we have multiple paragraph
    // types.
    $url = Url::fromRoute('layout_builder_paragraphs.choose_paragraph', [
      'section_storage_type' => $section_storage->getStorageType(),
      'section_storage' => $section_storage->getStorageId(),
      'delta' => $delta,
      'region' => $region,
    ]);

    if (isset($url)) {
      $build['choose_paragraph'] = [
        '#type' => 'link',
        '#url' => $url,
        // Right now it's hardcoded to paragraph.
        // @TODO: make this more generic.
        '#title' => $this->t('Create @entity_type', [
          '@entity_type' => $this->entityTypeManager->getDefinition('paragraph')->getSingularLabel(),
        ]),
        '#attributes' => parent::getAjaxAttributes(),  // Use dialog.
        // As user has access to the layout builder tab, user must have access to the entity.
        // @TODO: make this more generic. E.g. check that the user has access
        // to the paragraph reference field.
        '#access' => TRUE,
        '#weight' => -100,
      ];
      $build['choose_paragraph']['#attributes']['class'][] = 'inline-block-create-button';
    }

    // Start with collapsed block categories.
    foreach ($build['block_categories'] as &$block_category) {
      if (!empty($block_category['#type']) && $block_category['#type'] == 'details') {
        $block_category['#open'] = FALSE;
      }
    }

    return $build;
  }

  /**
   * Provides the UI for choosing the type for the new paragraph.
   *
   * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
   *   The section storage.
   * @param int $delta
   *   The delta of the section to splice.
   * @param string $region
   *   The region the block is going in.
   *
   * @return array
   *   A render array.
   */
  public function paragraphList(SectionStorageInterface $section_storage, $delta, $region) {
    // @TODO: check the access to various paragraph types, refer to paragraphs_type_permissions module.

    $entity = $section_storage->getContextValue('entity');
    $field_definition = $entity->getFieldDefinition(PARAGRAPH_FIELD);
    // The following lines are adapted from ParagraphsWidget::getAllowedTypes().
    $selection_manager = \Drupal::service('plugin.manager.entity_reference_selection');
    $handler = $selection_manager->getSelectionHandler($field_definition);
    $allowed_paragraph_types = $handler->getSortedAllowedTypes();

    $build = [];
    $links = [];

    // Create paragraph_blocks equivalent plugin id. E.g.
    // paragraph_field:node:field_contents:0:landing_page
    $paragraph_plugin_id = [
      'parent_type' => $entity->getEntityTypeId(),
      'field' => PARAGRAPH_FIELD,
      'delta' => $entity->{PARAGRAPH_FIELD}->count(),
      'parent_bundle' => $entity->bundle(),
    ];
    $paragraph_plugin_id = implode(':', $paragraph_plugin_id);
    // Render links for all allowed paragraph types.
    foreach ($allowed_paragraph_types as $paragraph_type => $paragraph) {
      $paragraph_type_entity = \Drupal\paragraphs\Entity\ParagraphsType::load($paragraph_type);

      $icon_url = $paragraph_type_entity->getIconUrl();
      $paragraph_label = $paragraph_type_entity->label();
      // if paragraph icon url is not empty
      if (!empty($icon_url)) {
        $title_with_icon = '<img src="' . $icon_url . '" alt="' . $paragraph_label . '" class="paragraph-icon">' . $paragraph_label;
        $link_title = $this->t($title_with_icon);
      }
      // If paragraph icon url is empty, use default icons
      else {
        $module_handler = \Drupal::service('module_handler');
        $module_path = $module_handler->getModule('layout_builder_paragraphs')->getPath();

        $default_icon_path = '/' . $module_path . '/images/default-paragraph-icon.png';

        $title_with_icon = '<img src="' . $default_icon_path . '" alt="Paragraph icon" class="paragraph-icon">' . $paragraph_label;

        $link_title = $this->t($title_with_icon);
      }

      $attributes = [];
      // @TODO: To use the paragraph form in modal, we need to solve the issue
      // of modal media browser closing the underlying paragraph form.
      // $attributes = $this->getAjaxAttributes();    // Use modal.
      $attributes['class'][] = 'js-layout-builder-block-link';
      $attributes['class'][] = \Drupal::moduleHandler()->moduleExists('gin_lb') ? 'create-paragraph-item' : 'inline-block-list__item';
      $link = [
        'title' => $link_title,
        'url' => Url::fromRoute('layout_builder_paragraphs.add_paragraph',
          [
            'section_storage_type' => $section_storage->getStorageType(),
            'section_storage' => $section_storage->getStorageId(),
            'delta' => $delta,
            'region' => $region,
            'plugin_id' => $paragraph_plugin_id,
            'paragraph_type' => $paragraph_type,
          ]
        ),
        'attributes' => $attributes,
      ];
      $links[] = $link;
    }
    // The remaining form setup mimics ChooseBlockController::inlineBlockList().
    $build['links'] = [
      '#theme' => 'links',
      '#links' => $links,
      '#attributes' => [
        'class' => [
          \Drupal::moduleHandler()->moduleExists('gin_lb') ? 'glb-list' : 'inline-block-list',
        ],
        'data-layout-builder-target-highlight-id' => $this->blockAddHighlightId($delta, $region),
      ],
    ];
    $build['back_button'] = [
      '#type' => 'link',
      '#url' => Url::fromRoute('layout_builder.choose_block',
        [
          'section_storage_type' => $section_storage->getStorageType(),
          'section_storage' => $section_storage->getStorageId(),
          'delta' => $delta,
          'region' => $region,
        ]
      ),
      '#title' => $this->t('Back'),
      '#attributes' => parent::getAjaxAttributes(),  // Use dialog.
    ];

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  protected function getAjaxAttributes($modal = NULL) {
    if ($this->isAjax()) {
      return [
        'class' => ['use-ajax'],
        'data-dialog-type' => 'modal',
        'data-dialog-options' => Json::encode(['width' => '80vw']),
      ];
    }
    return [];
  }
}

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

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