You are here

public function ExposedGroups::buildOptionsForm in Views exposed groups 3.0.x

Provide a form to edit options for this plugin.

Overrides ExposedFormPluginBase::buildOptionsForm

File

src/Plugin/views/exposed_form/ExposedGroups.php, line 47

Class

ExposedGroups
Provides an views exposed form plugin that groups filters.

Namespace

Drupal\views_exposed_groups\Plugin\views\exposed_form

Code

public function buildOptionsForm(&$form, FormStateInterface $form_state) {
  parent::buildOptionsForm($form, $form_state);
  $form['exposed_groups'] = [
    '#tree' => FALSE,
    '#attributes' => [
      'id' => 'views-exposed-groups-settings-wrapper',
    ],
  ];
  $form['exposed_groups']['format'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Render groups as'),
    '#description' => $this
      ->t('Choose the way that the grouped filters will be displayed.'),
    '#parents' => [
      'exposed_form_options',
      'exposed_groups_format',
    ],
    '#options' => [
      'vertical_tabs' => $this
        ->t('Vertical tabs'),
      'fieldsets_collapsed' => $this
        ->t('Fieldsets (collapsed)'),
      'fieldsets' => $this
        ->t('Fieldsets (expanded)'),
    ],
    '#default_value' => $this->options['exposed_groups_format'],
  ];
  $form['exposed_groups']['vertical_tabs_summary'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Use vertical tabs summaries'),
    '#description' => $this
      ->t('Enable this option to display a summary of filters on the vertical tab link.'),
    '#parents' => [
      'exposed_form_options',
      'exposed_groups_vertical_tabs_summary',
    ],
    '#options' => [
      0 => $this
        ->t('Do not add summaries'),
      1 => $this
        ->t('Add summaries'),
    ],
    '#default_value' => (int) $this->options['exposed_groups_vertical_tabs_summary'],
    '#states' => [
      'visible' => [
        [
          ':input[name="exposed_form_options[exposed_groups_format]"]' => [
            'value' => 'vertical_tabs',
          ],
        ],
      ],
    ],
  ];

  // Assembles the groups and filters as a table with tabledrag support.
  $headers = [
    [
      'data' => $this
        ->t('Filter'),
    ],
    [
      'data' => $this
        ->t('Group'),
    ],
    [
      'data' => $this
        ->t('Weight'),
    ],
  ];
  $form['exposed_groups']['groups'] = [
    '#type' => 'table',
    '#header' => $headers,
    '#empty' => $this
      ->t('This view does not have any filters.'),
    '#attributes' => [
      'id' => 'views-exposed-groups-table',
    ],
    '#tabledrag' => [],
    '#parents' => [
      'exposed_form_options',
      'groups',
    ],
  ];
  $allFilters = $this->displayHandler
    ->getHandlers('filter');
  $filters = array_filter($allFilters, function (ViewsHandlerInterface $filter) {

    // @todo Refactor to use PHP 7.4 arrow functions when Drupal requires 7.4.
    return $filter
      ->isExposed();
  });
  $weight_delta = round(count($filters) / 2);
  $groups = $this->options['exposed_groups'];
  foreach ($groups as $group) {
    $group_name_class_replace = Xss::filter(str_replace('_', '-', $group['name']));
    $form['exposed_groups']['groups']['#tabledrag'][] = [
      'action' => 'match',
      'relationship' => 'sibling',
      'group' => 'filter-group-select',
      'subgroup' => 'filter-group-' . $group_name_class_replace,
      'hidden' => TRUE,
      'limit' => FALSE,
    ];
    $form['exposed_groups']['groups']['#tabledrag'][] = [
      'action' => 'order',
      'relationship' => 'sibling',
      'group' => 'filter-weight',
      'subgroup' => 'filter-weight-' . $group_name_class_replace,
    ];
    $form['exposed_groups']['groups'][$group['name']] = [
      '#attributes' => [
        'colspan' => 4,
        'class' => [
          'tabledrag-root',
        ],
        'no_striping' => TRUE,
      ],
    ];
    if ($group['name'] === '_none') {
      $form['exposed_groups']['groups']['_none']['title'] = [
        '#plain_text' => $this
          ->t('Not grouped'),
      ];
      $form['exposed_groups']['groups'][$group['name']]['#weight'] = 999;
    }
    else {
      $form['exposed_groups']['groups'][$group['name']]['title'] = [
        '#prefix' => Xss::filter($group['label']),
        '#type' => 'button',
        '#value' => $this
          ->t('Remove group'),
      ];
    }
  }
  $default_group = array_reduce($groups, function (&$result, $group) {
    if ($result !== NULL && $group['name'] === '_none') {
      return $group;
    }
    return $result;
  }, NULL);
  $group_options = [];
  foreach ($groups as $index => $group) {
    $group_options[$group['name']] = $group['label'] !== NULL ? Xss::filter($group['label']) : $this
      ->t('Not grouped');
  }

  /* @var \Drupal\views\Plugin\views\filter\FilterPluginBase $filter */
  foreach ($filters as $filter_name => $filter) {
    $id = $filter->options['expose']['identifier'];

    // Filter is not escaped until t() or Xss::filter() is called.
    $label = $filter->options['expose']['label'];
    $group = $default_group;
    foreach ($groups as $gindex => $g) {
      foreach ($g['filters'] as $f) {
        if ($f['id'] === $id) {
          $group = $g;
        }
      }
    }
    $group_name = $group['name'];
    $group_name_class = Xss::filter(str_replace('_', '-', $group_name));
    $grouped_filter = NULL;
    if ($group['filters'] !== NULL) {
      $grouped_filter = array_reduce($group['filters'], function (&$result, array $f) use ($id) {
        if ($result !== NULL && $f['id'] === $id) {
          return $f;
        }
        return $result;
      }, NULL);
    }
    $grouped_filter = $grouped_filter !== NULL ? $grouped_filter : [
      'id' => $id,
      'weight' => 0,
    ];
    $weight = $grouped_filter['weight'];
    $form['exposed_groups']['groups']['filter-' . $id] = [
      '#attributes' => [
        'class' => [
          'draggable',
          'tabledrag-leaf',
        ],
      ],
      '#tree' => TRUE,
      '#parents' => [
        'exposed_form_options',
        'filters',
        $id,
      ],
      'filter' => [
        'id' => [
          '#type' => 'value',
          '#value' => $id,
        ],
        'title' => [
          '#plain_text' => $label,
        ],
      ],
      'group' => [
        '#type' => 'select',
        '#title' => $this
          ->t('Group'),
        '#title_display' => 'invisible',
        '#attributes' => [
          'class' => [
            'filter-group-select',
            'filter-group-' . $group_name_class,
          ],
        ],
        '#options' => $group_options,
      ],
      'weight' => [
        '#type' => 'weight',
        '#title' => $this
          ->t('Weight for @label', [
          '@label' => $label,
        ]),
        '#title_display' => 'invisible',
        '#delta' => $weight_delta,
        '#filter_field' => $filter,
        '#default_value' => $weight,
        '#attributes' => [
          'class' => [
            'filter-weight',
            'filter-weight-' . $group_name_class,
          ],
        ],
      ],
    ];
  }

  // Add another group button.
  $groups_value = '';
  foreach ($this->options['exposed_groups'] as $group_weight => $group) {
    $groups_value .= ($group['name'] !== '_none' ? $group['label'] : '_none') . "\n";
  }
  $groups_value = trim($groups_value);
  $form['exposed_groups']['manage_groups'] = [
    '#tree' => TRUE,
    'groups' => [
      '#type' => 'textarea',
      '#title' => $this
        ->t('Groups'),
      '#rows' => 5,
      '#columns' => 40,
      '#default_value' => Html::escape($groups_value),
      '#element_validate' => [
        [
          $this,
          'updateGroupsValidate',
        ],
      ],
    ],
  ];
}