class BlockListController

Defines the block list controller.

Hierarchy

Expanded class hierarchy of BlockListController

File

drupal/core/modules/block/lib/Drupal/block/BlockListController.php, line 17
Contains \Drupal\block\BlockListController.

Namespace

Drupal\block
View source
class BlockListController extends ConfigEntityListController implements FormInterface {

  /**
   * The regions containing the blocks.
   *
   * @var array
   */
  protected $regions;

  /**
   * The theme containing the blocks.
   *
   * @var string
   */
  protected $theme;

  /**
   * Overrides \Drupal\Core\Config\Entity\ConfigEntityListController::load().
   */
  public function load() {

    // If no theme was specified, use the current theme.
    if (!$this->theme) {
      $this->theme = $GLOBALS['theme'];
    }

    // Store the region list.
    $this->regions = system_region_list($this->theme, REGIONS_VISIBLE);

    // Load only blocks for this theme, and sort them.
    // @todo Move the functionality of _block_rehash() out of the listing page.
    $entities = _block_rehash($this->theme);
    uasort($entities, 'static::sort');
    return $entities;
  }

  /**
   * Overrides \Drupal\Core\Entity\EntityListController::render().
   */
  public function render($theme = NULL) {

    // If no theme was specified, use the current theme.
    $this->theme = $theme ?: $GLOBALS['theme_key'];
    return drupal_get_form($this);
  }

