Index: fieldgroup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/fieldgroup/fieldgroup.module,v
retrieving revision 1.79.2.8
diff -u -r1.79.2.8 fieldgroup.module
--- fieldgroup.module 8 Aug 2008 14:11:10 -0000 1.79.2.8
+++ fieldgroup.module 15 Aug 2008 01:46:46 -0000
@@ -4,6 +4,37 @@
/**
* @file
* Create field groups for CCK fields.
+ *
+ * New combo group treats all included fields as a single combo field,
+ * keeping the related delta values of all included fields synchronized.
+ *
+ * To use the combo group, create a new group, make it the 'Combo' type,
+ * set the number of multiple values for all the fields in the combo
+ * group, and drag into it the fields that should be included.
+ *
+ * All fields in the combo group will automatically get the group
+ * setting for multiple values. On the node form, the group is rearranged
+ * to keep the delta values for each field in a single drag 'n drop group,
+ * by transposing the normal array(field_name => delta => value) into
+ * array(delta => field_name => value).
+ *
+ * During validation and submission, the field values are restored to
+ * their normal positions.
+ *
+ * The combo group behaves exactly the same as a normal group
+ * in node displays, only the node form is different.
+ *
+ * TODO
+ *
+ * May need to limit this to specific fields that are known to work
+ * correctly and add validation and warning if other fields are added.
+ *
+ * Need to get the AHAH add more button working to create a new delta
+ * collection of all the group's fields.
+ *
+ * Lots of validation. Dragging fields with data into and out of the
+ * group can cause loss of data since the field's multiple value setting
+ * will be changed.
*/
/**
* Implementation of hook_init().
@@ -67,6 +98,9 @@
'fieldgroup_display_overview_form' => array(
'arguments' => array('form' => NULL),
),
+ 'fieldgroup_multiple_values' => array(
+ 'arguments' => array('element' => NULL),
+ ),
);
}
@@ -163,6 +197,29 @@
foreach (array_merge(array_keys(_content_admin_display_contexts(CONTENT_CONTEXTS_SIMPLE)), array('label')) as $key) {
$form['settings']['display'][$key] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]) ? $group['settings']['display'][$key] : 'fieldset');
}
+
+ $form['settings']['combo'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Group type settings'),
+ '#description' => t('Choose whether this is a standard or combo group. The fields in a standard group are independent of each other and have separate settings for multiple values. The fields in a combo group are treated as a single combined field with the same number of values.'),
+ );
+ $form['settings']['combo']['is_combo'] = array(
+ '#type' => 'select',
+ '#title' => t('Type of group'),
+ '#options' => fieldgroup_types(),
+ '#default_value' => isset($group['settings']['combo']['is_combo']) ? $group['settings']['combo']['is_combo'] : 0,
+ );
+ $description = t('Maximum number of values users can enter for combo fields. ');
+ $description .= '
'. t("'Unlimited' will provide an 'Add more' button so the users can add as many values as they like.");
+ $description .= '
'. t('Warning! Changing this setting after data has been created could result in the loss of data!') .'';
+ $form['settings']['combo']['multiple'] = array(
+ '#type' => 'select',
+ '#title' => t('Number of combo values'),
+ '#options' => array('' => t('N/A'), 1 => t('Unlimited'), 0 => 1) + drupal_map_assoc(range(2, 10)),
+ '#default_value' => isset($group['settings']['combo']['multiple']) ? $group['settings']['combo']['multiple'] : '',
+ '#description' => $description,
+ );
+
$form['weight'] = array('#type' => 'hidden', '#default_value' => isset($group['weight']) ? $group['weight'] : 0);
$form['group_name'] = array('#type' => 'hidden', '#default_value' => $group_name);
@@ -337,21 +394,34 @@
// Hide the fieldgroup, because the fields are inaccessible.
$form[$group_name]['#access'] = FALSE;
}
+ // If this is a combo group, alter it.
+ if (!empty($group['settings']['combo']) && !empty($group['settings']['combo']['is_combo'])) {
+ fieldgroup_combo_form($form, $form_state, $form_id, $group);
+ }
}
}
elseif ($form_id == '_content_admin_field' && isset($form['widget'])) {
$content_type = content_types($form['type_name']['#value']);
+ $groups = fieldgroup_groups($content_type['type']);
+ $group_name = _fieldgroup_field_get_group($content_type['type'], $form['field_name']['#value']);
+ $group = isset($groups[$group_name]) ? $groups[$group_name] : array();
$form['widget']['group'] = array(
'#type' => 'select',
'#title' => t('Display in group'),
'#options' => _fieldgroup_groups_label($content_type['type']),
- '#default_value' => _fieldgroup_field_get_group($content_type['type'], $form['field_name']['#value']),
+ '#default_value' => $group_name,
'#description' => t('Select a group, in which the field will be displayed on the editing form.'),
'#weight' => 5,
);
$form['widget']['weight']['#weight'] = 5;
$form['widget']['description']['#weight'] = 7;
+
+ // If this field is in a combo group, override the multiple value settings.
+ if (!empty($group) && !empty($group['settings']['combo']['is_combo'])) {
+ $form['field']['multiple']['#value'] = $group['settings']['combo']['multiple'];
+ $form['field']['multiple']['#access'] = FALSE;
+ }
$form['#submit'][] = 'fieldgroup_content_admin_form_submit';
}
elseif ($form_id == 'content_admin_field_overview_form' && !empty($form['#groups'])) {
@@ -368,6 +438,76 @@
}
}
+/**
+ * Align the delta values of each field in the combo group.
+ *
+ * Swap the field name and delta for each combo group so we can
+ * d-n-d each collection of fields as a single delta item.
+ */
+function fieldgroup_combo_form(&$form, &$form_state, $form_id, $group) {
+
+ $fields = $group['fields'];
+ $content_fields = content_fields();
+ $group_name = $group['group_name'];
+ $max = $group['settings']['combo']['multiple'];
+
+ $form[$group_name]['#theme'] = 'fieldgroup_multiple_values';
+ $form[$group_name]['#multiple'] = !empty($max);
+ $form[$group_name]['#group_name'] = $group_name;
+ $form[$group_name]['#group_label'] = $group['label'];
+ $form[$group_name]['#element_validate'] = array('fieldgroup_combo_form_validate');
+ $form[$group_name]['#tree'] = TRUE;
+
+ for ($delta = 0; $delta < $max; $delta++) {
+ foreach ($fields as $field_name => $field) {
+
+ // Transfer the delta value of the field to the group delta.
+ $form[$group_name][$delta][$field_name] = $form[$group_name][$field_name][$delta];
+
+ // Transfer attributes of the field to the new field location.
+ foreach ($form[$group_name][$field_name] as $key => $value) {
+ if (!is_numeric($key)) {
+ $form[$group_name][$delta][$field_name][$key] = $value;
+ }
+ }
+
+ // Each individual field should be a single value item.
+ $form[$group_name][$delta][$field_name]['#multiple'] = FALSE;
+ $form[$group_name][$delta]['_weight'] = $form[$group_name][$field_name][$delta]['_weight'];
+
+ // Add in our validation step, and make sure it preceeds other processing
+ // so we can massage the element back to the normal value.
+ if (isset($form[$group_name][$delta][$field_name]['#element_validate'])) {
+ array_unshift($form[$group_name][$delta][$field_name]['#element_validate'], 'fieldgroup_combo_item_validate');
+ }
+ else {
+ $form[$group_name][$delta][$field_name]['#element_validate'] = array('fieldgroup_combo_item_validate');
+ }
+
+ unset($form[$group_name][$delta][$field_name]['_weight']);
+ unset($form[$group_name][$delta][$field_name]['#theme']);
+
+ }
+ }
+ // Unset the original group values.
+ foreach ($fields as $field_name => $field) {
+ unset($form[$group_name][$field_name]);
+ }
+ $form['#element_validate'][] = 'fieldgroup_combo_form_validate';
+}
+
+/**
+ * Swap transposed field/delta values back to their normal positions.
+ */
+function fieldgroup_combo_item_validate($element, &$form_state) {
+ $field_name = array_pop($element['#parents']);
+ $delta = array_pop($element['#parents']);
+ $group = array_pop($element['#parents']);
+ array_push($element['#parents'], $field_name);
+ array_push($element['#parents'], $delta);
+ form_set_value($element, $element['#value'], $form_state);
+}
+
function fieldgroup_content_admin_form_submit($form, &$form_state) {
$form_values = $form_state['values'];
fieldgroup_update_fields($form_values);
@@ -539,6 +679,10 @@
}
}
+function fieldgroup_types() {
+ return array(0 => t('Standard'), 1 => t('Combo'));
+}
+
function fieldgroup_tablename($version = NULL) {
if (is_null($version)) {
$version = variable_get('fieldgroup_schema_version', 0);
@@ -589,15 +733,28 @@
db_query("INSERT INTO {". fieldgroup_tablename() ."} (type_name, group_name, label, settings, weight)
VALUES ('%s', '%s', '%s', '%s', %d)", $type_name, $group_name, $group['label'], serialize($group['settings']), $group['weight']);
cache_clear_all('fieldgroup_data', content_cache_tablename());
- return SAVED_NEW;
+ $ret = SAVED_NEW;
}
else {
db_query("UPDATE {". fieldgroup_tablename() ."} SET label = '%s', settings = '%s', weight = %d ".
"WHERE type_name = '%s' AND group_name = '%s'",
$group['label'], serialize($group['settings']), $group['weight'], $type_name, $group['group_name']);
cache_clear_all('fieldgroup_data', content_cache_tablename());
- return SAVED_UPDATED;
+ $ret = SAVED_UPDATED;
+ }
+
+ // For a combo group, update all the included fields with the right multiple value setting.
+ if ($group['settings']['combo']['is_combo']) {
+ $types = content_types();
+ $multiple = $group['settings']['combo']['multiple'];
+ $result = db_query("SELECT field_name, type_name FROM {". fieldgroup_fields_tablename() ."} WHERE group_name = '%s'", $group['group_name']);
+ while ($row = db_fetch_array($result)) {
+ $field = $types[$row['type_name']]['fields'][$row['field_name']];
+ $field['multiple'] = $multiple;
+ content_field_instance_update($field);
+ }
}
+ return $ret;
}
function fieldgroup_update_fields($form_values) {
@@ -650,3 +807,59 @@
return '