blockManager = $block_manager; $this->entityTypeManager = $entity_type_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('plugin.manager.block'), $container->get('entity_type.manager') ); } /** * Provides the UI for choosing a new 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 build(SectionStorageInterface $section_storage, $delta, $region) { $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, ]); } } 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 []; } }