function Block::blockForm

Same name and namespace in other branches
  1. 4.0.x modules/ctools_views/src/Plugin/Display/Block.php \Drupal\ctools_views\Plugin\Display\Block::blockForm()

Adds the configuration form elements specific to this views block plugin.

This method allows block instances to override the views items_per_page.

Parameters

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

array $form: The form definition array for the block configuration form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The renderable form array representing the entire configuration form.

Overrides Block::blockForm

File

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

Class

Block
Provides a Block display plugin.

Namespace

Drupal\ctools_views\Plugin\Display

Code

public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $form_state) {
  $form = parent::blockForm($block, $form, $form_state);
  $allow_settings = array_filter($this->getOption('allow'));
  $block_configuration = $block->getConfiguration();
  // Modify "Items per page" block settings form.
  if (!empty($allow_settings['items_per_page'])) {
    // Items per page.
    $form['override']['items_per_page']['#type'] = 'number';
    $form['override']['items_per_page']['#min'] = 0;
    unset($form['override']['items_per_page']['#options']);
  }
  // Provide "Pager offset" block settings form.
  if (!empty($allow_settings['offset'])) {
    $form['override']['pager_offset'] = [
      '#type' => 'number',
      '#title' => $this->t('Pager offset'),
      '#default_value' => $block_configuration['pager_offset'] ?? 0,
      '#description' => $this->t('For example, set this to 3 and the first 3 items will not be displayed.'),
    ];
  }
  // Provide "Pager type" block settings form.
  if (!empty($allow_settings['pager'])) {
    $pager_options = [
      'view' => $this->t('Inherit from view'),
      'some' => $this->t('Display a specified number of items'),
      'none' => $this->t('Display all items'),
    ];
    $form['override']['pager'] = [
      '#type' => 'radios',
      '#title' => $this->t('Pager'),
      '#options' => $pager_options,
      '#default_value' => $block_configuration['pager'] ?? 'view',
    ];
  }
  // Provide "Hide fields" / "Reorder fields" block settings form.
  if (!empty($allow_settings['hide_fields']) || !empty($allow_settings['sort_fields'])) {
    // Set up the configuration table for hiding / sorting fields.
    $fields = $this->getHandlers('field');
    $header = [];
    if (!empty($allow_settings['hide_fields'])) {
      $header['hide'] = $this->t('Hide');
    }
    $header['label'] = $this->t('Label');
    if (!empty($allow_settings['sort_fields'])) {
      $header['weight'] = $this->t('Weight');
    }
    $form['override']['order_fields'] = [
      '#type' => 'table',
      '#header' => $header,
      '#rows' => [],
    ];
    if (!empty($allow_settings['sort_fields'])) {
      $form['override']['order_fields']['#tabledrag'] = [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'field-weight',
        ],
      ];
      $form['override']['order_fields']['#attributes'] = [
        'id' => 'order-fields',
      ];
    }
    // Sort available field plugins by their currently configured weight.
    $sorted_fields = [];
    if (!empty($allow_settings['sort_fields']) && isset($block_configuration['fields'])) {
      uasort($block_configuration['fields'], '\\Drupal\\ctools_views\\Plugin\\Display\\Block::sortFieldsByWeight');
      foreach (array_keys($block_configuration['fields']) as $field_name) {
        if (!empty($fields[$field_name])) {
          $sorted_fields[$field_name] = $fields[$field_name];
          unset($fields[$field_name]);
        }
      }
      if (!empty($fields)) {
        foreach ($fields as $field_name => $field_info) {
          $sorted_fields[$field_name] = $field_info;
        }
      }
    }
    else {
      $sorted_fields = $fields;
    }
    // Add each field to the configuration table.
    foreach ($sorted_fields as $field_name => $plugin) {
      $field_label = $plugin->adminLabel();
      if (!empty($plugin->options['label'])) {
        $field_label .= ' (' . $plugin->options['label'] . ')';
      }
      if (!empty($allow_settings['sort_fields'])) {
        $form['override']['order_fields'][$field_name]['#attributes']['class'][] = 'draggable';
      }
      $form['override']['order_fields'][$field_name]['#weight'] = !empty($block_configuration['fields'][$field_name]['weight']) ? $block_configuration['fields'][$field_name]['weight'] : 0;
      if (!empty($allow_settings['hide_fields'])) {
        $form['override']['order_fields'][$field_name]['hide'] = [
          '#type' => 'checkbox',
          '#default_value' => !empty($block_configuration['fields'][$field_name]['hide']) ? $block_configuration['fields'][$field_name]['hide'] : 0,
        ];
      }
      $form['override']['order_fields'][$field_name]['label'] = [
        '#markup' => $field_label,
      ];
      if (!empty($allow_settings['sort_fields'])) {
        $form['override']['order_fields'][$field_name]['weight'] = [
          '#type' => 'weight',
          '#title' => $this->t('Weight for @title', [
            '@title' => $field_label,
          ]),
          '#title_display' => 'invisible',
          '#delta' => 50,
          '#default_value' => !empty($block_configuration['fields'][$field_name]['weight']) ? $block_configuration['fields'][$field_name]['weight'] : 0,
          '#attributes' => [
            'class' => [
              'field-weight',
            ],
          ],
        ];
      }
    }
  }
  // Provide "Configure filters" form elements.
  if (!empty($allow_settings['configure_filters'])) {
    $view_exposed_input = $block_configuration['exposed'];
    foreach ($block_configuration['exposed'] as $inner_input) {
      $view_exposed_input += $inner_input;
    }
    $this->view
      ->setExposedInput($view_exposed_input);
    $exposed_form_state = new FormState();
    $exposed_form_state->setValidationEnforced();
    $exposed_form_state->set('view', $this->view);
    $exposed_form_state->set('display', $this->view->current_display);
    $exposed_form_state->setUserInput($this->view
      ->getExposedInput());
    // Let form plugins know this is for exposed widgets.
    $exposed_form_state->set('exposed', TRUE);
    $exposed_form = [];
    $exposed_form['#info'] = [];
    // Initialize filter and sort handlers so that the exposed form alter
    // method works as expected.
    $this->view->filter = $this->getHandlers('filter');
    $this->view->sort = $this->getHandlers('sort');
    $form['exposed'] = [
      '#tree' => TRUE,
      '#title' => $this->t('Exposed filter values'),
      '#description' => $this->t('If a value is set for an exposed filter, it will be removed from the block display.'),
      '#type' => 'details',
      '#open' => TRUE,
    ];
    // Go through each handler and let it generate its exposed widget.
    /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface $handler */
    foreach ($this->view
      ->getDisplay()
      ->getHandlers('filter') as $id => $handler) {
      // If the current handler is exposed...
      if ($handler->canExpose() && $handler->isExposed()) {
        $filter_key = "filter-{$id}";
        // Create a panel for the exposed handler.
        $form['exposed'][$filter_key] = [
          '#type' => 'item',
          '#id' => Html::getUniqueId('views-exposed-pane'),
        ];
        $info = $handler->exposedInfo();
        // @todo This can result in double titles for group filters.
        if (!empty($info['label'])) {
          $form['exposed'][$filter_key]['#title'] = $info['label'];
        }
        // If the current filter has a value saved in block configuration...
        if (isset($block_configuration['exposed'][$filter_key])) {
          $identifier = $handler->options['expose']['identifier'];
          $this->mapConfigToHandler($handler, $block_configuration['exposed'][$filter_key]);
        }
        // Grouped exposed filters have their own forms. Instead of rendering
        // the standard exposed form, a new Select or Radio form field is
        // rendered with the available groups. When a user chooses an option
        // the selected value is split into the operator and value that the
        // item represents.
        if ($handler->isAGroup()) {
          $handler->groupForm($form['exposed'][$filter_key], $exposed_form_state);
          $id = $handler->options['group_info']['identifier'];
        }
        else {
          $handler->buildExposedForm($form['exposed'][$filter_key], $exposed_form_state);
          $form_field_present = isset($form['exposed'][$filter_key][$id]);
          $block_config_present = isset($block_configuration['exposed'][$filter_key]);
          $form_field_type = $form_field_present ? $form['exposed'][$filter_key][$id]['#type'] : FALSE;
          $filter_plugin_id = $block_config_present ? $block_configuration['exposed'][$filter_key]['plugin_id'] : FALSE;
          if ($form_field_present && $block_config_present) {
            if ($form_field_type == 'select') {
              // Single-value select elements get their default value set to
              // 'All' in buildExposedForm(), when that option is added, so set
              // thir defaults manually.
              $form['exposed'][$filter_key][$id]['#default_value'] = $block_configuration['exposed'][$filter_key]['value'] ?? NULL;
            }
            else {
              if ($form_field_type == 'entity_autocomplete' && $filter_plugin_id == 'taxonomy_index_tid') {
                // Entity reference autocomplete fields need their values
                // converted back to a string for the textfield input.
                $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')
                  ->loadMultiple($block_configuration['exposed'][$filter_key]['value']);
                $form['exposed'][$filter_key][$id]['#default_value'] = EntityAutocomplete::getEntityLabels($terms);
              }
            }
          }
        }
        $form['exposed'][$filter_key]['exposed'] = [
          '#type' => 'checkbox',
          '#title' => $this->t('Expose filter value to user'),
          '#description' => $this->t('Expose this filter value to visitors? If so, the value set here will be the default.'),
          '#default_value' => $block_configuration['exposed'][$filter_key]['exposed'] ?? FALSE,
        ];
        $handler_use_operator = !empty($handler->options['expose']['use_operator']);
        // If ''use_operator' is tru on the handler, let the admin decide to
        // expose it to the user.
        if ($handler_use_operator) {
          $form['exposed'][$filter_key]['use_operator'] = [
            '#type' => 'checkbox',
            '#title' => $this->t('Expose filter operator to user'),
            '#description' => $this->t("Expose this filter's operator to visitors? If so, the operator set here will be the default."),
            '#default_value' => $block_configuration['exposed'][$filter_key]['expose']['use_operator'] ?? $handler_use_operator,
            '#states' => [
              // Hide the operator form element until the value is exposed.
'invisible' => [
                ':input[name="settings[exposed][' . $filter_key . '][exposed]"]' => [
                  'checked' => FALSE,
                ],
              ],
            ],
          ];
        }
        if ($info) {
          $exposed_form['#info'][$filter_key] = $info;
        }
      }
    }
    // If there are no exposed filters, then we don't need the parent element.
    if (!count(Element::children($form['exposed']))) {
      unset($form['exposed']);
    }
  }
  if (!empty($allow_settings['disable_filters'])) {
    $filters = $this->getHandlers('filter');
    // Add a settings form for each exposed filter to configure or hide it.
    foreach ($filters as $filter_name => $plugin) {
      if ($plugin->isExposed() && ($exposed_info = $plugin->exposedInfo())) {
        // Render "Disable filters" settings form.
        if (!empty($allow_settings['disable_filters'])) {
          $form['override']['filters'][$filter_name]['disable'] = [
            '#type' => 'checkbox',
            '#title' => $this->t('Disable filter: @handler', [
              '@handler' => $plugin->options['expose']['label'],
            ]),
            '#default_value' => !empty($block_configuration['filter'][$filter_name]['disable']) ? $block_configuration['filter'][$filter_name]['disable'] : 0,
          ];
        }
      }
    }
  }
  // Provide "Configure sorts" block settings form.
  if (!empty($allow_settings['configure_sorts'])) {
    $sorts = $this->getHandlers('sort');
    $options = [
      'ASC' => $this->t('Sort ascending'),
      'DESC' => $this->t('Sort descending'),
    ];
    foreach ($sorts as $sort_name => $plugin) {
      $form['override']['sort'][$sort_name] = [
        '#type' => 'details',
        '#title' => $plugin->adminLabel(),
      ];
      $form['override']['sort'][$sort_name]['plugin'] = [
        '#type' => 'value',
        '#value' => $plugin,
      ];
      $form['override']['sort'][$sort_name]['order'] = [
        '#title' => $this->t('Order'),
        '#type' => 'radios',
        '#options' => $options,
        '#default_value' => $plugin->options['order'],
      ];
      // Set default values for sorts for this block.
      if (!empty($block_configuration["sort"][$sort_name])) {
        $form['override']['sort'][$sort_name]['order']['#default_value'] = $block_configuration["sort"][$sort_name];
      }
    }
  }
  return $form;
}