Mercurial > hg > isophonics-drupal-site
view core/modules/block/src/BlockListBuilder.php @ 19:fa3358dc1485 tip
Add ndrum files
author | Chris Cannam |
---|---|
date | Wed, 28 Aug 2019 13:14:47 +0100 |
parents | af1871eacc83 |
children |
line wrap: on
line source
<?php namespace Drupal\block; use Drupal\Component\Utility\Html; use Drupal\Component\Serialization\Json; use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Form\FormInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Theme\ThemeManagerInterface; use Drupal\Core\Url; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; /** * Defines a class to build a listing of block entities. * * @see \Drupal\block\Entity\Block */ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface { /** * The theme containing the blocks. * * @var string */ protected $theme; /** * The current request. * * @var \Symfony\Component\HttpFoundation\Request */ protected $request; /** * The theme manager. * * @var \Drupal\Core\Theme\ThemeManagerInterface */ protected $themeManager; /** * The form builder. * * @var \Drupal\Core\Form\FormBuilderInterface */ protected $formBuilder; /** * {@inheritdoc} */ protected $limit = FALSE; /** * The messenger. * * @var \Drupal\Core\Messenger\MessengerInterface */ protected $messenger; /** * Constructs a new BlockListBuilder object. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type definition. * @param \Drupal\Core\Entity\EntityStorageInterface $storage * The entity storage class. * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager * The theme manager. * @param \Drupal\Core\Form\FormBuilderInterface $form_builder * The form builder. */ public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, ThemeManagerInterface $theme_manager, FormBuilderInterface $form_builder, MessengerInterface $messenger) { parent::__construct($entity_type, $storage); $this->themeManager = $theme_manager; $this->formBuilder = $form_builder; $this->messenger = $messenger; } /** * {@inheritdoc} */ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { return new static( $entity_type, $container->get('entity_type.manager')->getStorage($entity_type->id()), $container->get('theme.manager'), $container->get('form_builder'), $container->get('messenger') ); } /** * {@inheritdoc} * * @param string|null $theme * (optional) The theme to display the blocks for. If NULL, the current * theme will be used. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. * * @return array * The block list as a renderable array. */ public function render($theme = NULL, Request $request = NULL) { $this->request = $request; $this->theme = $theme; return $this->formBuilder->getForm($this); } /** * {@inheritdoc} */ public function getFormId() { return 'block_admin_display_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form['#attached']['library'][] = 'core/drupal.tableheader'; $form['#attached']['library'][] = 'block/drupal.block'; $form['#attached']['library'][] = 'block/drupal.block.admin'; $form['#attributes']['class'][] = 'clearfix'; // Build the form tree. $form['blocks'] = $this->buildBlocksForm(); $form['actions'] = [ '#tree' => FALSE, '#type' => 'actions', ]; $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save blocks'), '#button_type' => 'primary', ]; return $form; } /** * Builds the main "Blocks" portion of the form. * * @return array */ 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 an 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' => 700, ]), ], ]; $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'] = [ '#plain_text' => $info['status'] ? $info['label'] : $this->t('@label (disabled)', ['@label' => $info['label']]), '#wrapper_attributes' => [ 'class' => ['block'], ], ]; $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; } /** * Gets the name of the theme used for this block listing. * * @return string * The name of the theme. */ protected function getThemeName() { // If no theme was specified, use the current theme. if (!$this->theme) { $this->theme = $this->themeManager->getActiveTheme()->getName(); } return $this->theme; } /** * {@inheritdoc} */ protected function getEntityIds() { return $this->getStorage()->getQuery() ->condition('theme', $this->getThemeName()) ->sort($this->entityType->getKey('id')) ->execute(); } /** * {@inheritdoc} */ public function getDefaultOperations(EntityInterface $entity) { $operations = parent::getDefaultOperations($entity); if (isset($operations['edit'])) { $operations['edit']['title'] = $this->t('Configure'); } if (isset($operations['delete'])) { $operations['delete']['title'] = $this->t('Remove'); } return $operations; } /** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { // No validation. } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $entities = $this->storage->loadMultiple(array_keys($form_state->getValue('blocks'))); /** @var \Drupal\block\BlockInterface[] $entities */ foreach ($entities as $entity_id => $entity) { $entity_values = $form_state->getValue(['blocks', $entity_id]); $entity->setWeight($entity_values['weight']); $entity->setRegion($entity_values['region']); $entity->save(); } $this->messenger->addStatus($this->t('The block settings have been updated.')); } /** * Wraps system_region_list(). */ protected function systemRegionList($theme, $show = REGIONS_ALL) { return system_region_list($theme, $show); } }