Index: modules/content_multigroup/content_multigroup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/content_multigroup/Attic/content_multigroup.module,v
retrieving revision 1.1.4.2
diff -u -p -r1.1.4.2 content_multigroup.module
--- modules/content_multigroup/content_multigroup.module	7 Jun 2009 00:06:21 -0000	1.1.4.2
+++ modules/content_multigroup/content_multigroup.module	2 Jul 2009 17:59:45 -0000
@@ -161,3 +161,12 @@ function content_multigroup_fieldgroup_v
     _content_multigroup_fieldgroup_view($node, $element, $group, $context);
   }
 }
+
+/**
+ * Implementation of hook_views_api().
+ */
+function content_multigroup_views_api() {
+  return array(
+    'api' => '2.0',
+  );
+}
Index: modules/content_multigroup/content_multigroup.views.inc
===================================================================
RCS file: modules/content_multigroup/content_multigroup.views.inc
diff -N modules/content_multigroup/content_multigroup.views.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/content_multigroup/content_multigroup.views.inc	2 Jul 2009 17:59:45 -0000
@@ -0,0 +1,83 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Uses hook_views_data_alter() to add the content_multigroup_handler_filter object as a possible filter for multigroup fields.
+ */
+
+/**
+ * Implementation of hook_views_data_alter().
+ */
+function content_multigroup_views_data_alter(&$data) {
+  $field_types = _content_field_types();
+  $fields = content_fields();
+  foreach ($fields as $field) {
+    $table_alias = content_views_tablename($field);
+    //Check that this field's table has data in the $data object.
+    if (isset($data[$table_alias])) {
+      $db_info = content_database_info($field);
+    
+      // Fill $types with the content type names which contain this field.
+      $types = array();
+      foreach (content_types() as $type) {
+        if (isset($type['fields'][$field['field_name']])) {
+          $types[] = $type['name'];
+        }
+      }
+      
+      $db_columns = array();
+      $additional_fields = array();
+      foreach ($db_info['columns'] as $column => $attributes) {
+        // Select explicitly enabled field columns.
+        if (!empty($attributes['views'])) {
+          $db_columns[$column] = $attributes;
+        }
+        // Ensure all columns are retrieved.
+        $additional_fields[$attributes['column']] = $attributes['column'];
+      }
+      
+      $multigroups = array();
+      $multigroup_results = db_query("SELECT cgf.group_name, cg.label, cg.type_name FROM {". fieldgroup_fields_tablename() ."} cgf
+                                     INNER JOIN {". fieldgroup_tablename() ."} cg on (cgf.group_name = cg.group_name AND cg.group_type = 'multigroup')
+                                     WHERE cgf.field_name = '%s'", $field['field_name']);
+      while ($group = db_fetch_array($multigroup_results)) {
+        $multigroups[$group['group_name']] = $group;
+      }
+      foreach ($multigroups as $group_name => $group) {
+        $db_field = $group_name;
+        $label_truncated = truncate_utf8(t($field['widget']['label']), 10, TRUE);
+        $title = t('@field_label in Multigroup @group_label (!column)', array('@field_label' => t($field['widget']['label']), '@group_label' => $group['label'], '!column' => $db_field));
+        $title_short = t('@label-truncated multigroup delta', array('@label-truncated' => $label_truncated));
+        $data[$table_alias][$db_field] = array(
+          'group' => t('Content'),
+          'title' => $title,
+          'title short' => $title_short,
+          'help' =>  t('Delta - Appears in: @types', array('@types' => implode(', ', $types))),
+        );
+        $data[$table_alias][$db_field]['filter'] = array(
+          'field' => $db_field,
+          'label' => t('Delta'),
+          'table' => $db_info['table'],
+          'handler' => 'content_multigroup_handler_filter',
+          'additional fields' => array($field['field_name'] .'_value' => $field['field_name'] .'_value'),
+          'content_field_name' => $field['field_name'],
+          'allow empty' => TRUE,
+        );
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_views_handlers().
+ */
+function content_multigroup_views_handlers() {
+  return array(
+    'handlers' => array(
+      'content_multigroup_handler_filter' => array(
+        'parent' => 'views_handler_filter',
+      ),
+    ),
+  );
+}
\ No newline at end of file
Index: modules/content_multigroup/content_multigroup_handler_filter.inc
===================================================================
RCS file: modules/content_multigroup/content_multigroup_handler_filter.inc
diff -N modules/content_multigroup/content_multigroup_handler_filter.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/content_multigroup/content_multigroup_handler_filter.inc	2 Jul 2009 17:59:45 -0000
@@ -0,0 +1,93 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Defines a content_multigroup filter object in views.
+ *
+ * This filter allows you to associate the deltas in a multigroup so that views doesn't do a cross-join across all values in
+ * multivalue cck fields.
+ */
+class content_multigroup_handler_filter extends views_handler_filter {
+  
+  function init(&$view, $options) {
+    parent::init($view, $options);
+  }
+  
+  function can_expose() {
+    return FALSE;
+  }
+  
+  function options(&$options) {
+    parent::options($options);
+    $options['content_multigroup_fields'] = array();
+  }
+  
+  function option_definition() {
+    $options = parent::option_definition();
+    return $options;
+  }
+  
+  function options_form(&$form, &$form_state) {
+    $fields = content_fields();
+    $options = array();
+    foreach ($fields as $name => $field) {
+      // Only need to filter $options to those that are multivalue and on the same group.
+      if (($name != $this->definition['content_field_name']) && $this->_is_field_multivalue($name) && $this->_is_field_multigroup($name, $this->field)) {
+        $table_alias = content_views_tablename($field);
+        $options[$table_alias] = $field['widget']['label'];
+      }
+    }
+
+    $form['content_multigroup_fields'] = array(
+      '#title' => t('Available content field(s)'),
+      '#type' => 'checkboxes',
+      '#options' => $options,
+      '#default_value' => $this->options['content_multigroup_fields'],
+      '#multiple' => TRUE,
+      '#description' => t('Select fields in multigroup to filter delta against.'),
+    );
+  }
+  
+  /**
+   * Checks to see if a field is listed as multivalue - if the result is '1' then it is.
+   */
+  function _is_field_multivalue($name) {
+    $multivalue = db_result(db_query(
+      "SELECT multiple FROM {". content_field_tablename() ."} WHERE field_name = '%s'", $name
+    ));
+    return ($multivalue == 1); 
+  }
+  
+  /**
+   * Checks to see if the field_name is part of a multigroup with the $group_name name.
+   */
+  function _is_field_multigroup($field_name, $group_name) {
+    $multigroup = db_result(db_query(
+      "SELECT cg.group_type FROM {".
+      fieldgroup_fields_tablename()
+      ."} cgf INNER JOIN {".
+      fieldgroup_tablename()
+      ."} cg ON (cgf.group_name = cg.group_name) WHERE cgf.field_name = '%s' AND cgf.group_name = '%s'",
+      $field_name, $group_name
+    ));
+    return ($multigroup == 'multigroup');
+  }
+  
+  function options_submit(&$form, &$form_state) {
+    $option_tables = array();
+    foreach ($form_state['values']['options']['content_multigroup_fields'] as $table => $value) {
+      if (!empty($value)) {
+        $option_tables[] = $table; 
+      }
+    }
+    $form_state['values']['options']['content_multigroup_fields'] = $option_tables;
+  }
+  
+  function query() {
+    $this->ensure_my_table();
+    foreach ($this->options['content_multigroup_fields'] as $option_table) {
+      $this->query->add_where($this->options['group'], "$this->table_alias.delta = %s.delta", $option_table);
+    }
+  }
+}
\ No newline at end of file
