You are here

composite_views_filter.module in Composite Views Filter 7

File

composite_views_filter.module
View source
<?php

/**
 * Implements hook_form_FORM_ID_alter() for views_ui_edit_display_form().
 */
function composite_views_filter_form_views_ui_edit_display_form_alter(&$form, &$form_state) {
  if ($form_state['section'] == 'exposed_form_options' && isset($form['options']['exposed_form_options']['bef'])) {
    $filters = $form_state['view']->display_handler
      ->get_option('filters');
    $element =& $form['options']['exposed_form_options']['bef'];
    foreach (element_children($element) as $name) {
      if (isset($filters[$name]) && $filters[$name]['field'] == 'composite_views_filter') {
        $element[$name]['bef_format']['#options'] += array(
          'bef' => t('Checkboxes/Radio Buttons'),
          'bef_links' => t('Links'),
          'bef_hidden' => t('Hidden'),
        );
      }
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for views_ui_config_item_form().
 */
function composite_views_filter_form_views_ui_config_item_form_alter(&$form, &$form_state, $form_id = 'views_ui_config_item_form') {
  $is_cvf_handler = get_class($form_state['handler']) == 'composite_views_filter_handler';

  // Alter CVF handler form.
  if ($is_cvf_handler) {
    $expose =& $form['options']['expose_button'];
    $checkbox =& $expose['checkbox']['checkbox'];
    if (!empty($checkbox['#default_value'])) {
      $checkbox['#disabled'] = TRUE;
    }
    $expose['button']['#access'] = FALSE;
    $expose['markup']['#access'] = FALSE;
  }
  elseif ('filter' == $form_state['type']) {
    $view = $form_state['view'];
    $view
      ->set_display($form_state['display_id']);
    $view
      ->init_handlers();
    if (_composite_views_filter_view_has_composite_filters($view)) {
      $groups = _composite_views_filter_groups($view);
      $classification = _composite_views_filter_classification($view);
      $filter_id = $form_state['id'];
      $group = (string) @$classification[$filter_id];
      $form['options']['composite_views_filter_group'] = array(
        '#type' => 'select',
        '#title' => t('Composite Views Filter Group'),
        '#options' => $groups,
        '#empty_option' => t('-- Always'),
        // '#empty_value' => '',
        '#default_value' => $group,
        '#weight' => -900,
      );
      $form['buttons']['submit']['#submit'][] = 'composite_views_filter_config_item_form_submit';
    }
  }
}

/**
 * Submit handler for views_ui_config_item_form().
 */
function composite_views_filter_config_item_form_submit($form, &$form_state) {
  $view = $form_state['view'];
  $view
    ->set_display($form_state['display_id']);
  $view
    ->init_handlers();
  if ($composite_views_filters = _composite_views_filter_view_has_composite_filters($view)) {
    $filter_id = $form_state['id'];
    $group = $form_state['values']['options']['composite_views_filter_group'];

    // Unset option.
    foreach ($composite_views_filters as $filter_handler) {
      unset($filter_handler->options['composite_views_filter']['classification'][$filter_id]);
    }

    // Set option.
    if ($group) {
      foreach ($composite_views_filters as $filter_handler) {
        $groups = $filter_handler
          ->get_groups();
        if (isset($groups[$group])) {
          $filter_handler->options['composite_views_filter']['classification'][$filter_id] = $group;
          break;
        }
      }
    }

    // Manual save. Not perfect, but probably the simplest way to save one handler
    // in another's submit.
    // @see views_ui_config_item_form_submit()
    foreach ($composite_views_filters as $filter_handler) {
      $view
        ->set_item($form_state['display_id'], $form_state['type'], $filter_handler->options['id'], $filter_handler->options);
    }
    views_ui_cache_set($view);
  }
}

/**
 * Implements hook_views_ui_display_tab_alter().
 */
function composite_views_filter_views_ui_display_tab_alter(&$build, $view, $display_id) {
  $view
    ->init_handlers();
  if ($filter_handlers = _composite_views_filter_view_has_composite_filters($view)) {
    $classification = _composite_views_filter_classification($view);
    foreach (element_children($build['details']['columns']['first']['filters']['fields']) as $field_name) {
      $filter =& $build['details']['columns']['first']['filters']['fields'][$field_name];

      // This is a CVF handler.
      if (isset($filter_handlers[$field_name])) {

        // This is truly nasty, but I need finer control than Views provides.
        // @see composite_views_filter_handler::admin_summary()
        $filter['#link'] = str_replace(t('Global') . ': ' . t('Composite Filter') . ' (', t('Composite Filter') . ': ', $filter['#link']);
      }
      elseif (isset($classification[$field_name])) {
        $filter['#link'] = preg_replace('/>/', '>[<strong>' . $classification[$field_name] . '</strong>] ', $filter['#link'], 1);
      }
      unset($filter);
    }
  }
}

/**
 * Implements hook_views_data().
 */
function composite_views_filter_views_data() {
  $data = array();
  $data['views']['composite_views_filter'] = array(
    'title' => t('Composite Filter'),
    'help' => t('A Composite Filter field will enable you to create groups.'),
    'filter' => array(
      'handler' => 'composite_views_filter_handler',
    ),
  );
  return $data;
}

/**
 * Implements hook_views_pre_build().
 */
function composite_views_filter_views_pre_build(&$view) {
  $view
    ->init_handlers();
  if ($composite_views_filters = _composite_views_filter_view_has_composite_filters($view)) {
    foreach ($composite_views_filters as $filter_handler) {
      $identifier = $filter_handler->options['expose']['identifier'];
      $classification = $filter_handler
        ->get_classification();
      $default_group = $filter_handler->options['composite_views_filter']['default_group'];
      $exposed_input = $view
        ->get_exposed_input();
      if (!isset($exposed_input[$identifier])) {
        $exposed_input[$identifier] = $default_group ?: 'All';
        $view
          ->set_exposed_input($exposed_input);
      }
      $selected_group = isset($exposed_input[$identifier]) ? $exposed_input[$identifier] : FALSE;
      $selected_groups = $selected_group != 'All' ? (array) $selected_group : array();
      foreach ($view->filter as $field_name => $filter) {
        if (isset($classification[$field_name]) && !in_array($classification[$field_name], $selected_groups)) {
          unset($view->filter[$field_name]);
        }
      }
    }
  }
}

/**
 * Implements hook_views_api().
 */
function composite_views_filter_views_api() {
  return array(
    'api' => 3,
  );
}

/**
 * Helper to determine the composite filters of a View.
 */
function _composite_views_filter_view_has_composite_filters($view) {
  $handler = $view->display_handler;
  if (isset($handler->composite_views_filters)) {
    return $handler->composite_views_filters;
  }
  if (empty($view->filter)) {
    $view
      ->init_handlers();
  }
  $filter_handlers = array();
  foreach ($view->filter as $filter_handler) {
    if (get_class($filter_handler) == 'composite_views_filter_handler') {
      $filter_id = $filter_handler->options['id'];
      $filter_handlers[$filter_id] = $filter_handler;
    }
  }
  return $handler->composite_views_filters = $filter_handlers;
}

/**
 * Helper to determine if a View has a composite filter.
 *
 * @deprecated in favor of the plural version.
 */
function _composite_views_filter_view_has_composite_filter($view) {
  $handlers = _composite_views_filter_view_has_composite_filters($view);
  return reset($handlers) ?: FALSE;
}

/**
 * Returns the combined stored groups of a View.
 */
function _composite_views_filter_groups($view) {
  $filter_handlers = _composite_views_filter_view_has_composite_filters($view);
  $groups = array();
  $default_count = 0;
  foreach ($filter_handlers as $filter_handler) {
    $label = $filter_handler->options['expose']['label'] ?: t('Composite Filter !num', array(
      '!num' => ++$default_count,
    ));
    $groups[$label] = $filter_handler
      ->get_groups();
  }
  return $groups;
}

/**
 * Returns the combined stored classification of a View.
 */
function _composite_views_filter_classification($view) {
  $filter_handlers = _composite_views_filter_view_has_composite_filters($view);
  $classification = array();
  foreach ($filter_handlers as $filter_handler) {
    $classification += $filter_handler
      ->get_classification();
  }
  return $classification;
}