Index: content_views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/content_views.inc,v
retrieving revision 1.2.2.11
diff -u -r1.2.2.11 content_views.inc
--- content_views.inc	26 Feb 2007 13:52:04 -0000	1.2.2.11
+++ content_views.inc	28 Feb 2007 15:50:50 -0000
@@ -86,6 +86,10 @@
     }
 
     $filters = module_invoke($module, 'field_settings', 'filters', $field);
+    // if no filter defined, we will add our own "empty / not empty")
+    if (empty($filters)) {
+      $filters = array('default' => array());
+    }
     if (is_array($filters) && count($filters)) {
       $table['filters'] = array();
       foreach ($filters as $key => $filter) {
@@ -102,6 +106,25 @@
           'content_field' => $field,
           'content_field_module' => $module,
         );
+        // add "empty / not empty" operators to the 'default' filter
+        if ($key == 'default') {
+          $operator = array('EMPTY' => t('Is Empty'), 'NEMPTY' => t('Is Not Empty'));
+          if (!is_array($filter['operator'])) {
+            if (function_exists($filter['operator'])) {
+              $init['operator'] = call_user_func($filter['operator']);
+            }
+            else {
+              $init['operator'] = array();
+            }
+          }
+          $init['operator'] = array_merge($init['operator'], $operator);
+
+          // add our own handler, and save the module-defined handler
+          $init['handler'] = 'content_views_filter_handler';
+          if (isset($filter['handler'])) {
+            $init['alt_handler'] = $filter['handler'];
+          }
+        }
         $table['filters'][$main_column['column'] .'_'. $key] = array_merge($filter, $init);
       }
     }
@@ -176,6 +199,99 @@
   return $output;
 }
 
+function content_views_filter_handler($op, $filter, $filterinfo, &$query) {
+  $operator = $filter['operator'];
+
+  // if operator is empty / not empty, deal with it
+  if (in_array($operator, array('EMPTY', 'NEMPTY'))) {
+    content_views_filter_handler_empty($op, $filter, $filterinfo, $query);
+  }
+  // if the field module provided a handler, defer to it
+  elseif (isset($filterinfo['alt_handler']) && function_exists($filterinfo['alt_handler'])) {
+    $filterinfo['handler'] = $filterinfo['alt_handler'];
+    $filterinfo['handler']($op, $filter, $filterinfo, $query);
+  }
+  // default : use views default filter building
+  else {
+    content_views_filter_handler_default($op, $filter, $filterinfo, $query);
+    //views_handler_filter_default($op, $filter, $filterinfo, $query);
+  }
+}
+
+function content_views_filter_handler_empty($op, $filter, $filterinfo, &$query) {
+  $field = $filterinfo['content_field'];
+  $table = $filterinfo['table'];
+  $db_info = $filterinfo['content_db_info'];
+  $main_column = reset($db_info['columns']);
+  $operator = $filter['operator'];
+
+  switch ($main_column['type']) {
+      case 'int':
+      case 'mediumint':
+      case 'tinyint':
+      case 'bigint':
+        $column_placeholder = '%d';
+        break;
+      case 'float':
+        $column_placeholder = '%f';
+        break;
+      default:
+        $column_placeholder = "'%s'";
+  }
+  if (isset($main_column['default'])) {
+    $op = ($operator == 'EMPTY') ? ' = ' : ' != ';
+    $clause = $table .'.'. $main_column['column'] . $op . $column_placeholder;
+    $arg = trim($main_column['default'], "'");
+  }
+  else {
+    $op = ($operator == 'EMPTY') ? ' IS NULL' : ' IS NOT NULL';
+    $clause .= $table .'.'. $main_column['column'] .' IS NULL';
+  }
+  $query->ensure_table($table);
+  $query->add_where($clause , $arg);
+}
+
+function content_views_filter_handler_default($op, $filter, $filterinfo, &$query) {
+  // copy / paste of views default management...
+  // TODO : propose a patch for Views that would defer this in a function call,
+  // and avoid code duplication.
+  $field = $filterinfo['field'];
+  $table = $filterinfo['table'];
+  if (is_array($filter['value']) && count($filter['value'])) {
+    if ($filter['operator'] == 'OR' || $filter['operator'] == 'NOR') {
+      $query->ensure_table($table);
+      $where_args = array_merge(array($query->use_alias_prefix . $table, $field), $filter['value']);
+      $placeholder = array_fill(0, count($filter['value']), '%s');
+      if ($filter['operator'] == 'OR') {
+        $query->add_where("%s.%s IN ('". implode("','", $placeholder) ."')", $where_args);
+      }
+      else {
+        $where_args[] = $where_args[0];
+        $where_args[] = $where_args[1];
+        $query->add_where("(%s.%s NOT IN ('". implode("','", $placeholder) ."') OR %s.%s IS NULL)", $where_args);
+      }
+    }
+    else {
+      $howmany = count($filter['value']);
+      $high_table = $query->add_table($table, true, $howmany);
+      if (!$high_table) { // couldn't add the table
+        break;
+      }
+
+      $table_num = $high_table - $howmany;
+      foreach ($filter['value'] as $item) {
+        $table_num++;
+        $tn = $query->get_table_name($table, $table_num);
+        $query->add_where("%s.%s = '%s'", $tn, $field, $item);
+      }
+    }
+  }
+  else {
+    $query->ensure_table("$table");
+    $query->add_where("%s.%s %s '%s'", $query->use_alias_prefix . $table, $field, $filter['operator'], $filter['value']);
+  }
+}
+
 /**
  * Implementation of hook_views_arguments().
  *
