Pull merge.
[yaffs-website] / web / core / modules / layout_builder / src / Controller / ChooseBlockController.php
index 5287be25fcff10b8908ebf93a5c9b3538bab84a2..9bd76bacc13f7df47d918053e167a034e4bdeb5a 100644 (file)
@@ -2,8 +2,11 @@
 
 namespace Drupal\layout_builder\Controller;
 
+use Drupal\Core\Ajax\AjaxHelperTrait;
 use Drupal\Core\Block\BlockManagerInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
 use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
 use Drupal\layout_builder\SectionStorageInterface;
@@ -18,6 +21,7 @@ class ChooseBlockController implements ContainerInjectionInterface {
 
   use AjaxHelperTrait;
   use LayoutBuilderContextTrait;
+  use StringTranslationTrait;
 
   /**
    * The block manager.
@@ -26,14 +30,24 @@ class ChooseBlockController implements ContainerInjectionInterface {
    */
   protected $blockManager;
 
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
   /**
    * ChooseBlockController constructor.
    *
    * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
    *   The block manager.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
    */
-  public function __construct(BlockManagerInterface $block_manager) {
+  public function __construct(BlockManagerInterface $block_manager, EntityTypeManagerInterface $entity_type_manager) {
     $this->blockManager = $block_manager;
+    $this->entityTypeManager = $entity_type_manager;
   }
 
   /**
@@ -41,7 +55,8 @@ class ChooseBlockController implements ContainerInjectionInterface {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('plugin.manager.block')
+      $container->get('plugin.manager.block'),
+      $container->get('entity_type.manager')
     );
   }
 
@@ -59,39 +74,164 @@ class ChooseBlockController implements ContainerInjectionInterface {
    *   A render array.
    */
   public function build(SectionStorageInterface $section_storage, $delta, $region) {
-    $build['#type'] = 'container';
-    $build['#attributes']['class'][] = 'block-categories';
-
-    $definitions = $this->blockManager->getDefinitionsForContexts($this->getAvailableContexts($section_storage));
-    foreach ($this->blockManager->getGroupedDefinitions($definitions) as $category => $blocks) {
-      $build[$category]['#type'] = 'details';
-      $build[$category]['#open'] = TRUE;
-      $build[$category]['#title'] = $category;
-      $build[$category]['links'] = [
-        '#theme' => 'links',
-      ];
-      foreach ($blocks as $block_id => $block) {
-        $link = [
-          'title' => $block['admin_label'],
-          'url' => Url::fromRoute('layout_builder.add_block',
-            [
-              'section_storage_type' => $section_storage->getStorageType(),
-              'section_storage' => $section_storage->getStorageId(),
-              'delta' => $delta,
-              'region' => $region,
-              'plugin_id' => $block_id,
-            ]
-          ),
-        ];
-        if ($this->isAjax()) {
-          $link['attributes']['class'][] = 'use-ajax';
-          $link['attributes']['data-dialog-type'][] = 'dialog';
-          $link['attributes']['data-dialog-renderer'][] = 'off_canvas';
+    $build['#title'] = $this->t('Choose a block');
+    if ($this->entityTypeManager->hasDefinition('block_content_type') && $types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple()) {
+      if (count($types) === 1) {
+        $type = reset($types);
+        $plugin_id = 'inline_block:' . $type->id();
+        if ($this->blockManager->hasDefinition($plugin_id)) {
+          $url = Url::fromRoute('layout_builder.add_block', [
+            'section_storage_type' => $section_storage->getStorageType(),
+            'section_storage' => $section_storage->getStorageId(),
+            'delta' => $delta,
+            'region' => $region,
+            'plugin_id' => $plugin_id,
+          ]);
         }
-        $build[$category]['links']['#links'][] = $link;
+      }
+      else {
+        $url = Url::fromRoute('layout_builder.choose_inline_block', [
+          'section_storage_type' => $section_storage->getStorageType(),
+          'section_storage' => $section_storage->getStorageId(),
+          'delta' => $delta,
+          'region' => $region,
+        ]);
+      }
+      if (isset($url)) {
+        $build['add_block'] = [
+          '#type' => 'link',
+          '#url' => $url,
+          '#title' => $this->t('Create @entity_type', [
+            '@entity_type' => $this->entityTypeManager->getDefinition('block_content')->getSingularLabel(),
+          ]),
+          '#attributes' => $this->getAjaxAttributes(),
+        ];
+        $build['add_block']['#attributes']['class'][] = 'inline-block-create-button';
       }
     }
+
+    $block_categories['#type'] = 'container';
+    $block_categories['#attributes']['class'][] = 'block-categories';
+
+    // @todo Explicitly cast delta to an integer, remove this in
+    //   https://www.drupal.org/project/drupal/issues/2984509.
+    $delta = (int) $delta;
+
+    $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
+      'section_storage' => $section_storage,
+      'delta' => $delta,
+      'region' => $region,
+    ]);
+    $grouped_definitions = $this->blockManager->getGroupedDefinitions($definitions);
+    foreach ($grouped_definitions as $category => $blocks) {
+      $block_categories[$category]['#type'] = 'details';
+      $block_categories[$category]['#open'] = TRUE;
+      $block_categories[$category]['#title'] = $category;
+      $block_categories[$category]['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks);
+    }
+    $build['block_categories'] = $block_categories;
     return $build;
   }
 
+  /**
+   * Provides the UI for choosing a new inline block.
+   *
+   * @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 inlineBlockList(SectionStorageInterface $section_storage, $delta, $region) {
+    $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
+      'section_storage' => $section_storage,
+      'region' => $region,
+      'list' => 'inline_blocks',
+    ]);
+    $blocks = $this->blockManager->getGroupedDefinitions($definitions);
+    $build = [];
+    if (isset($blocks['Inline blocks'])) {
+      $build['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks['Inline blocks']);
+      $build['links']['#attributes']['class'][] = 'inline-block-list';
+      foreach ($build['links']['#links'] as &$link) {
+        $link['attributes']['class'][] = 'inline-block-list__item';
+      }
+      $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' => $this->getAjaxAttributes(),
+      ];
+    }
+    return $build;
+  }
+
+  /**
+   * Gets a render array of block links.
+   *
+   * @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.
+   * @param array $blocks
+   *   The information for each block.
+   *
+   * @return array
+   *   The block links render array.
+   */
+  protected function getBlockLinks(SectionStorageInterface $section_storage, $delta, $region, array $blocks) {
+    $links = [];
+    foreach ($blocks as $block_id => $block) {
+      $link = [
+        'title' => $block['admin_label'],
+        'url' => Url::fromRoute('layout_builder.add_block',
+          [
+            'section_storage_type' => $section_storage->getStorageType(),
+            'section_storage' => $section_storage->getStorageId(),
+            'delta' => $delta,
+            'region' => $region,
+            'plugin_id' => $block_id,
+          ]
+        ),
+        'attributes' => $this->getAjaxAttributes(),
+      ];
+
+      $links[] = $link;
+    }
+    return [
+      '#theme' => 'links',
+      '#links' => $links,
+    ];
+  }
+
+  /**
+   * Get dialog attributes if an ajax request.
+   *
+   * @return array
+   *   The attributes array.
+   */
+  protected function getAjaxAttributes() {
+    if ($this->isAjax()) {
+      return [
+        'class' => ['use-ajax'],
+        'data-dialog-type' => 'dialog',
+        'data-dialog-renderer' => 'off_canvas',
+      ];
+    }
+    return [];
+  }
+
 }