Index: content_multigroup.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/content_multigroup/Attic/content_multigroup.module,v retrieving revision 1.1.2.4 diff -u -r1.1.2.4 content_multigroup.module --- content_multigroup.module 22 Oct 2008 11:02:41 -0000 1.1.2.4 +++ content_multigroup.module 6 Dec 2008 15:18:09 -0000 @@ -61,7 +61,7 @@ module_load_include('inc', 'content', 'includes/content.admin'); $settings = array('multigroup' => array('multiple' => 1)); foreach (array_keys(content_build_modes()) as $key) { - $settings['multigroup']['display_settings'][$key]['format'] = 'fieldset'; + $settings['display'][$key]['format'] = 'fieldset'; } return $settings; } @@ -108,12 +108,12 @@ content_multigroup_field_overview_form($form, $form_state); $form['#validate'][] = 'content_multigroup_field_overview_form_validate'; } - elseif ($form_id == 'content_display_overview_form') { + elseif ($form_id == 'content_display_overview_form' && !empty($form['#groups'])) { content_multigroup_display_overview_form($form, $form_state, $form_id); $form['#submit'] = array_merge(array('content_multigroup_display_overview_form_submit'), $form['#submit']); } elseif ($form_id == 'fieldgroup_group_edit_form') { - return content_multigroup_group_edit_form($form, $form_state, $form_id); + content_multigroup_group_edit_form($form, $form_state, $form_id); } } @@ -180,39 +180,37 @@ } } - if (!empty($fields)) { - foreach ($fields as $field_name => $field) { - $new_group = $form_values[$field_name]['parent']; - $old_group = $form_values[$field_name]['prev_parent']; - if (!empty($new_group) && isset($groups[$new_group]) && $groups[$new_group]['group_type'] == 'multigroup') { - $allowed_in = content_multigroup_allowed_in($field, $groups[$new_group]); - if (!$allowed_in['allowed']) { - form_set_error($field_name, $allowed_in['message']); - } - else { - if (!empty($allowed_in['message'])) { - drupal_set_message($allowed_in['message']); - } - module_load_include('inc', 'content', 'includes/content.crud'); - $content_type = content_types($type_name); - $multiple = $groups[$new_group]['settings']['multigroup']['multiple']; - $multiple_values = content_multigroup_multiple_values(); - $field = $content_type['fields'][$field_name]; - $field['multiple'] = $multiple; - $field = content_field_instance_collapse($field); - content_field_instance_update($field); - drupal_set_message(t('The field %field has been updated to use %multiple values, to match the multiple value setting of the Multigroup %group.', array( - '%field' => $field['label'], '%multiple' => $multiple_values[$multiple], '%group' => $groups[$new_group]['label']))); - } + foreach ($fields as $field_name => $field) { + $new_group = $form_values[$field_name]['parent']; + $old_group = $form_values[$field_name]['prev_parent']; + if (!empty($new_group) && isset($groups[$new_group]) && $groups[$new_group]['group_type'] == 'multigroup') { + $allowed_in = content_multigroup_allowed_in($field, $groups[$new_group]); + if (!$allowed_in['allowed']) { + form_set_error($field_name, $allowed_in['message']); } - elseif (!empty($old_group) && isset($groups[$old_group]) && $groups[$old_group]['group_type'] == 'multigroup') { - $allowed_out = content_multigroup_allowed_out($field, $groups[$old_group]); - if (!$allowed_out['allowed']) { - form_set_error($field_name, $allowed_out['message']); - } - elseif (!empty($allowed_out['message'])) { - drupal_set_message($allowed_out['message']); + else { + if (!empty($allowed_in['message'])) { + drupal_set_message($allowed_in['message']); } + module_load_include('inc', 'content', 'includes/content.crud'); + $content_type = content_types($type_name); + $group_multiple = $groups[$new_group]['settings']['multigroup']['multiple']; + $multiple_values = content_multigroup_multiple_values(); + $field = $content_type['fields'][$field_name]; + $field['multiple'] = $group_multiple; + $field = content_field_instance_collapse($field); + content_field_instance_update($field); + drupal_set_message(t('The field %field has been updated to use %multiple values, to match the multiple value setting of the Multigroup %group.', array( + '%field' => $field['label'], '%multiple' => $multiple_values[$group_multiple], '%group' => $groups[$new_group]['label']))); + } + } + elseif (!empty($old_group) && isset($groups[$old_group]) && $groups[$old_group]['group_type'] == 'multigroup') { + $allowed_out = content_multigroup_allowed_out($field, $groups[$old_group]); + if (!$allowed_out['allowed']) { + form_set_error($field_name, $allowed_out['message']); + } + elseif (!empty($allowed_out['message'])) { + drupal_set_message($allowed_out['message']); } } } @@ -230,12 +228,12 @@ // We can't allow fields with more multiple values than the group has // to be moved into it. $max_existing = content_max_delta($field['field_name']); - $group_max = $group['settings']['multigroup']['multiple']; + $group_multiple = $group['settings']['multigroup']['multiple']; $multiple_values = content_multigroup_multiple_values(); - if ($group_max != 1 && $max_existing > $group_max) { + if ($group_multiple != 1 && $max_existing > $group_multiple) { return array( 'allowed' => FALSE, - 'message' => t('This change is not allowed. The field %field already has %multiple values in the database but the group %group only allows %group_max. Making this change would result in the loss of data.', array('%field' => $field['widget']['label'], '%multiple' => $max_existing, '%group' => $group['label'], '%group_max' => $multiple_values[$group_max])) + 'message' => t('This change is not allowed. The field %field already has %multiple values in the database but the group %group only allows %group_max. Making this change would result in the loss of data.', array('%field' => $field['widget']['label'], '%multiple' => $max_existing, '%group' => $group['label'], '%group_max' => $multiple_values[$group_multiple])) ); } @@ -254,7 +252,7 @@ 'nodereference_select', 'userreference_buttons', 'userreference_select', - ); + ); $allowed_widgets = array_merge($allowed_widgets, module_invoke_all('content_multigroup_allowed_widgets')); if (!in_array($field['widget']['type'], $allowed_widgets)) { return array( @@ -295,14 +293,14 @@ $max_existing = content_max_delta($field['field_name']); $no_remove_widgets = array( - 'optionwidgets_select', - 'optionwidgets_buttons', - 'optionwidgets_onoff', - 'nodereference_buttons', - 'nodereference_select', - 'userreference_buttons', - 'userreference_select', - ); + 'optionwidgets_select', + 'optionwidgets_buttons', + 'optionwidgets_onoff', + 'nodereference_buttons', + 'nodereference_select', + 'userreference_buttons', + 'userreference_select', + ); $no_remove_widgets = array_merge($no_remove_widgets, module_invoke_all('content_multigroup_no_remove_widgets')); if (in_array($field['widget']['type'], $no_remove_widgets) && $max_existing > 0) { return array( @@ -336,14 +334,17 @@ $contexts_selector = $form['#contexts']; // Gather type information. - $type = content_types($type_name); - $field_types = _content_field_types(); - $fields = $type['fields']; + $content_type = content_types($type_name); + + // The content module stops building the form if the type has no fields. + if (empty($content_type['fields'])) { + return; + } $groups = $group_options = array(); if (module_exists('fieldgroup')) { - $groups = fieldgroup_groups($type['type']); - $group_options = _fieldgroup_groups_label($type['type']); + $groups = fieldgroup_groups($type_name); + $group_options = _fieldgroup_groups_label($type_name); } $contexts = content_build_modes($contexts_selector); @@ -363,7 +364,7 @@ if ($group['group_type'] != 'multigroup') { continue; } - $defaults = $group['settings']['multigroup']['display_settings']; + $defaults = $group['settings']['display']; $form_name = $name .'_subgroup'; $form['#fields'] = array_merge(array($form_name), $form['#fields']); @@ -383,11 +384,16 @@ $form[$form_name][$key]['format'] = array( '#type' => 'select', '#options' => $options, - '#default_value' => isset($defaults[$key]) ? $defaults[$key] : 'fieldset', + '#default_value' => isset($defaults[$key]['format']) ? $defaults[$key]['format'] : 'fieldset', + ); + // exclude in $content + $form[$form_name][$key]['exclude'] = array( + '#type' => 'checkbox', + '#options' => array(0 => t('Include'), 1 => t('Exclude')), + '#default_value' => isset($defaults[$key]['exclude']) ? $defaults[$key]['exclude'] : 0, ); } } - return $form; } /** @@ -409,7 +415,7 @@ // We have some numeric keys here, so we can't use array_merge. foreach ($values as $k => $v) { - $group['settings']['multigroup']['display_settings'][$k] = $v; + $group['settings']['display'][$k] = $v; } fieldgroup_save_group($form['#type_name'], $group); @@ -430,7 +436,7 @@ $group_name = $form['group_name']['#default_value']; $content_type = content_types($type_name); - $groups = fieldgroup_groups($content_type['type']); + $groups = fieldgroup_groups($type_name); $group = $groups[$group_name]; if ($group['group_type'] != 'multigroup') { @@ -442,7 +448,7 @@ $form['group_type'] = array( '#type' => 'hidden', '#value' => $group['group_type'], - ); + ); $form['settings']['multigroup'] = array( '#type' => 'fieldset', '#title' => t('Other settings'), @@ -454,13 +460,13 @@ $description .= t("'Unlimited' will provide an 'Add more' button so the users can add repeat it as many times as they like.") . ' '; $description .= t('All fields in this group will automatically be set to allow this number of values.'); - $multiple = isset($group['settings']['multigroup']['multiple']) ? $group['settings']['multigroup']['multiple'] : 1; + $group_multiple = isset($group['settings']['multigroup']['multiple']) ? $group['settings']['multigroup']['multiple'] : 1; $form['settings']['multigroup']['multiple'] = array( '#tree' => TRUE, '#type' => 'select', '#title' => t('Number of repeats'), '#options' => content_multigroup_multiple_values(), - '#default_value' => $multiple, + '#default_value' => $group_multiple, '#description' => $description, ); @@ -469,8 +475,8 @@ '#title' => t('Labels'), '#description' => t("Labels for each subgroup of fields. Labels can be hidden or shown in various contexts using the 'Display fields' screen."), ); - if ($multiple < 2) { - $multiple = 0; + if ($group_multiple < 2) { + $group_multiple = 0; } for ($i = 0; $i < 10; $i++) { $form['settings']['multigroup']['labels'][$i] = array( @@ -482,7 +488,6 @@ $form['#validate'][] = 'content_multigroup_group_edit_form_validate'; $form['#submit'][] = 'content_multigroup_group_edit_form_submit'; - return $form; } /** @@ -523,10 +528,9 @@ $content_type = $form['#content_type']; $groups = fieldgroup_groups($content_type['type']); $group = $groups[$form_values['group_name']]; - $multiple = $form_values['settings']['multigroup']['multiple']; - foreach ($group['fields'] as $field_name => $data) { - $field = $content_type['fields'][$field_name]; - $field['multiple'] = $multiple; + $group_fields = array_intersect_key($content_type['fields'], $group['fields']); + foreach ($group_fields as $field_name => $field) { + $field['multiple'] = $form_values['settings']['multigroup']['multiple']; $field = content_field_instance_collapse($field); content_field_instance_update($field); } @@ -547,59 +551,63 @@ } $node = $form['#node']; - $fields = $group['fields']; - $content_fields = content_fields(); + $content_type = content_types($group['type_name']); $group_name = $group['group_name']; + $group_fields = array_intersect_key($content_type['fields'], $group['fields']); + $group_multiple = $group['settings']['multigroup']['multiple']; - // Use the first field in the group to get the item counts. - $first_field_name = array_shift(array_keys($group['fields'])); - $first_field = isset($content_fields[$first_field_name]) ? $content_fields[$first_field_name] : array(); - $first_field_items = isset($node->$first_field_name) ? $node->$first_field_name : array(); - - $group['multiple'] = $group['settings']['multigroup']['multiple']; - switch ($group['multiple']) { + switch ($group_multiple) { case 0: - $max = 0; + $group_deltas = array(0); + $max_delta = 0; break; + case 1: - // Is this a new node? - if (empty($first_field_items)) { - $max = 1; + $group_deltas = array(); + $max_delta = -1; + foreach ($group_fields as $field_name => $field) { + $field_items = isset($node->$field_name) ? $node->$field_name : array(); + if (!empty($field_items)) { + $field = $group_fields[$field_name]; + $field_deltas = array_keys(content_set_empty($field, $field_items)); + $field_max = (!empty($field_deltas) ? max($field_deltas) : 0); + if ($field_max > $max_delta || empty($group_deltas)) { + $max_delta = $field_max; + $group_deltas = $field_deltas; + } + } } - else { - $filled_items = content_set_empty($first_field, $first_field_items); - $current_item_count = isset($form_state['item_count'][$group_name]) - ? $form_state['item_count'][$group_name] - : count($first_field_items); - // We always want at least one empty icon for the user to fill in. - $max = ($current_item_count > count($filled_items)) - ? $current_item_count - 1 - : count($filled_items); + $current_item_count = (isset($form_state['item_count'][$group_name]) ? $form_state['item_count'][$group_name] : count($group_deltas) + 1); + while (count($group_deltas) < $current_item_count) { + $max_delta++; + $group_deltas[] = $max_delta; } break; + default: - $max = $group['multiple'] - 1; + $group_deltas = array_keys(array_fill(0, $group_multiple, 0)); + $max_delta = $group_multiple - 1; break; } $form[$group_name]['#theme'] = 'content_multigroup_node_form'; - $form[$group_name]['#multiple'] = !empty($max); + $form[$group_name]['#item_count'] = count($group_deltas); $form[$group_name]['#type_name'] = $group['type_name']; $form[$group_name]['#group_name'] = $group_name; $form[$group_name]['#group_label'] = $group['label']; $form[$group_name]['#element_validate'] = array('content_multigroup_node_form_validate'); $form[$group_name]['#tree'] = TRUE; - for ($delta = 0; $delta <= $max; $delta++) { + foreach ($group_deltas as $delta) { content_multigroup_group_form($form, $form_state, $group, $delta); } // Unset the original group field values now that we've moved them. - foreach ($fields as $field_name => $field) { + foreach (array_keys($group_fields) as $field_name) { unset($form[$group_name][$field_name]); } - if ($add_more = content_multigroup_add_more($form, $form_state, $group)) { + if (($add_more = content_multigroup_add_more($form, $form_state, $group)) !== FALSE) { $form[$group_name] += $add_more; } } @@ -617,13 +625,13 @@ module_load_include('inc', 'content', 'includes/content.node_form'); $node = $form['#node']; - $fields = $group['fields']; - $content_fields = content_fields(); + $content_type = content_types($group['type_name']); + $group_fields = array_intersect_key($content_type['fields'], $group['fields']); $group_name = $group['group_name']; - $group['multiple'] = $group['settings']['multigroup']['multiple']; - $form[$group_name]['#fields'] = array_keys($group['fields']); + $group_multiple = $group['settings']['multigroup']['multiple']; + $form[$group_name]['#fields'] = array_keys($group_fields); - foreach ($fields as $field_name => $group_field) { + foreach ($group_fields as $field_name => $field) { if (empty($form[$group_name][$delta])) { $form[$group_name] += array($delta => array($field_name => array())); } @@ -631,19 +639,13 @@ $form[$group_name][$delta][$field_name] = array(); } + $weight_delta = (isset($form_state['item_count'][$group_name]) ? $form_state['item_count'][$group_name] : $form[$group_name]['#item_count']); $form[$group_name][$delta]['_weight'] = array( '#type' => 'weight', - '#delta' => $delta, // this 'delta' is the 'weight' element's property + '#delta' => $weight_delta, // this 'delta' is the 'weight' element's property '#default_value' => $delta, '#weight' => 100, ); - $form[$group_name][$delta]['_delta'] = array( - '#type' => 'hidden', - '#value' => $delta, - ); - - - $field = $content_fields[$field_name]; // Make each field into a pseudo single value field // with the right delta value. @@ -680,89 +682,86 @@ } $form[$group_name][$delta][$field_name]['#weight'] = $field['widget']['weight']; - // Add in our validation step, and make sure it preceeds other - // processing so we can massage the element back to the normal position. - if (empty($form[$group_name][$delta][$field_name]['#element_validate'])) { - $form[$group_name][$delta][$field_name]['#element_validate'] = array(); - } - array_unshift($form[$group_name][$delta][$field_name]['#element_validate'], 'content_multigroup_node_item_validate'); + // By default keep empty items unless all fields in a delta group are empty. + // See content_set_empty() and content_multigroup_node_form_validate(). + $form[$group_name][$delta][$field_name]['_keep_empty'] = array('#type' => 'hidden', '#value' => 1); } // Reset the form '#node' back to its original value. $form['#node'] = $node; - - return $form; } /** - * Swap transposed field/delta values back - * to their normal positions in the node. + * Validation for the whole node group. */ -function content_multigroup_node_item_validate($element, &$form_state) { - static $weights = array(); +function content_multigroup_node_form_validate($element, &$form_state) { + $group_name = $element['#parents'][count($element['#parents']) - 1]; + $groups = fieldgroup_groups($element['#type_name']); + $group = $groups[$group_name]; + $content_type = content_types($group['type_name']); + $group_fields = array_intersect_key($content_type['fields'], $group['fields']); - //dsm($form_state['values']); + // It's very important to use $form_values instead of $element['#value'] + // here, because $element['#value'] is sometimes missing changes made in + // #element_validate processing done by other modules. $form_values = $form_state['values']; - $field_name = array_pop($element['#parents']); - $delta = array_pop($element['#parents']); - $group_name = array_pop($element['#parents']); - - // Identify the new delta value for each field. - - // Find the original delta values for this group, save as static value - // because the group will acquire and lose values while we process it. - if (!array_key_exists($group_name, $weights)) { - $items = $form_state['values'][$group_name]; - $weights[$group_name] = array(); - foreach ($items as $count => $value) { - // Allow for the possibility of matching _weights and missing deltas. - $weight = floatval($value['_weight']); - $old_delta = intval($value['_delta']); - if (empty($weights[$group_name][$weight]) || !in_array($old_delta, $weights[$group_name][$weight])) { - $weights[$group_name][$weight][] = $old_delta; + + // Move group data from group->delta->field to field->delta. + $group_data = array(); + $empty_deltas = array(); + foreach ($form_values[$group_name] as $delta => $items) { + if (is_array($items) && isset($items['_weight'])) { + // If all fields in the delta group are empty, then we can let the + // content module remove them. See content_set_empty(). + $is_empty = TRUE; + foreach ($group_fields as $field_name => $field) { + if (!isset($group_data[$field_name])) { + $group_data[$field_name] = array(); + } + // If this particular field is empty, we want to keep all fields in + // the same delta group, even those that are empty. + $function = $field['module'] .'_content_is_empty'; + if (!$function($items[$field_name], $field)) { + $is_empty = FALSE; + } + $group_data[$field_name][$delta] = array_merge($items[$field_name], array( + '_weight' => $items['_weight'], + '_keep_empty' => $items[$field_name]['_keep_empty'], + )); + } + if ($is_empty && isset($group_data[$field_name])) { + $empty_deltas[] = $delta; } } - ksort($weights[$group_name]); } - $count = 0; - foreach ($weights[$group_name] as $weight => $values) { - foreach ($values as $old_delta) { - if ($old_delta === $delta) { - $delta = $count; - //dsm('moving delta values: '.$group_name.'>'.$field_name.'>'.'from '. $old_delta .' to '. $delta); - break 2; + foreach ($empty_deltas as $delta) { + foreach ($group_data as $field_name => $items) { + foreach (array_keys($items) as $key) { + if ($delta == $key) { + $group_data[$field_name][$delta]['_keep_empty'] = 0; + } } - $count++; } } - // We figured out what the new order for the fields is, - // so set the value for the new delta. - // We move these new values back up to the top level of the - // node and out of the group so the Content module will find and - // save the new values and so they don't get mixed into the - // remaining, unaltered, values in the group. - array_push($element['#parents'], $field_name); - array_push($element['#parents'], $delta); + // Move the field values back up to the top level of the node and out of + // the group so the Content module will find and save the new values. + foreach ($group_data as $field_name => $items) { + + // Sort field items according to drag-n-drop reordering. Deltas are also + // rebuilt to start counting from 0 to n. Since all fields in the group + // share the same weight, all fields in the same delta remain in sync. + usort($items, '_content_sort_items_helper'); + + // Move field items back to it's original position on the form. + $element_copy = $element; + array_pop($element_copy['#parents']); + array_push($element_copy['#parents'], $field_name); + form_set_value($element_copy, $items, $form_state); + } - // It's very important to use $form_values instead of $element['#value'] - // here, because $element['#value'] is sometimes missing changes - // made in #element_validate processing done by other modules. - $value = isset($form_values[$group_name][$delta][$field_name]) ? $form_values[$group_name][$delta][$field_name] : NULL; - - // Fields that use optionwidgets have an extra array level in the value - // because of the optionwidgets transposition that forces a delta value - // into the result array. This works fine when a delta value is between - // the field name and the field value, as in normal nodes, but not when - // we reverse the field and the delta, so in this case we need to - // promote the nested delta value back up to the field level. - if (is_array($value) && content_multigroup_uses_optionwidgets($field_name, $element['#type_name'])) { - $value = array_shift($value); - } - - //dsm('setting value of '. $field_name.'>'.$delta); - //dsm($value); - form_set_value($element, $value, $form_state); + // Finally, get rid of the group data from the form. + form_set_value($element, NULL, $form_state); } /** @@ -771,7 +770,7 @@ */ function content_multigroup_uses_optionwidgets($field_name, $type_name) { static $optionwidgets; - if (empty($optionwidgets)) { + if (!isset($optionwidgets)) { $optionwidgets = array( 'optionwidgets_select', 'optionwidgets_buttons', @@ -780,32 +779,19 @@ 'nodereference_select', 'userreference_buttons', 'userreference_select', - ); + ); // Add hook where other widgets that use optionwidgets can announce it. $optionwidgets = array_merge($optionwidgets, module_invoke_all('content_multigroup_uses_optionwidgets')); } - $types = content_types($type_name); - $fields = $types['fields']; - $field = $fields[$field_name]; - if (in_array($field['widget']['type'], $optionwidgets)) { + $content_type = content_types($type_name); + if (in_array($content_type['fields'][$field_name]['widget']['type'], $optionwidgets)) { return TRUE; } return FALSE; } /** - * Validation for the whole node group. - */ -function content_multigroup_node_form_validate($element, $form_state) { - // We moved all the new field values out of the field group - // and up to the top level of the node, now get rid of the - // original group values. - form_set_value($element, NULL, $form_state); - return; -} - -/** * Implementation of hook_fieldgroup_view(). */ function content_multigroup_fieldgroup_view(&$node, &$element, $group, $context) { @@ -815,69 +801,74 @@ $group_name = $group['group_name']; $node_copy = drupal_clone($node); - $max = $group['settings']['multigroup']['multiple']; - - $count = 0; - foreach ($group['fields'] as $field_name => $field) { - $count = max($count, count($node->$field_name)); - } - $group['multiple'] = isset($group['settings']['multigroup']['multiple']) ? $group['settings']['multigroup']['multiple'] : 1; + $group_multiple = $group['settings']['multigroup']['multiple']; $labels = isset($group['settings']['multigroup']['labels']) ? $group['settings']['multigroup']['labels'] : array(); - $format = isset($group['settings']['multigroup']['display_settings'][$context]['format']) ? $group['settings']['multigroup']['display_settings'][$context]['format'] : 'fieldset'; - $show_label = isset($group['settings']['multigroup']['display_settings']['label']) ? $group['settings']['multigroup']['display_settings']['label'] : 'above'; + $format = isset($group['settings']['display'][$context]['format']) ? $group['settings']['display'][$context]['format'] : 'fieldset'; + $show_label = isset($group['settings']['display']['label']) ? $group['settings']['display']['label'] : 'above'; + $group_field_names = array_keys($group['fields']); - switch ($group['multiple']) { + switch ($group_multiple) { case 0: - $max = 0; + $group_deltas = array(0); break; + case 1: - $max = $count; + // Compute deltas based on the field with the highest number of items. + $group_deltas = array(); + $max_delta = -1; + foreach ($group_field_names as $field_name) { + $field_deltas = is_array($node->content[$field_name]['field']['items']) ? array_keys($node->content[$field_name]['field']['items']) : array(); + $field_max = (!empty($field_deltas) ? max($field_deltas) : 0); + if ($field_max > $max_delta) { + $max_delta = $field_max; + $group_deltas = $field_deltas; + } + } break; + default: - $max = $group['multiple']; + $group_deltas = array_keys(array_fill(0, $group_multiple - 1, 0)); break; } - for ($delta = 0; $delta < $max; $delta++) { - $element[$delta] = array('#weight' => $delta); - - $label = !empty($labels[$delta]) && $show_label == 'above' ? $labels[$delta] : ''; + foreach ($group_deltas as $delta) { + $element[$delta] = array( + '#weight' => $delta, + '#title' => !empty($labels[$delta]) && $show_label == 'above' ? $labels[$delta] : '', + ); - foreach ($group['fields'] as $field_name => $field) { + foreach ($group_field_names as $field_name) { // Create a pseudo node that only has the value we want // in this group and pass it to the formatter. if (isset($node->content[$field_name])) { $node_copy->content[$field_name]['field']['items'] = array( $delta => isset($node->content[$field_name]['field']['items'][$delta]) ? $node->content[$field_name]['field']['items'][$delta] : NULL, - ); + ); $element[$delta][$field_name] = $node_copy->content[$field_name]; $element[$delta][$field_name]['#delta'] = $delta; } } + switch ($format) { case 'table': $element[$delta]['#theme'] = 'content_multigroup_display_table'; - $element[$delta]['#title'] = $label; break; case 'fieldset': $element[$delta]['#type'] = 'fieldset'; - $element[$delta]['#title'] = $label; break; case 'hr': $element[$delta]['#theme'] = 'content_multigroup_display_hr'; - $element[$delta]['#title'] = $label; break; default: $element[$delta]['#theme'] = 'content_multigroup_display_simple'; - $element[$delta]['#title'] = $label; break; } } - foreach ($group['fields'] as $field_name => $field) { + foreach ($group_field_names as $field_name) { if (isset($element[$field_name])) { unset($element[$field_name]); } @@ -890,11 +881,18 @@ * Combine multiple values into a table with drag-n-drop reordering. */ function theme_content_multigroup_node_form($element) { + $groups = fieldgroup_groups($element['#type_name']); + $group_name = $element['#group_name']; + $group = $groups[$group_name]; + $group_multiple = $group['settings']['multigroup']['multiple']; $output = ''; - if ($element['#multiple'] >= 1) { + + if ($group_multiple >= 1) { $table_id = $element['#group_name'] .'_values'; $order_class = $element['#group_name'] .'-delta-order'; + $labels = isset($group['settings']['multigroup']['labels']) ? $group['settings']['multigroup']['labels'] : array(); + $header = array( array( 'data' => '', @@ -903,14 +901,10 @@ t('Order'), ); $rows = array(); - $groups = fieldgroup_groups($element['#type_name']); - $group = $groups[$element['#group_name']]; - $labels = isset($group['settings']['multigroup']['labels']) ? $group['settings']['multigroup']['labels'] : array(); - $multiple = isset($group['settings']['multigroup']['multiple']) ? $group['settings']['multigroup']['multiple'] : 1; $i = 0; foreach (element_children($element) as $delta => $key) { - if ($key !== $element['#group_name'] .'_add_more') { + if ($key !== $group_name .'_add_more') { $label = !empty($labels[$i]) ? theme('content_multigroup_node_label', $labels[$i]) : ''; $element[$key]['_weight']['#attributes']['class'] = $order_class; $delta_element = drupal_render($element[$key]['_weight']); @@ -933,7 +927,7 @@ $output .= theme('table', $header, $rows, array('id' => $table_id, 'class' => 'content-multiple-table')); $output .= $element['#description'] ? '
'. $element['#description'] .'
' : ''; - $output .= drupal_render($element[$element['#group_name'] .'_add_more']); + $output .= drupal_render($element[$group_name .'_add_more']); drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class); } @@ -946,47 +940,46 @@ return $output; } +/** + * Add AHAH add more button, if not working with a programmed form. + */ function content_multigroup_add_more(&$form, &$form_state, $group) { - // Add AHAH add more button, if not working with a programmed form. - $multiple = $group['settings']['multigroup']['multiple']; - $form_element = array(); - if ($multiple != 1 || !empty($form['#programmed'])) { - return $form_element; + $group_multiple = $group['settings']['multigroup']['multiple']; + if ($group_multiple != 1 || !empty($form['#programmed'])) { + return FALSE; } - else { - // Make sure the form is cached so ahah can work. - $form['#cache'] = TRUE; - $content_type = content_types($group['type_name']); - $group_name = $group['group_name']; - $group_name_css = str_replace('_', '-', $group_name); - - $form_element[$group_name .'_add_more'] = array( - '#type' => 'submit', - '#name' => $group_name .'_add_more', - '#value' => t('Add more values'), - '#weight' => $multiple + 1, - // Submit callback for disabled JavaScript. drupal_get_form() might get - // the form from the cache, so we can't rely on content_form_alter() - // including this file. Therefore, call a proxy function to do this. - '#submit' => array('content_multigroup_add_more_submit_proxy'), - '#ahah' => array( - 'path' => 'content_multigroup/js_add_more/'. $content_type['url_str'] .'/'. $group_name, - 'wrapper' => $group_name_css .'-items', - 'method' => 'replace', - 'effect' => 'fade', - ), - // When JS is disabled, the content_add_more_submit handler will find - // the relevant field using these entries. - '#group_name' => $group_name, - '#type_name' => $group['type_name'], - ); - // Add wrappers for the group and 'more' button. - // TODO: could be simplified ? - $form_element['#prefix'] = '
'; - $form_element[$group_name .'_add_more']['#prefix'] = '
'; - $form_element[$group_name .'_add_more']['#suffix'] = '
'; - } + // Make sure the form is cached so ahah can work. + $form['#cache'] = TRUE; + $content_type = content_types($group['type_name']); + $group_name = $group['group_name']; + $group_name_css = str_replace('_', '-', $group_name); + + $form_element = array(); + $form_element[$group_name .'_add_more'] = array( + '#type' => 'submit', + '#name' => $group_name .'_add_more', + '#value' => t('Add more values'), + '#weight' => $group_multiple + 1, + '#submit' => array('content_multigroup_add_more_submit'), + '#ahah' => array( + 'path' => 'content_multigroup/js_add_more/'. $content_type['url_str'] .'/'. $group_name, + 'wrapper' => $group_name_css .'-items', + 'method' => 'replace', + 'effect' => 'fade', + ), + // When JS is disabled, the content_multigroup_add_more_submit handler will + // find the relevant field using these entries. + '#group_name' => $group_name, + '#type_name' => $group['type_name'], + ); + + // Add wrappers for the group and 'more' button. + // TODO: could be simplified ? + $form_element['#prefix'] = '
'; + $form_element[$group_name .'_add_more']['#prefix'] = '
'; + $form_element[$group_name .'_add_more']['#suffix'] = '
'; + return $form_element; } @@ -1013,12 +1006,11 @@ * Adapted from content_add_more_js to work with groups instead of fields. */ function content_multigroup_add_more_js($type_name_url, $group_name) { - $type = content_types($type_name_url); - $groups = fieldgroup_groups($type['type']); + $content_type = content_types($type_name_url); + $groups = fieldgroup_groups($content_type['type']); $group = $groups[$group_name]; - $group['multiple'] = $group['settings']['multigroup']['multiple']; - if (($group['multiple'] != 1) || empty($_POST['form_build_id'])) { + if (($group['settings']['multigroup']['multiple'] != 1) || empty($_POST['form_build_id'])) { // Invalid request. drupal_json(array('data' => '')); exit; @@ -1059,17 +1051,23 @@ unset($form_state['values'][$group_name][$group['group_name'] .'_add_more']); foreach ($_POST[$group_name] as $delta => $item) { $form_state['values'][$group_name][$delta]['_weight'] = $item['_weight']; - $form_state['values'][$group_name][$delta]['_delta'] = $item['_delta']; } + $group['multiple'] = $group['settings']['multigroup']['multiple']; $form_state['values'][$group_name] = _content_sort_items($group, $form_state['values'][$group_name]); $_POST[$group_name] = _content_sort_items($group, $_POST[$group_name]); // Build our new form element for the whole group, asking for one more element. - - $form_state['item_count'] = array($group_name => count($_POST[$group_name]) + 1); $delta = max(array_keys($_POST[$group_name])) + 1; + $form_state['item_count'] = array($group_name => count($_POST[$group_name]) + 1); content_multigroup_group_form($form, $form_state, $group, $delta); + // Rebuild weight deltas to make sure they all are equally dimensioned. + foreach ($form[$group_name] as $key => $item) { + if (is_numeric($key) && isset($item['_weight']) && is_array($item['_weight'])) { + $form[$group_name][$key]['_weight']['#delta'] = $delta; + } + } + // Save the new definition of the form. $form_state['values'] = array(); form_set_cache($form_build_id, $form, $form_state); @@ -1086,7 +1084,6 @@ // Render the new output. $group_form = $form[$group_name]; - // We add a div around the new content to receive the ahah effect. $group_form[$delta]['#prefix'] = '
'. (isset($group_form[$delta]['#prefix']) ? $group_form[$delta]['#prefix'] : ''); $group_form[$delta]['#suffix'] = (isset($group_form[$delta]['#suffix']) ? $group_form[$delta]['#suffix'] : '') .'
'; @@ -1147,4 +1144,4 @@ $output .= drupal_render($element[$key]); } return $output; -} \ No newline at end of file +}