function Block::preBlockBuild

Allows to change the display settings right before executing the block.

Parameters

\Drupal\views\Plugin\Block\ViewsBlock $block: The block plugin for views displays.

Overrides Block::preBlockBuild

File

modules/ctools_views/src/Plugin/Display/Block.php, line 563

Class

Block
Provides a Block display plugin.

Namespace

Drupal\ctools_views\Plugin\Display

Code

public function preBlockBuild(ViewsBlock $block) {
  parent::preBlockBuild($block);
  $allow_settings = array_filter($this->getOption('allow'));
  $config = $block->getConfiguration();
  [, $display_id] = explode('-', $block->getDerivativeId(), 2);
  // Change pager offset settings based on block configuration.
  if (!empty($allow_settings['offset']) && isset($config['pager_offset'])) {
    $this->view
      ->setOffset($config['pager_offset']);
  }
  // Change pager style settings based on block configuration.
  if (!empty($allow_settings['pager'])) {
    $pager = $this->view->display_handler
      ->getOption('pager');
    if (!empty($config['pager']) && $config['pager'] != 'view') {
      $pager['type'] = $config['pager'];
    }
    $this->view->display_handler
      ->setOption('pager', $pager);
  }
  // Change fields output based on block configuration.
  if (!empty($allow_settings['hide_fields']) || !empty($allow_settings['sort_fields'])) {
    if (!empty($config['fields']) && $this->view
      ->getStyle()
      ->usesFields()) {
      $fields = $this->view
        ->getHandlers('field');
      uasort($config['fields'], '\\Drupal\\ctools_views\\Plugin\\Display\\Block::sortFieldsByWeight');
      $iterate_fields = !empty($allow_settings['sort_fields']) ? $config['fields'] : $fields;
      foreach (array_keys($iterate_fields) as $field_name) {
        // Remove each field in sequence and re-add them to sort
        // appropriately or hide if disabled.
        $this->view
          ->removeHandler($display_id, 'field', $field_name);
        if (empty($allow_settings['hide_fields']) || !empty($allow_settings['hide_fields']) && empty($config['fields'][$field_name]['hide'])) {
          $this->view
            ->addHandler($display_id, 'field', $fields[$field_name]['table'], $fields[$field_name]['field'], $fields[$field_name], $field_name);
        }
      }
    }
  }
  // Change filters output based on block configuration.
  if (!empty($allow_settings['disable_filters'])) {
    $filters = $this->view
      ->getHandlers('filter', $display_id);
    foreach ($filters as $filter_name => $filter) {
      // If we allow disabled filters and this filter is disabled, disable it
      // and continue.
      if (!empty($allow_settings['disable_filters']) && !empty($config["filter"][$filter_name]['disable'])) {
        $this->view
          ->removeHandler($display_id, 'filter', $filter_name);
        // We don't want to needlessly set filter options later.
        unset($config['exposed']['filter-' . $filter_name]);
      }
    }
  }
  // Set an exposed filter value and remove it from the display if set in the
  // block configuration.
  if (!empty($allow_settings['configure_filters'])) {
    // Fetch the current view's exposed filter input from the client request.
    $exposed = $this->view
      ->getExposedInput();
    $denylisted_keys = [
      'form_id',
    ];
    // Filter the exposed filter input to contain only expected keys.
    $exposed = array_filter($exposed, function ($key) use ($denylisted_keys) {
      // Filter out certain keys not related to exposed filters that are
      // known to cause issues.
      return !in_array($key, $denylisted_keys, TRUE);
    }, ARRAY_FILTER_USE_KEY);
    // Loop over the exposed filter settings in the block configuration.
    foreach ($config['exposed'] as $key => $value) {
      // Load the handler related to the exposed filter.
      [$handler_type, $handler_name] = explode('-', $key, 2);
      $handler = $this->view
        ->getDisplay()
        ->getHandler($handler_type, $handler_name);
      // Set exposed filter input directly where they were entered in the
      // block configuration. Otherwise only set them if they haven't been set
      // already.
      if ($handler) {
        if ($handler->isAGroup()) {
          $this->mapConfigToHandler($handler, $value);
        }
        else {
          // Access values with the identifier.
          $identifier = $handler->options['expose']['identifier'];
          // If the value is set from exposed form input, keep it.
          if (!isset($exposed[$identifier])) {
            // Entity reference autocomplete fields need their values
            // submitted either as an array of entities or of arrays in the
            // form ['target_id' => $id].
            if (isset($config['exposed'][$key]['type']) && $config['exposed'][$key]['type'] == 'entity_autocomplete') {
              $exposed[$identifier] = array_map(function ($item) {
                return [
                  'target_id' => $item,
                ];
              }, $value['value']);
            }
            elseif (isset($value['value']['value'])) {
              $exposed[$identifier] = $value['value']['value'];
            }
            else {
              $exposed[$identifier] = $value['value'] ?? NULL;
            }
          }
          // If the operator is set from exposed form input, keep it.
          if ($handler->options['expose']['use_operator']) {
            $operator_id = $handler->options['expose']['operator_id'];
            if (!isset($exposed[$operator_id])) {
              $exposed[$operator_id] = $value['operator'];
            }
          }
        }
        // If the filter is exposed, set a variable to pass that through.
        if (isset($config['exposed'][$key]['exposed']) && $config['exposed'][$key]['exposed']) {
          $handler->options['value_exposed_to_user'] = TRUE;
          // If the operator is exposed, set a variable to pass that through.
          if ($config['exposed'][$key]['expose']['use_operator']) {
            $handler->options['operator_exposed_to_user'] = TRUE;
          }
        }
      }
    }
    // Set the updated exposed filter input array on the View.
    $this->view
      ->setExposedInput($exposed);
  }
  // Change sorts based on block configuration.
  if (!empty($allow_settings['configure_sorts'])) {
    $sorts = $this->view
      ->getHandlers('sort', $display_id);
    foreach ($sorts as $sort_name => $sort) {
      if (!empty($config["sort"][$sort_name])) {
        $sort['order'] = $config["sort"][$sort_name];
        $this->view
          ->setHandler($display_id, 'sort', $sort_name, $sort);
      }
    }
  }
}