  /**
   * Sorts active blocks by region then weight; sorts inactive blocks by name.
   */
  protected function sort(Block $a, Block $b) {
    static $regions;

    // We need the region list to correctly order by region.
    if (!isset($regions)) {
      $regions = array_flip(array_keys($this->regions));
      $regions[BLOCK_REGION_NONE] = count($regions);
    }

    // Separate enabled from disabled.
    $status = $b
      ->get('status') - $a
      ->get('status');
    if ($status) {
      return $status;
    }

    // Sort by region (in the order defined by theme .info.yml file).
    $aregion = $a
      ->get('region');
    $bregion = $b
      ->get('region');
    if (!empty($aregion) && !empty($bregion) && ($place = $regions[$aregion] - $regions[$bregion])) {
      return $place;
    }

    // Sort by weight, unless disabled.
    if ($a
      ->get('region') != BLOCK_REGION_NONE) {
      $weight = $a
        ->get('weight') - $b
        ->get('weight');
      if ($weight) {
        return $weight;
      }
    }

    // Sort by label.
    return strcmp($a
      ->label(), $b
      ->label());
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::getFormID().
   */
  public function getFormID() {
    return 'block_admin_display_form';
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::buildForm().
   *
   * Form constructor for the main block administration form.
   */
  public function buildForm(array $form, array &$form_state) {
    $entities = $this
      ->load();
    $form['#attached']['css'][] = drupal_get_path('module', 'block') . '/css/block.admin.css';
    $form['#attached']['library'][] = array(
      'system',
      'drupal.tableheader',
    );
    $form['#attached']['library'][] = array(
      'block',
      'drupal.block',
    );

    // Add a last region for disabled blocks.
    $block_regions_with_disabled = $this->regions + array(
      BLOCK_REGION_NONE => BLOCK_REGION_NONE,
    );
    $form['block_regions'] = array(
      '#type' => 'value',
      '#value' => $block_regions_with_disabled,
    );

    // 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);

    // Build the form tree.
    $form['edited_theme'] = array(
      '#type' => 'value',
      '#value' => $this->theme,
    );
    $form['blocks'] = array(
      '#type' => 'table',
      '#header' => array(
        t('Block'),
        t('Region'),
        t('Weight'),
        t('Operations'),
      ),
      '#attributes' => array(
        'id' => 'blocks',
      ),
    );

    // Build blocks first for each region.
    foreach ($entities as $entity_id => $entity) {
      $definition = $entity
        ->getPlugin()
        ->getPluginDefinition();
      $blocks[$entity
        ->get('region')][$entity_id] = array(
        'admin_label' => $definition['admin_label'],
        'entity_id' => $entity_id,
        'weight' => $entity
          ->get('weight'),
      );
    }

    // Loop over each region and build blocks.
    foreach ($block_regions_with_disabled as $region => $title) {
      $form['blocks']['#tabledrag'][] = array(
        'match',
        'sibling',
        'block-region-select',
        'block-region-' . $region,
        NULL,
        FALSE,
      );
      $form['blocks']['#tabledrag'][] = array(
        'order',
        'sibling',
        'block-weight',
        'block-weight-' . $region,
      );
      $form['blocks'][$region] = array(
        '#attributes' => array(
          'class' => array(
            'region-title',
            'region-title-' . $region,
            'odd',
          ),
          'no_striping' => TRUE,
        ),
      );
      $form['blocks'][$region]['title'] = array(
        '#markup' => $region != BLOCK_REGION_NONE ? $title : t('Disabled'),
        '#wrapper_attributes' => array(
          'colspan' => 5,
        ),
      );
      $form['blocks'][$region . '-message'] = array(
        '#attributes' => array(
          'class' => array(
            'region-message',
            'region-' . $region . '-message',
            empty($blocks[$region]) ? 'region-empty' : 'region-populated',
          ),
        ),
      );
      $form['blocks'][$region . '-message']['message'] = array(
        '#markup' => '<em>' . t('No blocks in this region') . '</em>',
        '#wrapper_attributes' => array(
          'colspan' => 5,
        ),
      );
      if (isset($blocks[$region])) {
        foreach ($blocks[$region] as $info) {
          $entity_id = $info['entity_id'];
          $form['blocks'][$entity_id] = array(
            '#attributes' => array(
              'class' => array(
                'draggable',
              ),
            ),
          );
          $form['blocks'][$entity_id]['info'] = array(
            '#markup' => check_plain($info['admin_label']),
            '#wrapper_attributes' => array(
              'class' => array(
                'block',
              ),
            ),
          );
          $form['blocks'][$entity_id]['region-theme']['region'] = array(
            '#type' => 'select',
            '#default_value' => $region,
            '#empty_value' => BLOCK_REGION_NONE,
            '#title_display' => 'invisible',
            '#title' => t('Region for @block block', array(
              '@block' => $info['admin_label'],
            )),
            '#options' => $this->regions,
            '#attributes' => array(
              'class' => array(
                'block-region-select',
                'block-region-' . $region,
              ),
            ),
            '#parents' => array(
              'blocks',
              $entity_id,
              'region',
            ),
          );
          $form['blocks'][$entity_id]['region-theme']['theme'] = array(
            '#type' => 'hidden',
            '#value' => $this->theme,
            '#parents' => array(
              'blocks',
              $entity_id,
              'theme',
            ),
          );
          $form['blocks'][$entity_id]['weight'] = array(
            '#type' => 'weight',
            '#default_value' => $info['weight'],
            '#delta' => $weight_delta,
            '#title_display' => 'invisible',
            '#title' => t('Weight for @block block', array(
              '@block' => $info['admin_label'],
            )),
            '#attributes' => array(
              'class' => array(
                'block-weight',
                'block-weight-' . $region,
              ),
            ),
          );
          $links['configure'] = array(
            'title' => t('configure'),
            'href' => 'admin/structure/block/manage/' . $entity_id . '/configure',
          );
          $links['delete'] = array(
            'title' => t('delete'),
            'href' => 'admin/structure/block/manage/' . $entity_id . '/delete',
          );
          $form['blocks'][$entity_id]['operations'] = array(
            '#type' => 'operations',
            '#links' => $links,
          );
        }
      }
    }

    // Do not allow disabling the main system content block when it is present.
    if (isset($form['blocks']['system_main']['region'])) {
      $form['blocks']['system_main']['region']['#required'] = TRUE;
    }
    $form['actions'] = array(
      '#tree' => FALSE,
      '#type' => 'actions',
    );
    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Save blocks'),
      '#button_type' => 'primary',
    );
    return $form;
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::validateForm().
   */
  public function validateForm(array &$form, array &$form_state) {

    // No validation.
  }

  /**
   * Implements \Drupal\Core\Form\FormInterface::submitForm().
   *
   * Form submission handler for the main block administration form.
   */
  public function submitForm(array &$form, array &$form_state) {
    $entities = entity_load_multiple('block', array_keys($form_state['values']['blocks']));
    foreach ($entities as $entity_id => $entity) {
      $entity
        ->set('weight', $form_state['values']['blocks'][$entity_id]['weight']);
      $entity
        ->set('region', $form_state['values']['blocks'][$entity_id]['region']);
      if ($entity
        ->get('region') == BLOCK_REGION_NONE) {
        $entity
          ->disable();
      }
      else {
        $entity
          ->enable();
      }
      $entity
        ->save();
    }
    drupal_set_message(t('The block settings have been updated.'));
    cache_invalidate_tags(array(
      'content' => TRUE,
    ));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BlockListController::$regions protected property The regions containing the blocks.
BlockListController::$theme protected property The theme containing the blocks.
BlockListController::buildForm public function Implements \Drupal\Core\Form\FormInterface::buildForm(). Overrides FormInterface::buildForm
BlockListController::getFormID public function Implements \Drupal\Core\Form\FormInterface::getFormID(). Overrides FormInterface::getFormID
BlockListController::load public function Overrides \Drupal\Core\Config\Entity\ConfigEntityListController::load(). Overrides ConfigEntityListController::load
BlockListController::render public function Overrides \Drupal\Core\Entity\EntityListController::render(). Overrides EntityListController::render
BlockListController::sort protected function Sorts active blocks by region then weight; sorts inactive blocks by name.
BlockListController::submitForm public function Implements \Drupal\Core\Form\FormInterface::submitForm(). Overrides FormInterface::submitForm
BlockListController::validateForm public function Implements \Drupal\Core\Form\FormInterface::validateForm(). Overrides FormInterface::validateForm
ConfigEntityListController::getOperations public function Overrides \Drupal\Core\Entity\EntityListController::getOperations(); Overrides EntityListController::getOperations 9
EntityListController::$entityInfo protected property The entity info array.
EntityListController::$entityType protected property The entity type name.
EntityListController::$moduleHandler protected property The module handler to invoke hooks on.
EntityListController::$storage protected property The entity storage controller class.
EntityListController::buildHeader public function Builds the header row for the entity listing. 8
EntityListController::buildOperations public function Builds a renderable list of operation links for the entity. 1
EntityListController::buildRow public function Builds a row for an entity in the entity listing. 8
EntityListController::createInstance public static function Instantiates a new instance of this entity controller. Overrides EntityControllerInterface::createInstance 1
EntityListController::getStorageController public function Implements \Drupal\Core\Entity\EntityListControllerInterface::getStorageController(). Overrides EntityListControllerInterface::getStorageController
EntityListController::__construct public function Constructs a new EntityListController object. 1