You are here

views_exposed_groups_plugin.inc in Views exposed groups 7.2

Same filename and directory in other branches
  1. 7 views/views_exposed_groups_plugin.inc

Provides a grouped form exposed form plugin for View 3.x.

File

views/views_exposed_groups_plugin.inc
View source
<?php

/**
 * @file
 * Provides a grouped form exposed form plugin for View 3.x.
 */
class views_exposed_groups_plugin extends views_plugin_exposed_form_basic {
  function summary_title() {
    return t('Grouped form');
  }
  function option_definition() {
    $options = parent::option_definition();
    $options['views_exposed_groups'] = array(
      'default' => array(
        'groups' => '',
        'format_groups' => 'vertical_tabs',
        'vertical_tabs_summary' => '0',
      ),
    );
    return $options;
  }
  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
    if (isset($form_state['section']) && $form_state['section'] === 'exposed_form_options') {
      $groups = $this
        ->get_group_options($this->options['views_exposed_groups']['groups']);
      $form['views_exposed_groups']['format_groups'] = [
        '#type' => 'select',
        '#title' => t('Render groups as'),
        '#options' => [
          'vertical_tabs' => t('Vertical tabs'),
          'fieldsets_collapsed' => t('Fieldset (collapsed)'),
          'fieldsets' => t('Fieldset (not collapsed)'),
        ],
        '#default_value' => $this->options['views_exposed_groups']['format_groups'],
      ];
      $form['views_exposed_groups']['vertical_tabs_summary'] = [
        '#type' => 'radios',
        '#title' => t('Use vertical tabs summaries'),
        '#description' => t('Enable this option to display a summary of filters on the vertical tab link.'),
        '#options' => [
          0 => t('Do not add summaries'),
          1 => t('Add summaries'),
        ],
        '#default_value' => $this->options['views_exposed_groups']['vertical_tabs_summary'],
      ];
      $form['views_exposed_groups']['groups'] = [
        '#type' => 'textarea',
        '#title' => t('Groups'),
        '#description' => t('Enter a list of groups to include in this form'),
        '#default_value' => $this->options['views_exposed_groups']['groups'],
      ];
      $weight_delta = count($this->display->handler
        ->get_handlers('filter'));
      foreach ($this->display->handler
        ->get_handlers('filter') as $filter_name => $filter) {
        if (!$filter->options['exposed']) {
          continue;
        }
        $label = $filter->options['expose']['identifier'];
        $field_label = $filter->options['expose']['label'] ? $filter->options['expose']['label'] : $label;
        $default_value = isset($this->options['views_exposed_groups']['group-' . $label]) ? $this->options['views_exposed_groups']['group-' . $label]['group'] : 'no-group';
        $default_weight = isset($this->options['views_exposed_groups']['group-' . $label]) ? $this->options['views_exposed_groups']['group-' . $label]['weight'] : 0;
        $form['views_exposed_groups']['group-' . $label]['group'] = [
          '#type' => 'select',
          '#title' => t('Group for @label', [
            '@label' => $field_label,
          ]),
          '#filter_field' => $filter,
          '#options' => $groups,
          '#title_display' => 'invisible',
          '#default_value' => $default_value,
        ];
        $form['views_exposed_groups']['group-' . $label]['filter_name'] = [
          '#type' => 'value',
          '#value' => $filter_name,
        ];
        $form['views_exposed_groups']['group-' . $label]['weight'] = [
          '#type' => 'weight',
          '#title' => t('Weight for @label', [
            '@label' => $field_label,
          ]),
          '#filter_field' => $filter,
          '#delta' => $weight_delta,
          '#title_display' => 'invisible',
          '#default_value' => $default_weight,
        ];
      }
      $form['views_exposed_groups']['#groups'] = $groups;
      $form['views_exposed_groups']['#theme'][] = 'views_exposed_groups_reorder_filter_form';
    }
  }
  function options_submit(&$form, &$form_state) {
    $plugin_values =& $form_state['values']['exposed_form_options']['views_exposed_groups'];

    // Gets the filters on the view.
    $filters = array_reduce($this->display->handler
      ->get_handlers('filter'), function (&$result, $filter) {
      if (!$filter->options['exposed']) {
        return $result;
      }
      $label = $filter->options['expose']['identifier'];
      $result[] = 'group-' . $label;
      return $result;
    }, []);

    // Gets the groups defined in the text area. If it's an empty string, then
    // set to an empty array.
    if (trim($plugin_values['groups']) === '') {
      $groups = [];
    }
    else {
      $groups = $this
        ->get_group_options($plugin_values['groups']);
    }

    // Resets the filter group to no-group if a group was removed during form
    // submission.
    if (!empty($filters)) {
      foreach ($filters as $filter) {
        if (isset($plugin_values[$filter])) {
          $group = $plugin_values[$filter]['group'];
          if (!isset($groups[$group])) {
            $plugin_values[$filter]['group'] = 'no-group';
          }
        }
      }
    }
    parent::options_submit($form, $form_state);
  }

  /*
   * Tweak the exposed filter form to show grouped form options.
   */
  function exposed_form_alter(&$form, &$form_state) {
    parent::exposed_form_alter($form, $form_state);
    if (!isset($form['#attributes']['class'])) {
      $form['#attributes']['class'] = [];
    }
    $form['#attributes']['class'][] = 'views-exposed-form--views-exposed-group';
    if ($this->options['submit_button']) {
      $form['submit']['#value'] = $this->options['submit_button'];
    }

    // @todo Investigate the need for removing a theme hook.
    $form['#theme'] = array(
      '',
    );
    if ($this->options['views_exposed_groups']['format_groups'] == 'vertical_tabs') {
      $form['filters'] = array(
        '#type' => 'vertical_tabs',
        '#weight' => -10,
        '#attached' => [
          'js' => [
            drupal_get_path('module', 'views_exposed_groups') . '/js/views_exposed_groups.js',
            [
              'data' => [
                'viewsExposedGroups' => [
                  'id' => $form['#id'],
                  'options' => $this->options['views_exposed_groups'],
                ],
              ],
              'type' => 'setting',
            ],
          ],
        ],
      );
    }
    else {
      $form['filters'] = array(
        '#weight' => -10,
      );
    }
    $groups = $this
      ->get_group_options($this->options['views_exposed_groups']['groups']);
    foreach ($groups as $key => $group) {
      $form['filters'][$key] = array(
        '#type' => 'fieldset',
        '#title' => $group,
        '#collapsible' => TRUE,
        '#collapsed' => $this->options['views_exposed_groups']['format_groups'] == 'fieldsets_collapsed' ? TRUE : FALSE,
      );
    }

    // Unsets no-group filter as a fieldset.
    unset($form['filters']['no-group']);
    $form['no-group'] = [
      '#weight' => -1,
    ];
    $fields = $this->options['views_exposed_groups'];
    $ignore = [
      'groups',
      'format_groups',
      'vertical_tabs_summary',
    ];
    foreach ($fields as $field => $group) {
      if (in_array($field, $ignore)) {
        continue;
      }
      $field = str_replace('group-', '', $field);

      // Sets a reference to the group in the form.
      if ($group['group'] === 'no-group') {
        $element =& $form['no-group'];
      }
      else {
        $element =& $form['filters'][$group['group']];
      }
      if (isset($form[$field]) && is_array($form[$field])) {
        if ($group['group'] == 'no-group') {
          $element[$field] = $form[$field] + array(
            '#weight' => $group['weight'],
            '#title' => $form['#info']['filter-' . $group['filter_name']]['label'],
          );
        }
        else {
          $element[$field] = $form[$field] + array(
            '#weight' => $group['weight'],
            '#title' => $form['#info']['filter-' . $group['filter_name']]['label'],
          );
        }
      }
      if (isset($form[$field . '_op']) && is_array($form[$field . '_op']) || isset($form[$field]['#tree']) && $form[$field]['#tree']) {
        $element[$field . '_group'] = array(
          '#type' => 'fieldset',
          '#title' => check_plain($form['#info']['filter-' . $field]['label']),
          '#weight' => isset($form['filters'][$group['group']]) ? $form['filters'][$group['group']][$field]['#weight'] : 0,
        );
        $element[$field . '_group'][$field] = $element[$field];
        if (isset($form[$field . '_op'])) {
          $element[$field . '_group'][$field . '_op'] = $form[$field . '_op'];
        }
        $element[$field . '_group'][$field]['#title_display'] = 'invisible';
        $element[$field . '_group'][$field]['#weight'] = 10;
        unset($element[$field]);
        unset($form[$field . '_op']);
      }
      unset($form[$field]);
    }
    if (!empty($this->options['reset_button'])) {
      $form['reset'] = array(
        '#value' => $this->options['reset_button_label'],
        '#type' => 'submit',
      );
    }
  }

  /**
   * Safely retrieve the group options for display.
   *
   * @todo https://www.drupal.org/project/views_exposed_groups/issues/2300219
   *
   * @param string $value
   *   The raw values that need to be exploded and escaped.
   *
   * @return array
   *   An array of options for the select list.
   */
  public function get_group_options($value = '') {
    $groups = explode("\n", $value);

    // Reduce the groups to only valid options.
    $options = array_reduce($groups, function (&$result, $option) {
      $option = trim($option);
      if ($option) {
        $result[] = filter_xss($option, []);
      }
      return $result;
    }, []);
    $options['no-group'] = t('- No group -');
    return $options;
  }

}

Classes

Namesort descending Description
views_exposed_groups_plugin @file Provides a grouped form exposed form plugin for View 3.x.