annotate core/modules/layout_builder/src/Controller/ChooseBlockController.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents 1fec387a4317
children af1871eacc83
rev   line source
Chris@14 1 <?php
Chris@14 2
Chris@14 3 namespace Drupal\layout_builder\Controller;
Chris@14 4
Chris@17 5 use Drupal\Core\Ajax\AjaxHelperTrait;
Chris@14 6 use Drupal\Core\Block\BlockManagerInterface;
Chris@14 7 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
Chris@17 8 use Drupal\Core\Entity\EntityTypeManagerInterface;
Chris@17 9 use Drupal\Core\StringTranslation\StringTranslationTrait;
Chris@14 10 use Drupal\Core\Url;
Chris@14 11 use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
Chris@14 12 use Drupal\layout_builder\SectionStorageInterface;
Chris@14 13 use Symfony\Component\DependencyInjection\ContainerInterface;
Chris@14 14
Chris@14 15 /**
Chris@14 16 * Defines a controller to choose a new block.
Chris@14 17 *
Chris@14 18 * @internal
Chris@14 19 */
Chris@14 20 class ChooseBlockController implements ContainerInjectionInterface {
Chris@14 21
Chris@14 22 use AjaxHelperTrait;
Chris@14 23 use LayoutBuilderContextTrait;
Chris@17 24 use StringTranslationTrait;
Chris@14 25
Chris@14 26 /**
Chris@14 27 * The block manager.
Chris@14 28 *
Chris@14 29 * @var \Drupal\Core\Block\BlockManagerInterface
Chris@14 30 */
Chris@14 31 protected $blockManager;
Chris@14 32
Chris@14 33 /**
Chris@17 34 * The entity type manager.
Chris@17 35 *
Chris@17 36 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
Chris@17 37 */
Chris@17 38 protected $entityTypeManager;
Chris@17 39
Chris@17 40 /**
Chris@14 41 * ChooseBlockController constructor.
Chris@14 42 *
Chris@14 43 * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
Chris@14 44 * The block manager.
Chris@17 45 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
Chris@17 46 * The entity type manager.
Chris@14 47 */
Chris@17 48 public function __construct(BlockManagerInterface $block_manager, EntityTypeManagerInterface $entity_type_manager) {
Chris@14 49 $this->blockManager = $block_manager;
Chris@17 50 $this->entityTypeManager = $entity_type_manager;
Chris@14 51 }
Chris@14 52
Chris@14 53 /**
Chris@14 54 * {@inheritdoc}
Chris@14 55 */
Chris@14 56 public static function create(ContainerInterface $container) {
Chris@14 57 return new static(
Chris@17 58 $container->get('plugin.manager.block'),
Chris@17 59 $container->get('entity_type.manager')
Chris@14 60 );
Chris@14 61 }
Chris@14 62
Chris@14 63 /**
Chris@14 64 * Provides the UI for choosing a new block.
Chris@14 65 *
Chris@14 66 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
Chris@14 67 * The section storage.
Chris@14 68 * @param int $delta
Chris@14 69 * The delta of the section to splice.
Chris@14 70 * @param string $region
Chris@14 71 * The region the block is going in.
Chris@14 72 *
Chris@14 73 * @return array
Chris@14 74 * A render array.
Chris@14 75 */
Chris@14 76 public function build(SectionStorageInterface $section_storage, $delta, $region) {
Chris@17 77 $build['#title'] = $this->t('Choose a block');
Chris@17 78 if ($this->entityTypeManager->hasDefinition('block_content_type') && $types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple()) {
Chris@17 79 if (count($types) === 1) {
Chris@17 80 $type = reset($types);
Chris@17 81 $plugin_id = 'inline_block:' . $type->id();
Chris@17 82 if ($this->blockManager->hasDefinition($plugin_id)) {
Chris@17 83 $url = Url::fromRoute('layout_builder.add_block', [
Chris@17 84 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 85 'section_storage' => $section_storage->getStorageId(),
Chris@17 86 'delta' => $delta,
Chris@17 87 'region' => $region,
Chris@17 88 'plugin_id' => $plugin_id,
Chris@17 89 ]);
Chris@17 90 }
Chris@17 91 }
Chris@17 92 else {
Chris@17 93 $url = Url::fromRoute('layout_builder.choose_inline_block', [
Chris@17 94 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 95 'section_storage' => $section_storage->getStorageId(),
Chris@17 96 'delta' => $delta,
Chris@17 97 'region' => $region,
Chris@17 98 ]);
Chris@17 99 }
Chris@17 100 if (isset($url)) {
Chris@17 101 $build['add_block'] = [
Chris@17 102 '#type' => 'link',
Chris@17 103 '#url' => $url,
Chris@17 104 '#title' => $this->t('Create @entity_type', [
Chris@17 105 '@entity_type' => $this->entityTypeManager->getDefinition('block_content')->getSingularLabel(),
Chris@17 106 ]),
Chris@17 107 '#attributes' => $this->getAjaxAttributes(),
Chris@17 108 ];
Chris@17 109 $build['add_block']['#attributes']['class'][] = 'inline-block-create-button';
Chris@17 110 }
Chris@17 111 }
Chris@14 112
Chris@17 113 $block_categories['#type'] = 'container';
Chris@17 114 $block_categories['#attributes']['class'][] = 'block-categories';
Chris@17 115
Chris@17 116 // @todo Explicitly cast delta to an integer, remove this in
Chris@17 117 // https://www.drupal.org/project/drupal/issues/2984509.
Chris@17 118 $delta = (int) $delta;
Chris@17 119
Chris@17 120 $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
Chris@17 121 'section_storage' => $section_storage,
Chris@17 122 'delta' => $delta,
Chris@17 123 'region' => $region,
Chris@17 124 ]);
Chris@17 125 $grouped_definitions = $this->blockManager->getGroupedDefinitions($definitions);
Chris@17 126 foreach ($grouped_definitions as $category => $blocks) {
Chris@17 127 $block_categories[$category]['#type'] = 'details';
Chris@17 128 $block_categories[$category]['#open'] = TRUE;
Chris@17 129 $block_categories[$category]['#title'] = $category;
Chris@17 130 $block_categories[$category]['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks);
Chris@17 131 }
Chris@17 132 $build['block_categories'] = $block_categories;
Chris@17 133 return $build;
Chris@17 134 }
Chris@17 135
Chris@17 136 /**
Chris@17 137 * Provides the UI for choosing a new inline block.
Chris@17 138 *
Chris@17 139 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
Chris@17 140 * The section storage.
Chris@17 141 * @param int $delta
Chris@17 142 * The delta of the section to splice.
Chris@17 143 * @param string $region
Chris@17 144 * The region the block is going in.
Chris@17 145 *
Chris@17 146 * @return array
Chris@17 147 * A render array.
Chris@17 148 */
Chris@17 149 public function inlineBlockList(SectionStorageInterface $section_storage, $delta, $region) {
Chris@17 150 $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
Chris@17 151 'section_storage' => $section_storage,
Chris@17 152 'region' => $region,
Chris@17 153 'list' => 'inline_blocks',
Chris@17 154 ]);
Chris@17 155 $blocks = $this->blockManager->getGroupedDefinitions($definitions);
Chris@17 156 $build = [];
Chris@17 157 if (isset($blocks['Inline blocks'])) {
Chris@17 158 $build['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks['Inline blocks']);
Chris@17 159 $build['links']['#attributes']['class'][] = 'inline-block-list';
Chris@17 160 foreach ($build['links']['#links'] as &$link) {
Chris@17 161 $link['attributes']['class'][] = 'inline-block-list__item';
Chris@17 162 }
Chris@17 163 $build['back_button'] = [
Chris@17 164 '#type' => 'link',
Chris@17 165 '#url' => Url::fromRoute('layout_builder.choose_block',
Chris@17 166 [
Chris@17 167 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 168 'section_storage' => $section_storage->getStorageId(),
Chris@17 169 'delta' => $delta,
Chris@17 170 'region' => $region,
Chris@17 171 ]
Chris@17 172 ),
Chris@17 173 '#title' => $this->t('Back'),
Chris@17 174 '#attributes' => $this->getAjaxAttributes(),
Chris@14 175 ];
Chris@14 176 }
Chris@14 177 return $build;
Chris@14 178 }
Chris@14 179
Chris@17 180 /**
Chris@17 181 * Gets a render array of block links.
Chris@17 182 *
Chris@17 183 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
Chris@17 184 * The section storage.
Chris@17 185 * @param int $delta
Chris@17 186 * The delta of the section to splice.
Chris@17 187 * @param string $region
Chris@17 188 * The region the block is going in.
Chris@17 189 * @param array $blocks
Chris@17 190 * The information for each block.
Chris@17 191 *
Chris@17 192 * @return array
Chris@17 193 * The block links render array.
Chris@17 194 */
Chris@17 195 protected function getBlockLinks(SectionStorageInterface $section_storage, $delta, $region, array $blocks) {
Chris@17 196 $links = [];
Chris@17 197 foreach ($blocks as $block_id => $block) {
Chris@17 198 $link = [
Chris@17 199 'title' => $block['admin_label'],
Chris@17 200 'url' => Url::fromRoute('layout_builder.add_block',
Chris@17 201 [
Chris@17 202 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 203 'section_storage' => $section_storage->getStorageId(),
Chris@17 204 'delta' => $delta,
Chris@17 205 'region' => $region,
Chris@17 206 'plugin_id' => $block_id,
Chris@17 207 ]
Chris@17 208 ),
Chris@17 209 'attributes' => $this->getAjaxAttributes(),
Chris@17 210 ];
Chris@17 211
Chris@17 212 $links[] = $link;
Chris@17 213 }
Chris@17 214 return [
Chris@17 215 '#theme' => 'links',
Chris@17 216 '#links' => $links,
Chris@17 217 ];
Chris@17 218 }
Chris@17 219
Chris@17 220 /**
Chris@17 221 * Get dialog attributes if an ajax request.
Chris@17 222 *
Chris@17 223 * @return array
Chris@17 224 * The attributes array.
Chris@17 225 */
Chris@17 226 protected function getAjaxAttributes() {
Chris@17 227 if ($this->isAjax()) {
Chris@17 228 return [
Chris@17 229 'class' => ['use-ajax'],
Chris@17 230 'data-dialog-type' => 'dialog',
Chris@17 231 'data-dialog-renderer' => 'off_canvas',
Chris@17 232 ];
Chris@17 233 }
Chris@17 234 return [];
Chris@17 235 }
Chris@17 236
Chris@14 237 }