Chris@14: blockManager = $block_manager; Chris@17: $this->entityTypeManager = $entity_type_manager; Chris@18: if (!$current_user) { Chris@18: @trigger_error('The current_user service must be passed to ChooseBlockController::__construct(), it is required before Drupal 9.0.0.', E_USER_DEPRECATED); Chris@18: $current_user = \Drupal::currentUser(); Chris@18: } Chris@18: $this->currentUser = $current_user; Chris@14: } Chris@14: Chris@14: /** Chris@14: * {@inheritdoc} Chris@14: */ Chris@14: public static function create(ContainerInterface $container) { Chris@14: return new static( Chris@17: $container->get('plugin.manager.block'), Chris@18: $container->get('entity_type.manager'), Chris@18: $container->get('current_user') Chris@14: ); Chris@14: } Chris@14: Chris@14: /** Chris@14: * Provides the UI for choosing a new block. Chris@14: * Chris@14: * @param \Drupal\layout_builder\SectionStorageInterface $section_storage Chris@14: * The section storage. Chris@14: * @param int $delta Chris@14: * The delta of the section to splice. Chris@14: * @param string $region Chris@14: * The region the block is going in. Chris@14: * Chris@14: * @return array Chris@14: * A render array. Chris@14: */ Chris@14: public function build(SectionStorageInterface $section_storage, $delta, $region) { Chris@17: if ($this->entityTypeManager->hasDefinition('block_content_type') && $types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple()) { Chris@17: if (count($types) === 1) { Chris@17: $type = reset($types); Chris@17: $plugin_id = 'inline_block:' . $type->id(); Chris@17: if ($this->blockManager->hasDefinition($plugin_id)) { Chris@17: $url = Url::fromRoute('layout_builder.add_block', [ Chris@17: 'section_storage_type' => $section_storage->getStorageType(), Chris@17: 'section_storage' => $section_storage->getStorageId(), Chris@17: 'delta' => $delta, Chris@17: 'region' => $region, Chris@17: 'plugin_id' => $plugin_id, Chris@17: ]); Chris@17: } Chris@17: } Chris@17: else { Chris@17: $url = Url::fromRoute('layout_builder.choose_inline_block', [ Chris@17: 'section_storage_type' => $section_storage->getStorageType(), Chris@17: 'section_storage' => $section_storage->getStorageId(), Chris@17: 'delta' => $delta, Chris@17: 'region' => $region, Chris@17: ]); Chris@17: } Chris@17: if (isset($url)) { Chris@17: $build['add_block'] = [ Chris@17: '#type' => 'link', Chris@17: '#url' => $url, Chris@17: '#title' => $this->t('Create @entity_type', [ Chris@17: '@entity_type' => $this->entityTypeManager->getDefinition('block_content')->getSingularLabel(), Chris@17: ]), Chris@17: '#attributes' => $this->getAjaxAttributes(), Chris@18: '#access' => $this->currentUser->hasPermission('create and edit custom blocks'), Chris@17: ]; Chris@17: $build['add_block']['#attributes']['class'][] = 'inline-block-create-button'; Chris@17: } Chris@17: } Chris@14: Chris@18: $build['filter'] = [ Chris@18: '#type' => 'search', Chris@18: '#title' => $this->t('Filter by block name'), Chris@18: '#title_display' => 'invisible', Chris@18: '#size' => 30, Chris@18: '#placeholder' => $this->t('Filter by block name'), Chris@18: '#attributes' => [ Chris@18: 'class' => ['js-layout-builder-filter'], Chris@18: 'title' => $this->t('Enter a part of the block name to filter by.'), Chris@18: ], Chris@18: ]; Chris@18: Chris@17: $block_categories['#type'] = 'container'; Chris@17: $block_categories['#attributes']['class'][] = 'block-categories'; Chris@18: $block_categories['#attributes']['class'][] = 'js-layout-builder-categories'; Chris@18: $block_categories['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockAddHighlightId($delta, $region); Chris@17: Chris@17: // @todo Explicitly cast delta to an integer, remove this in Chris@17: // https://www.drupal.org/project/drupal/issues/2984509. Chris@17: $delta = (int) $delta; Chris@17: Chris@17: $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [ Chris@17: 'section_storage' => $section_storage, Chris@17: 'delta' => $delta, Chris@17: 'region' => $region, Chris@17: ]); Chris@17: $grouped_definitions = $this->blockManager->getGroupedDefinitions($definitions); Chris@17: foreach ($grouped_definitions as $category => $blocks) { Chris@17: $block_categories[$category]['#type'] = 'details'; Chris@18: $block_categories[$category]['#attributes']['class'][] = 'js-layout-builder-category'; Chris@17: $block_categories[$category]['#open'] = TRUE; Chris@17: $block_categories[$category]['#title'] = $category; Chris@17: $block_categories[$category]['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks); Chris@17: } Chris@17: $build['block_categories'] = $block_categories; Chris@17: return $build; Chris@17: } Chris@17: Chris@17: /** Chris@17: * Provides the UI for choosing a new inline block. Chris@17: * Chris@17: * @param \Drupal\layout_builder\SectionStorageInterface $section_storage Chris@17: * The section storage. Chris@17: * @param int $delta Chris@17: * The delta of the section to splice. Chris@17: * @param string $region Chris@17: * The region the block is going in. Chris@17: * Chris@17: * @return array Chris@17: * A render array. Chris@17: */ Chris@17: public function inlineBlockList(SectionStorageInterface $section_storage, $delta, $region) { Chris@17: $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [ Chris@17: 'section_storage' => $section_storage, Chris@17: 'region' => $region, Chris@17: 'list' => 'inline_blocks', Chris@17: ]); Chris@17: $blocks = $this->blockManager->getGroupedDefinitions($definitions); Chris@17: $build = []; Chris@18: $inline_blocks_category = (string) $this->t('Inline blocks'); Chris@18: if (isset($blocks[$inline_blocks_category])) { Chris@18: $build['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks[$inline_blocks_category]); Chris@17: $build['links']['#attributes']['class'][] = 'inline-block-list'; Chris@17: foreach ($build['links']['#links'] as &$link) { Chris@17: $link['attributes']['class'][] = 'inline-block-list__item'; Chris@17: } Chris@17: $build['back_button'] = [ Chris@17: '#type' => 'link', Chris@17: '#url' => Url::fromRoute('layout_builder.choose_block', Chris@17: [ Chris@17: 'section_storage_type' => $section_storage->getStorageType(), Chris@17: 'section_storage' => $section_storage->getStorageId(), Chris@17: 'delta' => $delta, Chris@17: 'region' => $region, Chris@17: ] Chris@17: ), Chris@17: '#title' => $this->t('Back'), Chris@17: '#attributes' => $this->getAjaxAttributes(), Chris@14: ]; Chris@14: } Chris@18: $build['links']['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockAddHighlightId($delta, $region); Chris@14: return $build; Chris@14: } Chris@14: Chris@17: /** Chris@17: * Gets a render array of block links. Chris@17: * Chris@17: * @param \Drupal\layout_builder\SectionStorageInterface $section_storage Chris@17: * The section storage. Chris@17: * @param int $delta Chris@17: * The delta of the section to splice. Chris@17: * @param string $region Chris@17: * The region the block is going in. Chris@17: * @param array $blocks Chris@17: * The information for each block. Chris@17: * Chris@17: * @return array Chris@17: * The block links render array. Chris@17: */ Chris@17: protected function getBlockLinks(SectionStorageInterface $section_storage, $delta, $region, array $blocks) { Chris@17: $links = []; Chris@17: foreach ($blocks as $block_id => $block) { Chris@18: $attributes = $this->getAjaxAttributes(); Chris@18: $attributes['class'][] = 'js-layout-builder-block-link'; Chris@17: $link = [ Chris@17: 'title' => $block['admin_label'], Chris@17: 'url' => Url::fromRoute('layout_builder.add_block', Chris@17: [ Chris@17: 'section_storage_type' => $section_storage->getStorageType(), Chris@17: 'section_storage' => $section_storage->getStorageId(), Chris@17: 'delta' => $delta, Chris@17: 'region' => $region, Chris@17: 'plugin_id' => $block_id, Chris@17: ] Chris@17: ), Chris@18: 'attributes' => $attributes, Chris@17: ]; Chris@17: Chris@17: $links[] = $link; Chris@17: } Chris@17: return [ Chris@17: '#theme' => 'links', Chris@17: '#links' => $links, Chris@17: ]; Chris@17: } Chris@17: Chris@17: /** Chris@17: * Get dialog attributes if an ajax request. Chris@17: * Chris@17: * @return array Chris@17: * The attributes array. Chris@17: */ Chris@17: protected function getAjaxAttributes() { Chris@17: if ($this->isAjax()) { Chris@17: return [ Chris@17: 'class' => ['use-ajax'], Chris@17: 'data-dialog-type' => 'dialog', Chris@17: 'data-dialog-renderer' => 'off_canvas', Chris@17: ]; Chris@17: } Chris@17: return []; Chris@17: } Chris@17: Chris@14: }