Index: modules/content_multigroup/views/content_multigroup.views.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/content_multigroup/views/Attic/content_multigroup.views.inc,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 content_multigroup.views.inc --- modules/content_multigroup/views/content_multigroup.views.inc 8 Aug 2009 18:59:46 -0000 1.1.2.1 +++ modules/content_multigroup/views/content_multigroup.views.inc 9 Aug 2009 18:29:49 -0000 @@ -6,3 +6,90 @@ * Views integration for Content Multigroups. */ +/** + * Implementation of hook_views_data_alter(). + */ +function content_multigroup_views_data_alter(&$data) { + // Scan all field groups in the system. + foreach (fieldgroup_groups() as $type_name => $groups) { + $type_label = node_get_types('name', $type_name); + + foreach ($groups as $group_name => $group) { + // Let's focus on multigroups that really accept multiple values. + if ($group['group_type'] == 'multigroup' && !empty($group['settings']['multigroup']['multiple'])) { + + // Scan all fields in this multigroup. + $field_labels = array(); + foreach (array_keys($group['fields']) as $field_name) { + // Load information about the field for this particular content type. + $field = content_fields($field_name, $type_name); + + // Get the Views table alias. + $table_alias = content_views_tablename($field); + + // Discard this field if not already exposed to Views. + if (isset($data[$table_alias])) { + $field_labels[$field_name] = t($field['widget']['label']); + } + } + + if (!empty($field_labels)) { + // Build the name for this filter. + // The scope of field groups is the content type itself. You can + // have more than one group with the same name but different fields + // in different content types. Therefore, we need the type name and + // multigroup name. + $db_field = 'multigroup_'. $type_name .'_'. $group_name; + + // Build the labels for the filter. + $label_truncated = truncate_utf8(t($group['label']), 10, TRUE); + $title = t('@group_label multigroup in @type_label', array( + '@group_label' => t($group['label']), + '@type_label' => $type_label, + )); + $title_short = t('@label-truncated in @type_label', array( + '@label-truncated' => $label_truncated, + '@type_label' => $type_label, + )); + $help_text = t('Synchronize multiple values for fields in @group_label multigroup, @type_label type. Fields in this group: @fields.', array( + '@group_label' => t($group['label']), + '@type_label' => $type_label, + '@fields' => implode(', ', $field_labels), + )); + + // Attach the new filter to the node table. + $data['node'][$db_field] = array( + 'group' => t('Content multigroup'), + 'title' => $title, + 'title short' => $title_short, + 'help' => $help_text, + 'filter' => array( + 'field' => $db_field, + 'table' => 'node', + 'handler' => 'content_multigroup_handler_filter', + 'content_type_name' => $type_name, + 'content_group_name' => $group_name, + 'allow empty' => TRUE, + ), + ); + } + } + } + } +} + +/** + * Implementation of hook_views_handlers(). + */ +function content_multigroup_views_handlers() { + return array( + 'info' => array( + 'path' => drupal_get_path('module', 'content_multigroup') . '/views/handlers', + ), + 'handlers' => array( + 'content_multigroup_handler_filter' => array( + 'parent' => 'views_handler_filter', + ), + ), + ); +} Index: modules/content_multigroup/views/handlers/content_multigroup_handler_filter.inc =================================================================== RCS file: modules/content_multigroup/views/handlers/content_multigroup_handler_filter.inc diff -N modules/content_multigroup/views/handlers/content_multigroup_handler_filter.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/content_multigroup/views/handlers/content_multigroup_handler_filter.inc 9 Aug 2009 18:30:37 -0000 @@ -0,0 +1,100 @@ +definition['content_type_name']); + return $groups[$this->definition['content_group_name']]; + } + + /** + * Get information about the fields in this multigroup. + */ + function _get_multigroup_fields() { + if (!isset($this->content_multigroup_fields)) { + $group = $this->_get_multigroup(); + $this->content_multigroup_fields = array(); + foreach (array_keys($group['fields']) as $field_name) { + $field = content_fields($field_name, $this->definition['content_type_name']); + $table_alias = content_views_tablename($field); + $this->content_multigroup_fields[$table_alias] = $field; + } + } + return $this->content_multigroup_fields; + } + + /** + * Define default value for master field. + */ + function options(&$options) { + $multigroup_fields = $this->_get_multigroup_fields(); + // Find the first required field. + foreach ($multigroup_fields as $table_alias => $field) { + if ($field['required']) { + $options['content_multigroup_master_field'] = $table_alias; + break; + } + } + // Default to first field in the multigroup. + if (empty($options['content_multigroup_master_field'])) { + $options['content_multigroup_master_field'] = current(array_keys($multigroup_fields)); + } + } + + /** + * Options from to ask the user for a master field. + */ + function options_form(&$form, &$form_state) { + $group = $this->_get_multigroup(); + $options = array(); + foreach ($this->_get_multigroup_fields() as $table_alias => $field) { + $options[$table_alias] = t($field['widget']['label']); + } + $form['content_multigroup_master_field'] = array( + '#title' => t('Available fields in @group_label multigroup', array('@group_label' => t($group['label']))), + '#type' => 'radios', + '#options' => $options, + '#default_value' => $this->options['content_multigroup_master_field'], + '#description' => t('Select the field in this multigroup that will be used to build the primary join with the content table.'), + ); + } + + /** + * Add joins to the query to synchronize the fields in this multigroup. + */ + function query() { + // Create the join between the master field table and the node table. + $base_alias = $this->query->ensure_table($this->options['content_multigroup_master_field'], $this->relationship); + + // Now we want to join the master field table with all other tables + // related to fields in the same multigroup, but adding the delta + // key to the join condition. This is what allows us to keep delta + // values in sync for all fields in the same multigroup. + foreach ($this->_get_multigroup_fields() as $table_alias => $field) { + if ($table_alias != $this->options['content_multigroup_master_field']) { + $alias = $this->query->ensure_table($table_alias, $this->relationship); + $this->query->table_queue[$table_alias]['join']->extra = $base_alias .'.delta = '. $alias .'.delta'; + } + } + } +}