function BlockListBuilder::buildBlocksForm

Same name in other branches
  1. 9 core/modules/block/src/BlockListBuilder.php \Drupal\block\BlockListBuilder::buildBlocksForm()
  2. 8.9.x core/modules/block/src/BlockListBuilder.php \Drupal\block\BlockListBuilder::buildBlocksForm()
  3. 10 core/modules/block/src/BlockListBuilder.php \Drupal\block\BlockListBuilder::buildBlocksForm()

Builds the main "Blocks" portion of the form.

Return value

array

1 call to BlockListBuilder::buildBlocksForm()
BlockListBuilder::buildForm in core/modules/block/src/BlockListBuilder.php

File

core/modules/block/src/BlockListBuilder.php, line 154

Class

BlockListBuilder
Defines a class to build a listing of block entities.

Namespace

Drupal\block

Code

protected function buildBlocksForm() {
    // Build blocks first for each region.
    $blocks = [];
    $entities = $this->load();
    
    /** @var \Drupal\block\BlockInterface[] $entities */
    foreach ($entities as $entity_id => $entity) {
        $definition = $entity->getPlugin()
            ->getPluginDefinition();
        $blocks[$entity->getRegion()][$entity_id] = [
            'label' => $entity->label(),
            'entity_id' => $entity_id,
            'weight' => $entity->getWeight(),
            'entity' => $entity,
            'category' => $definition['category'],
            'status' => $entity->status(),
        ];
    }
    $form = [
        '#type' => 'table',
        '#header' => [
            $this->t('Block'),
            $this->t('Category'),
            $this->t('Region'),
            $this->t('Weight'),
            $this->t('Operations'),
        ],
        '#attributes' => [
            'id' => 'blocks',
        ],
    ];
    // Weights range from -delta to +delta, so delta should be at least half
    // of the amount of blocks present. This makes sure all blocks in the same
    // region get a unique weight.
    $weight_delta = round(count($entities) / 2);
    $placement = FALSE;
    if ($this->request->query
        ->has('block-placement')) {
        $placement = $this->request->query
            ->get('block-placement');
        $form['#attached']['drupalSettings']['blockPlacement'] = $placement;
        // Remove the block placement from the current request so that it is not
        // passed on to any redirect destinations.
        $this->request->query
            ->remove('block-placement');
    }
    // Loop over each region and build blocks.
    $regions = $this->systemRegionList($this->getThemeName(), REGIONS_VISIBLE);
    foreach ($regions as $region => $title) {
        $form['#tabledrag'][] = [
            'action' => 'match',
            'relationship' => 'sibling',
            'group' => 'block-region-select',
            'subgroup' => 'block-region-' . $region,
            'hidden' => FALSE,
        ];
        $form['#tabledrag'][] = [
            'action' => 'order',
            'relationship' => 'sibling',
            'group' => 'block-weight',
            'subgroup' => 'block-weight-' . $region,
        ];
        $form['region-' . $region] = [
            '#attributes' => [
                'class' => [
                    'region-title',
                    'region-title-' . $region,
                ],
                'no_striping' => TRUE,
            ],
        ];
        $form['region-' . $region]['title'] = [
            '#theme_wrappers' => [
                'container' => [
                    '#attributes' => [
                        'class' => 'region-title__action',
                    ],
                ],
            ],
            '#prefix' => $title,
            '#type' => 'link',
            '#title' => $this->t('Place block <span class="visually-hidden">in the %region region</span>', [
                '%region' => $title,
            ]),
            '#url' => Url::fromRoute('block.admin_library', [
                'theme' => $this->getThemeName(),
            ], [
                'query' => [
                    'region' => $region,
                ],
            ]),
            '#wrapper_attributes' => [
                'colspan' => 5,
            ],
            '#attributes' => [
                'class' => [
                    'use-ajax',
                    'button',
                    'button--small',
                ],
                'data-dialog-type' => 'modal',
                'data-dialog-options' => Json::encode([
                    'width' => 880,
                ]),
            ],
        ];
        $form['region-' . $region . '-message'] = [
            '#attributes' => [
                'class' => [
                    'region-message',
                    'region-' . $region . '-message',
                    empty($blocks[$region]) ? 'region-empty' : 'region-populated',
                ],
            ],
        ];
        $form['region-' . $region . '-message']['message'] = [
            '#markup' => '<em>' . $this->t('No blocks in this region') . '</em>',
            '#wrapper_attributes' => [
                'colspan' => 5,
            ],
        ];
        if (isset($blocks[$region])) {
            foreach ($blocks[$region] as $info) {
                $entity_id = $info['entity_id'];
                $form[$entity_id] = [
                    '#attributes' => [
                        'class' => [
                            'draggable',
                        ],
                    ],
                ];
                $form[$entity_id]['#attributes']['class'][] = $info['status'] ? 'block-enabled' : 'block-disabled';
                if ($placement && $placement == Html::getClass($entity_id)) {
                    $form[$entity_id]['#attributes']['class'][] = 'color-success';
                    $form[$entity_id]['#attributes']['class'][] = 'js-block-placed';
                }
                $form[$entity_id]['info'] = [
                    '#wrapper_attributes' => [
                        'class' => [
                            'block',
                        ],
                    ],
                ];
                // Ensure that the label is always rendered as plain text. Render
                // array #plain_text key is essentially treated same as @ placeholder
                // in translatable markup.
                if ($info['status']) {
                    $form[$entity_id]['info']['#plain_text'] = $info['label'];
                }
                else {
                    $form[$entity_id]['info']['#markup'] = $this->t('@label (disabled)', [
                        '@label' => $info['label'],
                    ]);
                }
                $form[$entity_id]['type'] = [
                    '#markup' => $info['category'],
                ];
                $form[$entity_id]['region-theme']['region'] = [
                    '#type' => 'select',
                    '#default_value' => $region,
                    '#required' => TRUE,
                    '#title' => $this->t('Region for @block block', [
                        '@block' => $info['label'],
                    ]),
                    '#title_display' => 'invisible',
                    '#options' => $regions,
                    '#attributes' => [
                        'class' => [
                            'block-region-select',
                            'block-region-' . $region,
                        ],
                    ],
                    '#parents' => [
                        'blocks',
                        $entity_id,
                        'region',
                    ],
                ];
                $form[$entity_id]['region-theme']['theme'] = [
                    '#type' => 'hidden',
                    '#value' => $this->getThemeName(),
                    '#parents' => [
                        'blocks',
                        $entity_id,
                        'theme',
                    ],
                ];
                $form[$entity_id]['weight'] = [
                    '#type' => 'weight',
                    '#default_value' => $info['weight'],
                    '#delta' => $weight_delta,
                    '#title' => $this->t('Weight for @block block', [
                        '@block' => $info['label'],
                    ]),
                    '#title_display' => 'invisible',
                    '#attributes' => [
                        'class' => [
                            'block-weight',
                            'block-weight-' . $region,
                        ],
                    ],
                ];
                $form[$entity_id]['operations'] = $this->buildOperations($info['entity']);
            }
        }
    }
    // Do not allow disabling the main system content block when it is present.
    if (isset($form['system_main']['region'])) {
        $form['system_main']['region']['#required'] = TRUE;
    }
    return $form;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.