From 3165ccef8c05657189efc745c1fad60e7fb4e8af Mon Sep 17 00:00:00 2001
From: Mariano D'Agostino <dagmar@154086.no-reply.drupal.org>
Date: Wed, 8 Aug 2012 09:42:15 -0300
Subject: [PATCH] Issue #873872 by dagmar, tim.plunkett: Allow to limit which
 exposed operators apply

---
 handlers/views_handler_filter.inc         |   41 +++++++++++++++++
 handlers/views_handler_filter_numeric.inc |   70 +++++++++++++++++++++--------
 2 files changed, 92 insertions(+), 19 deletions(-)

diff --git a/handlers/views_handler_filter.inc b/handlers/views_handler_filter.inc
index 9f96a5c..85b60e3 100644
--- a/handlers/views_handler_filter.inc
+++ b/handlers/views_handler_filter.inc
@@ -116,6 +116,8 @@ class views_handler_filter extends views_handler {
         'label' => array('default' => '', 'translatable' => TRUE),
         'use_operator' => array('default' => FALSE, 'bool' => TRUE),
         'operator' => array('default' => ''),
+        'limit_operators' => array('default' => FALSE, 'bool' => TRUE),
+        'available_operators' => array('default' => array()),
         'identifier' => array('default' => ''),
         'required' => array('default' => FALSE, 'bool' => TRUE),
         'remember' => array('default' => FALSE, 'bool' => TRUE),
@@ -248,7 +250,12 @@ class views_handler_filter extends views_handler {
       $this->value_submit($form, $form_state);
     }
     if (!empty($this->options['exposed'])) {
+      $options = &$form_state['values']['options']['expose'];
+      $options['available_operators'] = !empty($options['limit_operators']) ? array_filter($options['available_operators']) : array();
       $this->expose_submit($form, $form_state);
+      if (empty($options['use_operator'])) {
+        $options['limit_operators'] = array();
+      }
     }
     if ($this->is_a_group()) {
       $this->build_group_submit($form, $form_state);
@@ -275,6 +282,14 @@ class views_handler_filter extends views_handler {
   function operator_form(&$form, &$form_state) {
     $options = $this->operator_options();
     if (!empty($options)) {
+      $limit = array_filter($this->options['expose']['available_operators']);
+      if (!empty($this->options['expose']['limit_operators']) && count($limit)) {
+        foreach ($options as $key => $value) {
+          if (!isset($limit[$key])) {
+            unset($options[$key]);
+          }
+        }
+      }
       $form['operator'] = array(
         '#type' => count($options) < 10 ? 'radios' : 'select',
         '#title' => t('Operator'),
@@ -474,6 +489,32 @@ class views_handler_filter extends views_handler {
         '#title' => t('Required'),
         '#default_value' => $this->options['expose']['required'],
       );
+      $operator_options = $this->operator_options();
+      $form['expose']['limit_operators'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Limit operators'),
+        '#description' => t('When checked, the operator will be exposed to the user'),
+        '#default_value' => !empty($this->options['expose']['limit_operators']),
+        '#dependency' => array(
+          'edit-options-expose-use-operator' => array(1)
+        ),
+        '#description' => t('Restrict which operators will be available to select in the exposed operator form.'),
+        '#access' => count($operator_options) > 0,
+      );
+      if (count($operator_options)) {
+        $form['expose']['available_operators'] = array(
+          '#type' => 'checkboxes',
+          '#title' => t('Limit the exposed operators'),
+          '#default_value' => $this->options['expose']['available_operators'],
+          '#prefix' => '<div id="edit-options-expose-available-operators-wrapper"><div id="edit-options-expose-available-operators">',
+          '#suffix' => '</div></div>',
+          '#description' => t('Select which operators will be available to select in the exposed operator form. If none are selected, all the operators listed here will be used.'),
+          '#options' => $operator_options,
+          '#dependency' => array(
+            'edit-options-expose-limit-operators' => array(1)
+          ),
+        );
+      }
     }
     else {
       $form['expose']['required'] = array(
diff --git a/handlers/views_handler_filter_numeric.inc b/handlers/views_handler_filter_numeric.inc
index 982abd8..f9feab4 100644
--- a/handlers/views_handler_filter_numeric.inc
+++ b/handlers/views_handler_filter_numeric.inc
@@ -144,23 +144,51 @@ class views_handler_filter_numeric extends views_handler_filter {
     // not rendered, we can't render dependencies; instead we only
     // render the form items we need.
     $which = 'all';
+    $limit_operators = !empty($this->options['expose']['limit_operators']) && (count($this->options['expose']['available_operators']) > 0);
+    $use_value = FALSE;
+    $use_minmax = FALSE;
     if (!empty($form['operator'])) {
       $source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator';
     }
 
     if (!empty($form_state['exposed'])) {
+      $operator_values_with_1_values = $this->operator_values(1);
+      $operator_values_with_2_values = $this->operator_values(2);
+      if ($limit_operators) {
+        // If limit operators is enabled, check that at least one operator
+        // with two values is enabled to display the min max widgets
+        foreach ($operator_values_with_2_values as $operator) {
+          if (isset($this->options['expose']['available_operators'][$operator])) {
+            $use_minmax = TRUE;
+            break;
+          }
+        }
+        // the same for operators with one value
+        foreach ($operator_values_with_1_values as $operator) {
+          if (isset($this->options['expose']['available_operators'][$operator])) {
+            $use_value = TRUE;
+            break;
+          }
+        }
+      }
+      else {
+        $use_minmax = $use_value = TRUE;
+      }
       $identifier = $this->options['expose']['identifier'];
 
       if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
         // exposed and locked.
-        $which = in_array($this->operator, $this->operator_values(2)) ? 'minmax' : 'value';
+        $which = in_array($this->operator, $operator_values_with_2_values) ? 'minmax' : 'value';
       }
       else {
         $source = 'edit-' . drupal_html_id($this->options['expose']['operator_id']);
       }
     }
+    else {
+      $use_minmax = $use_value = TRUE;
+    }
 
-    if ($which == 'all') {
+    if ($which == 'all' && $use_value) {
       $form['value']['value'] = array(
         '#type' => 'textfield',
         '#title' => empty($form_state['exposed']) ? t('Value') : '',
@@ -172,7 +200,7 @@ class views_handler_filter_numeric extends views_handler_filter {
         $form_state['input'][$identifier]['value'] = $this->value['value'];
       }
     }
-    elseif ($which == 'value') {
+    elseif ($which == 'value' && $use_value) {
       // When exposed we drop the value-value and just do value if
       // the operator is locked.
       $form['value'] = array(
@@ -187,29 +215,33 @@ class views_handler_filter_numeric extends views_handler_filter {
     }
 
     if ($which == 'all' || $which == 'minmax') {
-      $form['value']['min'] = array(
-        '#type' => 'textfield',
-        '#title' => empty($form_state['exposed']) ? t('Min') : '',
-        '#size' => 30,
-        '#default_value' => $this->value['min'],
-      );
-      $form['value']['max'] = array(
-        '#type' => 'textfield',
-        '#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
-        '#size' => 30,
-        '#default_value' => $this->value['max'],
-      );
+      if ($use_minmax) {
+        $form['value']['min'] = array(
+          '#type' => 'textfield',
+          '#title' => empty($form_state['exposed']) ? t('Min') : '',
+          '#size' => 30,
+          '#default_value' => $this->value['min'],
+        );
+        $form['value']['max'] = array(
+          '#type' => 'textfield',
+          '#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
+          '#size' => 30,
+          '#default_value' => $this->value['max'],
+        );
+      }
       if ($which == 'all') {
         $dependency = array(
           '#dependency' => array($source => $this->operator_values(2)),
         );
-        $form['value']['min'] += $dependency;
-        $form['value']['max'] += $dependency;
+        if ($use_minmax) {
+          $form['value']['min'] += $dependency;
+          $form['value']['max'] += $dependency;
+        }
       }
-      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min'])) {
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min']) && $use_minmax) {
         $form_state['input'][$identifier]['min'] = $this->value['min'];
       }
-      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max'])) {
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max']) && $use_minmax) {
         $form_state['input'][$identifier]['max'] = $this->value['max'];
       }
 
-- 
1.7.9.5

