annotate core/modules/layout_builder/src/Controller/ChooseBlockController.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
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@18 9 use Drupal\Core\Session\AccountInterface;
Chris@17 10 use Drupal\Core\StringTranslation\StringTranslationTrait;
Chris@14 11 use Drupal\Core\Url;
Chris@14 12 use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
Chris@18 13 use Drupal\layout_builder\LayoutBuilderHighlightTrait;
Chris@14 14 use Drupal\layout_builder\SectionStorageInterface;
Chris@14 15 use Symfony\Component\DependencyInjection\ContainerInterface;
Chris@14 16
Chris@14 17 /**
Chris@14 18 * Defines a controller to choose a new block.
Chris@14 19 *
Chris@14 20 * @internal
Chris@18 21 * Controller classes are internal.
Chris@14 22 */
Chris@14 23 class ChooseBlockController implements ContainerInjectionInterface {
Chris@14 24
Chris@14 25 use AjaxHelperTrait;
Chris@14 26 use LayoutBuilderContextTrait;
Chris@18 27 use LayoutBuilderHighlightTrait;
Chris@17 28 use StringTranslationTrait;
Chris@14 29
Chris@14 30 /**
Chris@14 31 * The block manager.
Chris@14 32 *
Chris@14 33 * @var \Drupal\Core\Block\BlockManagerInterface
Chris@14 34 */
Chris@14 35 protected $blockManager;
Chris@14 36
Chris@14 37 /**
Chris@17 38 * The entity type manager.
Chris@17 39 *
Chris@17 40 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
Chris@17 41 */
Chris@17 42 protected $entityTypeManager;
Chris@17 43
Chris@17 44 /**
Chris@18 45 * The current user.
Chris@18 46 *
Chris@18 47 * @var \Drupal\Core\Session\AccountInterface
Chris@18 48 */
Chris@18 49 protected $currentUser;
Chris@18 50
Chris@18 51 /**
Chris@14 52 * ChooseBlockController constructor.
Chris@14 53 *
Chris@14 54 * @param \Drupal\Core\Block\BlockManagerInterface $block_manager
Chris@14 55 * The block manager.
Chris@17 56 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
Chris@17 57 * The entity type manager.
Chris@18 58 * @param \Drupal\Core\Session\AccountInterface $current_user
Chris@18 59 * The current user.
Chris@14 60 */
Chris@18 61 public function __construct(BlockManagerInterface $block_manager, EntityTypeManagerInterface $entity_type_manager, AccountInterface $current_user = NULL) {
Chris@14 62 $this->blockManager = $block_manager;
Chris@17 63 $this->entityTypeManager = $entity_type_manager;
Chris@18 64 if (!$current_user) {
Chris@18 65 @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 66 $current_user = \Drupal::currentUser();
Chris@18 67 }
Chris@18 68 $this->currentUser = $current_user;
Chris@14 69 }
Chris@14 70
Chris@14 71 /**
Chris@14 72 * {@inheritdoc}
Chris@14 73 */
Chris@14 74 public static function create(ContainerInterface $container) {
Chris@14 75 return new static(
Chris@17 76 $container->get('plugin.manager.block'),
Chris@18 77 $container->get('entity_type.manager'),
Chris@18 78 $container->get('current_user')
Chris@14 79 );
Chris@14 80 }
Chris@14 81
Chris@14 82 /**
Chris@14 83 * Provides the UI for choosing a new block.
Chris@14 84 *
Chris@14 85 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
Chris@14 86 * The section storage.
Chris@14 87 * @param int $delta
Chris@14 88 * The delta of the section to splice.
Chris@14 89 * @param string $region
Chris@14 90 * The region the block is going in.
Chris@14 91 *
Chris@14 92 * @return array
Chris@14 93 * A render array.
Chris@14 94 */
Chris@14 95 public function build(SectionStorageInterface $section_storage, $delta, $region) {
Chris@17 96 if ($this->entityTypeManager->hasDefinition('block_content_type') && $types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple()) {
Chris@17 97 if (count($types) === 1) {
Chris@17 98 $type = reset($types);
Chris@17 99 $plugin_id = 'inline_block:' . $type->id();
Chris@17 100 if ($this->blockManager->hasDefinition($plugin_id)) {
Chris@17 101 $url = Url::fromRoute('layout_builder.add_block', [
Chris@17 102 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 103 'section_storage' => $section_storage->getStorageId(),
Chris@17 104 'delta' => $delta,
Chris@17 105 'region' => $region,
Chris@17 106 'plugin_id' => $plugin_id,
Chris@17 107 ]);
Chris@17 108 }
Chris@17 109 }
Chris@17 110 else {
Chris@17 111 $url = Url::fromRoute('layout_builder.choose_inline_block', [
Chris@17 112 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 113 'section_storage' => $section_storage->getStorageId(),
Chris@17 114 'delta' => $delta,
Chris@17 115 'region' => $region,
Chris@17 116 ]);
Chris@17 117 }
Chris@17 118 if (isset($url)) {
Chris@17 119 $build['add_block'] = [
Chris@17 120 '#type' => 'link',
Chris@17 121 '#url' => $url,
Chris@17 122 '#title' => $this->t('Create @entity_type', [
Chris@17 123 '@entity_type' => $this->entityTypeManager->getDefinition('block_content')->getSingularLabel(),
Chris@17 124 ]),
Chris@17 125 '#attributes' => $this->getAjaxAttributes(),
Chris@18 126 '#access' => $this->currentUser->hasPermission('create and edit custom blocks'),
Chris@17 127 ];
Chris@17 128 $build['add_block']['#attributes']['class'][] = 'inline-block-create-button';
Chris@17 129 }
Chris@17 130 }
Chris@14 131
Chris@18 132 $build['filter'] = [
Chris@18 133 '#type' => 'search',
Chris@18 134 '#title' => $this->t('Filter by block name'),
Chris@18 135 '#title_display' => 'invisible',
Chris@18 136 '#size' => 30,
Chris@18 137 '#placeholder' => $this->t('Filter by block name'),
Chris@18 138 '#attributes' => [
Chris@18 139 'class' => ['js-layout-builder-filter'],
Chris@18 140 'title' => $this->t('Enter a part of the block name to filter by.'),
Chris@18 141 ],
Chris@18 142 ];
Chris@18 143
Chris@17 144 $block_categories['#type'] = 'container';
Chris@17 145 $block_categories['#attributes']['class'][] = 'block-categories';
Chris@18 146 $block_categories['#attributes']['class'][] = 'js-layout-builder-categories';
Chris@18 147 $block_categories['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockAddHighlightId($delta, $region);
Chris@17 148
Chris@17 149 // @todo Explicitly cast delta to an integer, remove this in
Chris@17 150 // https://www.drupal.org/project/drupal/issues/2984509.
Chris@17 151 $delta = (int) $delta;
Chris@17 152
Chris@17 153 $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
Chris@17 154 'section_storage' => $section_storage,
Chris@17 155 'delta' => $delta,
Chris@17 156 'region' => $region,
Chris@17 157 ]);
Chris@17 158 $grouped_definitions = $this->blockManager->getGroupedDefinitions($definitions);
Chris@17 159 foreach ($grouped_definitions as $category => $blocks) {
Chris@17 160 $block_categories[$category]['#type'] = 'details';
Chris@18 161 $block_categories[$category]['#attributes']['class'][] = 'js-layout-builder-category';
Chris@17 162 $block_categories[$category]['#open'] = TRUE;
Chris@17 163 $block_categories[$category]['#title'] = $category;
Chris@17 164 $block_categories[$category]['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks);
Chris@17 165 }
Chris@17 166 $build['block_categories'] = $block_categories;
Chris@17 167 return $build;
Chris@17 168 }
Chris@17 169
Chris@17 170 /**
Chris@17 171 * Provides the UI for choosing a new inline block.
Chris@17 172 *
Chris@17 173 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
Chris@17 174 * The section storage.
Chris@17 175 * @param int $delta
Chris@17 176 * The delta of the section to splice.
Chris@17 177 * @param string $region
Chris@17 178 * The region the block is going in.
Chris@17 179 *
Chris@17 180 * @return array
Chris@17 181 * A render array.
Chris@17 182 */
Chris@17 183 public function inlineBlockList(SectionStorageInterface $section_storage, $delta, $region) {
Chris@17 184 $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
Chris@17 185 'section_storage' => $section_storage,
Chris@17 186 'region' => $region,
Chris@17 187 'list' => 'inline_blocks',
Chris@17 188 ]);
Chris@17 189 $blocks = $this->blockManager->getGroupedDefinitions($definitions);
Chris@17 190 $build = [];
Chris@18 191 $inline_blocks_category = (string) $this->t('Inline blocks');
Chris@18 192 if (isset($blocks[$inline_blocks_category])) {
Chris@18 193 $build['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks[$inline_blocks_category]);
Chris@17 194 $build['links']['#attributes']['class'][] = 'inline-block-list';
Chris@17 195 foreach ($build['links']['#links'] as &$link) {
Chris@17 196 $link['attributes']['class'][] = 'inline-block-list__item';
Chris@17 197 }
Chris@17 198 $build['back_button'] = [
Chris@17 199 '#type' => 'link',
Chris@17 200 '#url' => Url::fromRoute('layout_builder.choose_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 ]
Chris@17 207 ),
Chris@17 208 '#title' => $this->t('Back'),
Chris@17 209 '#attributes' => $this->getAjaxAttributes(),
Chris@14 210 ];
Chris@14 211 }
Chris@18 212 $build['links']['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockAddHighlightId($delta, $region);
Chris@14 213 return $build;
Chris@14 214 }
Chris@14 215
Chris@17 216 /**
Chris@17 217 * Gets a render array of block links.
Chris@17 218 *
Chris@17 219 * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
Chris@17 220 * The section storage.
Chris@17 221 * @param int $delta
Chris@17 222 * The delta of the section to splice.
Chris@17 223 * @param string $region
Chris@17 224 * The region the block is going in.
Chris@17 225 * @param array $blocks
Chris@17 226 * The information for each block.
Chris@17 227 *
Chris@17 228 * @return array
Chris@17 229 * The block links render array.
Chris@17 230 */
Chris@17 231 protected function getBlockLinks(SectionStorageInterface $section_storage, $delta, $region, array $blocks) {
Chris@17 232 $links = [];
Chris@17 233 foreach ($blocks as $block_id => $block) {
Chris@18 234 $attributes = $this->getAjaxAttributes();
Chris@18 235 $attributes['class'][] = 'js-layout-builder-block-link';
Chris@17 236 $link = [
Chris@17 237 'title' => $block['admin_label'],
Chris@17 238 'url' => Url::fromRoute('layout_builder.add_block',
Chris@17 239 [
Chris@17 240 'section_storage_type' => $section_storage->getStorageType(),
Chris@17 241 'section_storage' => $section_storage->getStorageId(),
Chris@17 242 'delta' => $delta,
Chris@17 243 'region' => $region,
Chris@17 244 'plugin_id' => $block_id,
Chris@17 245 ]
Chris@17 246 ),
Chris@18 247 'attributes' => $attributes,
Chris@17 248 ];
Chris@17 249
Chris@17 250 $links[] = $link;
Chris@17 251 }
Chris@17 252 return [
Chris@17 253 '#theme' => 'links',
Chris@17 254 '#links' => $links,
Chris@17 255 ];
Chris@17 256 }
Chris@17 257
Chris@17 258 /**
Chris@17 259 * Get dialog attributes if an ajax request.
Chris@17 260 *
Chris@17 261 * @return array
Chris@17 262 * The attributes array.
Chris@17 263 */
Chris@17 264 protected function getAjaxAttributes() {
Chris@17 265 if ($this->isAjax()) {
Chris@17 266 return [
Chris@17 267 'class' => ['use-ajax'],
Chris@17 268 'data-dialog-type' => 'dialog',
Chris@17 269 'data-dialog-renderer' => 'off_canvas',
Chris@17 270 ];
Chris@17 271 }
Chris@17 272 return [];
Chris@17 273 }
Chris@17 274
Chris@14 275 }