Index: includes/content.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/includes/Attic/content.admin.inc,v
retrieving revision 1.181.2.68.2.5
diff -u -r1.181.2.68.2.5 content.admin.inc
--- includes/content.admin.inc 19 Jul 2009 13:04:21 -0000 1.181.2.68.2.5
+++ includes/content.admin.inc 19 Aug 2009 19:45:06 -0000
@@ -141,6 +141,7 @@
if (module_exists('fieldgroup')) {
$groups = fieldgroup_groups($type['type']);
$group_types = fieldgroup_types();
+ $plain_tree = _fieldgroup_plain_tree($groups);
$group_options = _fieldgroup_groups_label($type['type']);
// Add the ability to group under the newly created row.
$group_options['_add_new_group'] = '_add_new_group';
@@ -188,6 +189,8 @@
// Groups.
foreach ($groups as $name => $group) {
+ $current_group_options = $plain_tree;
+ unset($current_group_options[$name]);
$weight = $group['weight'];
$form[$name] = array(
'label' => array('#value' => check_plain($group['label'])),
@@ -196,17 +199,23 @@
'configure' => array('#value' => l(t('Configure'), 'admin/content/node-type/'. $type['url_str'] .'/groups/'. $group['group_name'])),
'remove' => array('#value' => l(t('Remove'), 'admin/content/node-type/'. $type['url_str'] .'/groups/'. $group['group_name'] .'/remove')),
'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
- 'parent' => array('#type' => 'hidden', '#default_value' => ''),
+ 'parent' => array('#type' => 'select', '#options' => $current_group_options, '#default_value' => ''),
+ 'prev_parent' => array('#type' => 'hidden', '#value' => ''),
'hidden_name' => array('#type' => 'hidden', '#default_value' => $group['group_name']),
- '#root' => TRUE,
'#row_type' => 'group',
'group' => array('#type' => 'value', '#value' => $group),
);
// Adjust child fields rows.
- foreach ($group['fields'] as $field_name => $field) {
- $form[$field_name]['parent']['#default_value'] = $name;
- $form[$field_name]['prev_parent']['#value'] = $name;
+ if (isset($group['fields'])) {
+ foreach ($group['fields'] as $field_name => $field) {
+ $form[$field_name]['parent']['#default_value'] = $name;
+ $form[$field_name]['prev_parent']['#value'] = $name;
+ }
}
+ // Adjust child group rows
+ $form[$name]['parent']['#default_value'] = $group['parent_group_name'];
+ $form[$name]['prev_parent']['#value'] = $group['parent_group_name'];
+
$form['#group_rows'][] = $name;
$weights[] = $weight;
}
@@ -308,6 +317,9 @@
// Additional row : add new group.
if (!empty($group_types)) {
+ $current_group_options = $group_options;
+ $options = fieldgroup_types();
+ unset($current_group_options[_add_new_group]);
$weight++;
$name = '_add_new_group';
$form[$name] = array(
@@ -334,9 +346,9 @@
'#value' => 'standard',
),
'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
- 'parent' => array('#type' => 'hidden', '#default_value' => ''),
+ 'parent' => array('#type' => 'select', '#options' => $current_group_options, '#default_value' => ''),
+ 'prev_parent' => array('#type' => 'hidden', '#value' => ''),
'hidden_name' => array('#type' => 'hidden', '#default_value' => $name),
- '#root' => TRUE,
'#add_new' => TRUE,
'#row_type' => 'add_new_group',
);
@@ -650,6 +662,7 @@
$form[$name] = array(
'human_name' => array('#value' => check_plain($group['label'])),
'weight' => array('#type' => 'value', '#value' => $weight),
+ 'parent' => array('#type' => 'value', '#value' => ''),
);
if ($contexts_selector == 'basic') {
$form[$name]['label'] = array(
@@ -674,6 +687,8 @@
foreach ($group['fields'] as $field_name => $field) {
$form[$field_name]['parent']['#value'] = $name;
}
+ $form[$name]['parent']['#value'] = $group['parent_group_name'];
+ $form[$name]['group']['#value']['depth'] = $group['depth'];
}
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
@@ -1640,8 +1655,15 @@
$dummy = array();
// Group rows: account for weight.
if (module_exists('fieldgroup')) {
+ $max_depth = 0;
foreach ($group_rows as $name) {
+ $depth = $form[$name]['group']['#value']['depth'];
+ if ($depth > $max_depth) {
+ $max_depth = $depth;
+ }
+ $parent = $form[$name]['parent']['#value'];
$dummy[$name] = array('#weight' => $form[$name]['weight']['#value'], '#value' => $name .' ');
+ $form[$name]['#depth'] = $depth;
}
}
// Field rows : account for weight and parenting.
@@ -1649,12 +1671,29 @@
$dummy[$name] = array('#weight' => $form[$name]['weight']['#value'], '#value' => $name .' ');
if (module_exists('fieldgroup')) {
if ($parent = $form[$name]['parent']['#value']) {
- $form[$name]['#depth'] = 1;
+ $depth = $form[$parent]['group']['#value']['depth'] + 1;
+ $form[$name]['#depth'] = $depth;
$dummy[$parent][$name] = $dummy[$name];
unset($dummy[$name]);
}
}
}
+ //we have to do this at the end so as to cascade these moves bottom-up rather than use a recursive function top-down
+ if (module_exists('fieldgroup')) {
+ while ($max_depth >= 0) {
+ foreach ($group_rows as $name) {
+ if ($form[$name]['group']['#value']['depth'] == $max_depth) {
+ $parent = $form[$name]['parent']['#value'];
+ if (isset($parent) && $parent != '') {
+ $dummy[$parent][$name] = $dummy[$name];
+ unset($dummy[$name]);
+ }
+ }
+ }
+ $max_depth--;
+ }
+ }
+ //drupal_set_message('
Dummy: ' .print_r($dummy, TRUE). '
');
return $dummy ? explode(' ', trim(drupal_render($dummy))) : array();
}
Index: includes/content.node_form.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/includes/Attic/content.node_form.inc,v
retrieving revision 1.7.2.19.2.3
diff -u -r1.7.2.19.2.3 content.node_form.inc
--- includes/content.node_form.inc 18 Jul 2009 00:46:09 -0000 1.7.2.19.2.3
+++ includes/content.node_form.inc 19 Aug 2009 19:47:10 -0000
@@ -468,12 +468,7 @@
drupal_alter('form', $form_element, array(), 'content_add_more_js');
// Add the new element at the right place in the (original, unbuilt) form.
- if (module_exists('fieldgroup') && ($group_name = _fieldgroup_field_get_group($type['type'], $field_name))) {
- $form[$group_name][$field_name] = $form_element[$field_name];
- }
- else {
- $form[$field_name] = $form_element[$field_name];
- }
+ content_set_form_element($field_name, $type['type'], $form, $form_element[$field_name]);
// Save the new definition of the form.
$form_state['values'] = array();
@@ -490,7 +485,8 @@
$form = form_builder($_POST['form_id'], $form, $form_state);
// Render the new output.
- $field_form = (!empty($group_name)) ? $form[$group_name][$field_name] : $form[$field_name];
+ $field_form = content_get_form_element($field_name, $type['type'], $form);
+
// We add a div around the new content to receive the ahah effect.
$field_form[$delta]['#prefix'] = ''. (isset($field_form[$delta]['#prefix']) ? $field_form[$delta]['#prefix'] : '');
$field_form[$delta]['#suffix'] = (isset($field_form[$delta]['#suffix']) ? $field_form[$delta]['#suffix'] : '') .'
';
@@ -514,3 +510,74 @@
print drupal_to_js(array('status' => TRUE, 'data' => $output));
exit;
}
+
+/**
+ * Store an element into a form.
+ *
+ * @param $name
+ * The field name.
+ * @param $type
+ * The content type where the field instance belongs to.
+ * @param $form
+ * The form to store this field element into.
+ * @param $element
+ * The form element to store.
+ */
+function content_set_form_element($name, $type, &$form, $element, $is_group = FALSE) {
+ if (module_exists('fieldgroup') && ($parents = _fieldgroup_field_get_parents($type, $name, $is_group))) {
+ foreach (module_implements('fieldgroup_parents_alter') as $module) {
+ $parents = call_user_func($module .'_fieldgroup_parents_alter', $form, $parents, $type, $name);
+ }
+ $reference = &$form;
+ if ($is_group) {
+ array_shift($parents);
+ $parents = array_reverse($parents);
+ }
+ else {
+ $parents = array_reverse($parents);
+ }
+
+ foreach (array_values($parents) as $group_name) {
+ $reference = &$reference[$group_name];
+ }
+
+ $reference[$name] = $element;
+
+ }
+ else {
+ $form[$name] = $element;
+ }
+}
+
+/**
+ * Retrieve an element from a form.
+ *
+ * @param $name
+ * The field name.
+ * @param $type
+ * The content type where the field instance belongs to.
+ * @param $form
+ * The form to retrieve this field element from.
+ */
+function content_get_form_element($name, $type, $form, $is_group = FALSE) {
+ if (module_exists('fieldgroup') && ($parents = _fieldgroup_field_get_parents($type, $name, $is_group))) {
+ foreach (module_implements('fieldgroup_parents_alter') as $module) {
+ $parents = call_user_func($module .'_fieldgroup_parents_alter', $form, $parents, $type, $name);
+ }
+ $reference = &$form;
+ if ($is_group) {
+ array_shift($parents);
+ $parents = array_reverse($parents);
+ }
+ else {
+ $parents = array_reverse($parents);
+ }
+
+ foreach (array_values($parents) as $group_name) {
+ $reference = &$reference[$group_name];
+ }
+
+ return $reference[$name];
+ }
+ return $form[$name];
+}
Index: modules/content_multigroup/content_multigroup.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/content_multigroup/Attic/content_multigroup.admin.inc,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 content_multigroup.admin.inc
--- modules/content_multigroup/content_multigroup.admin.inc 10 Aug 2009 04:58:16 -0000 1.1.2.3
+++ modules/content_multigroup/content_multigroup.admin.inc 19 Aug 2009 19:54:16 -0000
@@ -46,6 +46,7 @@
// See if we have fields moving into or out of a Multigroup.
// Set any fields to use the new name here so they will get processed
// correctly by the fieldgroup module when saved.
+ $group_rows = array();
foreach ($form_values as $key => $values) {
if ($values['parent'] == '_add_new_group') {
$values['parent'] = $new_group_name;
@@ -56,6 +57,7 @@
// Gather up info about all groups.
$group_name = $form_values[$key]['group']['group_name'];
$groups[$group_name] = $form_values[$key]['group'];
+ $group_rows[$group_name] = $group_name;
}
if (!empty($form[$key]['#row_type']) && $form[$key]['#row_type'] == 'field') {
if ($values['prev_parent'] != $values['parent']) {
@@ -66,6 +68,18 @@
}
$rebuild = FALSE;
+
+ foreach ($groups as $key => $values) {
+ if (in_array($key, $group_rows)) {
+ if (!empty($groups[$key]['parent']) && $groups[$groups[$key]['parent']]['group_type'] == 'multigroup') {
+ $error_message = t('You cannot place any kind of group inside a multigroup. ' . $key . ' was moved back to where it started.');
+ form_set_value($form[$key]['weight'], $form[$key]['weight']['#default_value'], $form_state);
+ form_set_value($form[$key]['parent'], $form[$key]['parent']['#default_value'], $form_state);
+ drupal_set_message($error_message, 'error');
+ }
+ }
+ }
+
foreach ($fields as $field_name => $field) {
$new_group = $form_values[$field_name]['parent'];
$old_group = $form_values[$field_name]['prev_parent'];
@@ -234,6 +248,10 @@
return;
}
+ $groups = array();
+ if (module_exists('fieldgroup')) {
+ $groups = fieldgroup_groups($type_name);
+ }
$contexts = content_build_modes($contexts_selector);
// Multigroups, extra values.
@@ -248,7 +266,7 @@
'table-single' => t('Table - Single column'),
'table-multiple' => t('Table - Multiple columns'),
);
- foreach (fieldgroup_groups($type_name) as $group_name => $group) {
+ foreach ($groups as $group_name => $group) {
if ($group['group_type'] != 'multigroup') {
continue;
}
Index: modules/content_multigroup/content_multigroup.node_form.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/content_multigroup/Attic/content_multigroup.node_form.inc,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 content_multigroup.node_form.inc
--- modules/content_multigroup/content_multigroup.node_form.inc 10 Aug 2009 04:07:51 -0000 1.1.2.10
+++ modules/content_multigroup/content_multigroup.node_form.inc 19 Aug 2009 20:10:47 -0000
@@ -105,11 +105,13 @@
if (!in_array('content_multigroup_node_form_pre_render', $form['#pre_render'])) {
array_unshift($form['#pre_render'], 'content_multigroup_node_form_pre_render');
}
-
+ $elements[$group_name] = array();
foreach ($group_deltas as $delta) {
- content_multigroup_group_form($form, $form_state, $group, $delta);
+ $element = content_multigroup_group_form($form, $form_state, $group, $delta);
+ $elements[$group_name] = array_merge($elements[$group_name], $element[$group_name]);
}
-
+ $form[$group_name] = $elements[$group_name];
+
// Unset the original group field values now that we've moved them.
foreach (array_keys($group_fields) as $field_name) {
unset($form[$group_name][$field_name]);
@@ -126,36 +128,49 @@
* Called in form_alter and by AHAH add more.
*/
function content_multigroup_group_form(&$form, &$form_state, $group, $delta) {
+ module_load_include('inc', 'content', 'includes/content.node_form');
+ $element = array();
+ $type_name = $group['type_name'];
+ $content_type = content_types($type_name);
$group_name = $group['group_name'];
- if ($group['group_type'] != 'multigroup' || empty($form[$group_name]) || empty($form['#multigroups']) || empty($form['#multigroups'][$group_name])) {
+
+ if (!isset($form[$group_name])) {//nested AHAH, not initial build
+ $element[$group_name] = content_get_form_element($group_name, $type_name, $form, TRUE);
+ }
+ else {//initial build (via content_multigroup_fieldgroup_form) or non-nested AHAH
+ $element[$group_name] = $form[$group_name];
+ }
+ if (($group['group_type'] != 'multigroup')
+ || (!(empty($element[$group['group_name']]['#access'])) && $element[$group['group_name']]['#access'] != TRUE)
+ || empty($element[$group['group_name']])) {
return;
}
- module_load_include('inc', 'content', 'includes/content.node_form');
-
- $node = $form['#node'];
+
$group_fields = $form['#multigroups'][$group_name];
+ $element[$group_name]['#fields'] = array_keys($group_fields);
+ $node = $form['#node'];
$group_multiple = $group['settings']['multigroup']['multiple'];
foreach ($group_fields as $field_name => $field) {
- if (empty($form[$group_name][$delta])) {
- $form[$group_name] += array($delta => array($field_name => array()));
+ if (empty($element[$group_name][$delta])) {
+ $element[$group_name] += array($delta => array($field_name => array()));
}
else {
- $form[$group_name][$delta][$field_name] = array();
+ $element[$group_name][$delta][$field_name] = array();
}
-
- $item_count = (isset($form_state['item_count'][$group_name]) ? $form_state['item_count'][$group_name] : $form[$group_name]['#item_count']);
- $form[$group_name][$delta]['_weight'] = array(
+
+ $item_count = (isset($form_state['item_count'][$group_name]) ? $form_state['item_count'][$group_name] : $element[$group_name]['#item_count']);
+ $element[$group_name][$delta]['_weight'] = array(
'#type' => 'weight',
'#delta' => $item_count, // this 'delta' is the 'weight' element's property
'#default_value' => $delta,
'#weight' => 100,
);
-
+
// Add a checkbox to allow users remove a single delta subgroup.
// See content_set_empty() and theme_content_multigroup_node_form().
if ($group_multiple == 1) {
- $form[$group_name][$delta]['_remove'] = array(
+ $element[$group_name][$delta]['_remove'] = array(
'#type' => 'checkbox',
'#attributes' => array('class' => 'content-multiple-remove-checkbox'),
'#default_value' => isset($form_state['multigroup_removed'][$group_name][$delta]) ? $form_state['multigroup_removed'][$group_name][$delta] : 0,
@@ -200,7 +215,7 @@
if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
$field_form = content_field_form($form, $form_state, $field, $delta);
$value = array_key_exists($delta, $field_form[$field_name]) ? $delta : 0;
- $form[$group_name][$delta][$field_name] = $field_form[$field_name][$value];
+ $element[$group_name][$delta][$field_name] = $field_form[$field_name][$value];
}
else {
// When the form is submitted, get the element data from the form values.
@@ -224,14 +239,16 @@
$field_form[$field_name]['#element_validate'] = array();
}
$field_form[$field_name]['#element_validate'][] = 'content_multigroup_fix_multivalue_fields';
-
- $form[$group_name][$delta][$field_name] = $field_form[$field_name];
+
+ $element[$group_name][$delta][$field_name] = $field_form[$field_name];
}
- $form[$group_name][$delta][$field_name]['#weight'] = $field['widget']['weight'];
+ $element[$group_name][$delta][$field_name]['#weight'] = $field['widget']['weight'];
}
// Reset the form '#node' back to its original value.
$form['#node'] = $node;
+
+ return $element;
}
/**
@@ -726,15 +743,17 @@
// Build our new form element for the whole group, asking for one more element.
$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);
+ $form_element = 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) {
+ foreach ($form_element[$group_name] as $key => $item) {
if (is_numeric($key) && isset($item['_weight']) && is_array($item['_weight'])) {
- $form[$group_name][$key]['_weight']['#delta'] = $delta;
+ $form_element[$group_name][$key]['_weight']['#delta'] = $delta;
}
}
-
+ // Add the new element at the right place in the (original, unbuilt) form.
+ content_set_form_element($group_name, $content_type['type'], $form, $form_element[$group_name], TRUE);
+
// Save the new definition of the form.
$form_state['values'] = array();
form_set_cache($form_build_id, $form, $form_state);
@@ -750,7 +769,7 @@
$form = form_builder($_POST['form_id'], $form, $form_state);
// Render the new output.
- $group_form = $form[$group_name];
+ $group_form = content_get_form_element($group_name, $content_type['type'], $form, TRUE);
// 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'] : '') .'
';
Index: modules/fieldgroup/fieldgroup.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/fieldgroup/fieldgroup.install,v
retrieving revision 1.34.2.19
diff -u -r1.34.2.19 fieldgroup.install
--- modules/fieldgroup/fieldgroup.install 26 Dec 2008 11:51:46 -0000 1.34.2.19
+++ modules/fieldgroup/fieldgroup.install 19 Aug 2009 20:14:03 -0000
@@ -52,6 +52,7 @@
'group_type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => 'standard'),
'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
'group_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'parent_group_name' => array('type' => 'varchar', 'length' => 32, 'not null' => FALSE, 'default' => ''),
'label' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
'settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE),
'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
@@ -313,4 +314,16 @@
$ret = array();
$ret[] = update_sql("DELETE FROM {content_group_fields} WHERE (field_name, type_name) NOT IN (SELECT field_name, type_name FROM {content_node_field_instance})");
return $ret;
+}
+
+/**
+ * allow for nesting of fieldgroups
+ */
+function fieldgroup_update_6008() {
+ if ($abort = content_check_update('fieldgroup')) {
+ return $abort;
+ }
+ $ret = array();
+ db_add_field($ret, 'content_group', 'parent_group_name', array('type' => 'varchar', 'length' => 32, 'not null' => FALSE, 'default' => ''));
+ return $ret;
}
\ No newline at end of file
Index: modules/fieldgroup/fieldgroup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/fieldgroup/fieldgroup.module,v
retrieving revision 1.79.2.48.2.3
diff -u -r1.79.2.48.2.3 fieldgroup.module
--- modules/fieldgroup/fieldgroup.module 14 Aug 2009 12:17:58 -0000 1.79.2.48.2.3
+++ modules/fieldgroup/fieldgroup.module 19 Aug 2009 21:04:28 -0000
@@ -166,6 +166,7 @@
$form['settings']['display']['label'] = array('#type' => 'value', '#value' => $group['settings']['display']['label']);
$form['weight'] = array('#type' => 'hidden', '#default_value' => $group['weight']);
$form['group_name'] = array('#type' => 'hidden', '#default_value' => $group_name);
+ $form['parent_group_name'] = array('#type' => 'hidden', '#default_value' => $group['parent_group_name']);
$form['#content_type'] = $content_type;
@@ -210,6 +211,9 @@
$form_values = $form_state['values'];
$content_type = $form['#content_type'];
$group_name = $form['#group_name'];
+ $parent_group_name = db_fetch_array(db_query("SELECT parent_group_name FROM {". fieldgroup_tablename() ."} WHERE group_name = '%s' and type_name = '%s'", $group_name, $content_type['type']));
+ $result = db_query("UPDATE {". fieldgroup_tablename() ."} SET parent_group_name = '%s' WHERE parent_group_name = '%s'", $parent_group_name['parent_group_name'], $group_name);
+ $result = db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET group_name = '%s' WHERE group_name = '%s'", $parent_group_name['parent_group_name'], $group_name);
fieldgroup_delete($content_type['type'], $group_name);
drupal_set_message(t('The group %group_name has been removed.', array('%group_name' => $group_name)));
$form_state['redirect'] = 'admin/content/node-type/'. $content_type['url_str'] .'/fields';
@@ -228,45 +232,14 @@
$groups_sorted = $data['groups_sorted'];
}
else {
- $result = db_query("SELECT * FROM {". fieldgroup_tablename() ."} ORDER BY weight, group_name");
+ $result = db_query("SELECT * FROM {". fieldgroup_tablename() ."} ORDER BY type_name, weight");
$groups = array();
$groups_sorted = array();
while ($group = db_fetch_array($result)) {
- $group['settings'] = unserialize($group['settings']);
- $group['fields'] = array();
-
- // Allow external modules to translate field group strings.
- $group_strings = array(
- 'label' => $group['label'],
- 'form_description' => $group['settings']['form']['description'],
- 'display_description' => $group['settings']['display']['description'],
- );
- drupal_alter('content_fieldgroup_strings', $group_strings, $group['type_name'], $group['group_name']);
- $group['label'] = $group_strings['label'];
- $group['settings']['form']['description'] = $group_strings['form_description'];
- $group['settings']['display']['description'] = $group_strings['display_description'];
-
- $groups[$group['type_name']][$group['group_name']] = $group;
+ $groups[$group['type_name']] = _fieldgroup_get_tree($group['type_name']);
$groups_sorted[$group['type_name']][] = &$groups[$group['type_name']][$group['group_name']];
}
- //load fields
- $result = db_query("SELECT nfi.*, ng.group_name FROM {". fieldgroup_tablename() ."} ng ".
- "INNER JOIN {". fieldgroup_fields_tablename() ."} ngf ON ngf.type_name = ng.type_name AND ngf.group_name = ng.group_name ".
- "INNER JOIN {". content_instance_tablename() ."} nfi ON nfi.field_name = ngf.field_name AND nfi.type_name = ngf.type_name ".
- "WHERE nfi.widget_active = 1 ORDER BY nfi.weight");
- while ($field = db_fetch_array($result)) {
- // Allow external modules to translate field strings.
- $field_strings = array(
- 'widget_label' => $field['label'],
- 'widget_description' => $field['description'],
- );
- drupal_alter('content_field_strings', $field_strings, $field['type_name'], $field['field_name']);
- $field['label'] = $field_strings['widget_label'];
- $field['description'] = $field_strings['widget_description'];
-
- $groups[$field['type_name']][$field['group_name']]['fields'][$field['field_name']] = $field;
- }
- cache_set('fieldgroup_data:'. $language->language, array('groups' => $groups, 'groups_sorted' => $groups_sorted), content_cache_tablename());
+ cache_set('fieldgroup_data', array('groups' => $groups, 'groups_sorted' => $groups_sorted), content_cache_tablename());
}
}
if (empty($content_type)) {
@@ -278,6 +251,81 @@
return $sorted ? $groups_sorted[$content_type] : $groups[$content_type];
}
+/**
+ * create a tree of fieldgroups for nesting them
+ */
+function _fieldgroup_get_tree($type_name, $parent_group_name = '', $depth = -1, $max_depth = null) {
+ static $children, $parents, $groups;
+
+ $depth++;
+ // We cache trees, so it's not CPU-intensive to call get_tree() on a term
+ // and its children, too.
+ if (!isset($children[$type_name])) {
+ $children[$type_name] = array();
+
+ $s = "SELECT * FROM {". fieldgroup_tablename() ."} WHERE type_name='%s' ORDER BY weight";
+ $r = db_query($s, $type_name);
+ while ($group = db_fetch_array($r)) {
+ $groups[$type_name][$group['group_name']]['settings'] = unserialize($group['settings']);
+ $groups[$type_name][$group['group_name']]['fields'] = array();
+
+ // Allow external modules to translate field group strings.
+ $group_strings = array(
+ 'label' => $group['label'],
+ 'form_description' => $group['settings']['form']['description'],
+ 'display_description' => $group['settings']['display']['description'],
+ );
+ drupal_alter('content_fieldgroup_strings', $group_strings, $type_name, $group['group_name']);
+ $group['label'] = $group_strings['label'];
+ $group['settings']['form']['description'] = $group_strings['form_description'];
+ $group['settings']['display']['description'] = $group_strings['display_description'];
+
+ $children[$type_name][$group['parent_group_name']][] = $group['group_name'];
+ $parents[$type_name][$group['group_name']][] = $group['parent_group_name'];
+ $groups[$type_name][$group['group_name']] = $group;
+ }
+ //load fields
+ $result = db_query("SELECT nfi.*, ng.group_name FROM {". fieldgroup_tablename() ."} ng ".
+ "INNER JOIN {". fieldgroup_fields_tablename() ."} ngf ON ngf.type_name = ng.type_name AND ngf.group_name = ng.group_name ".
+ "INNER JOIN {". content_instance_tablename() ."} nfi ON nfi.field_name = ngf.field_name AND nfi.type_name = ngf.type_name ".
+ "WHERE nfi.widget_active = 1 ORDER BY nfi.weight");
+ while ($field = db_fetch_array($result)) {
+ $groups[$field['type_name']][$field['group_name']]['fields'][$field['field_name']] = $field;
+ }
+ }
+
+ $max_depth = (is_null($max_depth)) ? count($children[$type_name]) : $max_depth;
+ if (isset($children[$type_name][$parent_group_name])) {
+ foreach ($children[$type_name][$parent_group_name] as $child_group_name) {
+ if ($max_depth > $depth) {
+ $group = $groups[$type_name][$child_group_name];
+ $group['depth'] = $depth;
+ $group['parents'] = $parents[$type_name][$child_group_name];
+ $tree[$group['group_name']] = $group;
+ if ($children[$type_name][$child_group_name]) {
+ $tree = array_merge($tree, _fieldgroup_get_tree($type_name, $child_group_name, $depth, $max_depth));
+ }
+ }
+ }
+ }
+ return $tree ? $tree : array();
+}
+
+/**
+ * go through a set of fieldgroups and construct a simple representation of their hierarchy
+ */
+function _fieldgroup_plain_tree($items) {
+ $rows = array();
+ $rows[''] = '<'. t('none') .'>';
+ foreach ($items as $item) {
+ $group_name = $item['group_name'];
+ $label = t($item['label']);
+ if ($group_name) {
+ $rows[$group_name] = str_repeat('--', $item['depth']) . ' ' . $label;
+ }
+ }
+ return $rows;
+}
function _fieldgroup_groups_label($content_type) {
$groups = fieldgroup_groups($content_type);
@@ -293,51 +341,157 @@
return db_result(db_query("SELECT group_name FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $content_type, $field_name));
}
+function _fieldgroup_field_get_parents($content_type, $name, $is_group = FALSE) {
+ $counter = 0;
+ if ($is_group) {
+ $parents[$counter] = $name;
+ }
+ else {
+ if ($result = db_result(db_query("SELECT group_name FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $content_type, $name))) {
+ $parents[$counter] = $result;
+ }
+ }
+ while ($result = db_result(db_query("SELECT parent_group_name FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $parents[$counter]))) {
+ $counter++;
+ $parents[$counter] = $result;
+ }
+ return $parents;
+}
+
+function _fieldgroup_add_group_to_form(&$form, &$form_state, $form_id, $group_name, $group, $groups) {
+ $form[$group_name] = array(
+ '#type' => 'fieldset',
+ '#title' => check_plain(t($group['label'])),
+ '#collapsed' => $group['settings']['form']['style'] == 'fieldset_collapsed',
+ '#collapsible' => in_array($group['settings']['form']['style'], array('fieldset_collapsed', 'fieldset_collapsible')),
+ '#weight' => $group['weight'],
+ '#depth' => $group['depth'],
+ '#group_parent' => $group['parent_group_name'],
+ '#description' => content_filter_xss(t($group['settings']['form']['description'])),
+ '#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
+ );
+ $has_accessible_field = FALSE;
+ foreach ($group['fields'] as $field_name => $field) {
+ if (isset($form[$field_name])) {
+ $form[$field_name]['#weight'] = $field['weight'];
+ $form[$group_name][$field_name] = $form[$field_name];
+ //Track whether this group has any accessible fields within it.
+ if (!isset($form[$field_name]['#access']) || $form[$field_name]['#access'] !== FALSE) {
+ $has_accessible_field = TRUE;
+ }
+ unset($form[$field_name]);
+ }
+ }
+ if (!empty($group['fields']) && !element_children($form[$group_name])) {
+ //hide the fieldgroup, because the fields are hidden too
+ unset($form[$group_name]);
+ }
+
+ if (!$has_accessible_field) {
+ // Hide the fieldgroup, because the fields are inaccessible.
+ $form[$group_name]['#access'] = FALSE;
+ }
+ else {
+ //cascade visibility up
+ $form[$group_name]['#access'] = TRUE;
+ }
+
+ // Allow other modules to alter the form.
+ // Can't use module_invoke_all because we want
+ // to be able to use a reference to $form and $form_state.
+ foreach (module_implements('fieldgroup_form') as $module) {
+ $function = $module .'_fieldgroup_form';
+ $function($form, $form_state, $form_id, $group);
+ }
+}
+
+
+/**
+ * This is function fieldgroup_order_fields_and_groups
+ *
+ * @param array $group_rows An empty array that we will fill.
+ * @param array $groups All of the info we need about all of the groups for the content type we're working on.
+ * @param array $field_check_off This contains the fields. We will unset them as we process them.
+ *
+ */
+function fieldgroup_order_fields_groups(&$group_rows, &$groups, &$field_check_off) {
+ $max_depth = 0;
+ foreach ($group_rows as $name) {
+ $depth = $groups[$name]['depth'];
+ if ($depth > $max_depth) {
+ $max_depth = $depth;
+ }
+ $parent = $groups[$name]['parent_group_name'];
+
+ //run through the fields and come up with new weights for display purposes
+ if (isset($groups[$name]['fields'])) {
+ foreach ($groups[$name]['fields'] as $name2 => $elements) {
+ $depth2 = $groups[$name]['depth'] + 1;
+ $groups[$name]['fields'][$name2]['depth'] = $depth2;
+ if (in_array($name2, $field_check_off)) {
+ $index = array_search($name2, $field_check_off);
+ unset($field_check_off[$index]);
+ }
+ }
+ }
+ }
+ return $max_depth;
+}
+
/**
* Implementation of hook_form_alter()
*/
function fieldgroup_form_alter(&$form, $form_state, $form_id) {
if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
- foreach (fieldgroup_groups($form['type']['#value']) as $group_name => $group) {
- $form[$group_name] = array(
- '#type' => 'fieldset',
- '#title' => check_plain(t($group['label'])),
- '#collapsed' => $group['settings']['form']['style'] == 'fieldset_collapsed',
- '#collapsible' => in_array($group['settings']['form']['style'], array('fieldset_collapsed', 'fieldset_collapsible')),
- '#weight' => $group['weight'],
- '#description' => content_filter_xss(t($group['settings']['form']['description'])),
- '#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
- );
-
- $has_accessible_field = FALSE;
- foreach ($group['fields'] as $field_name => $field) {
- if (isset($form[$field_name])) {
- $form[$group_name][$field_name] = $form[$field_name];
- // Track whether this group has any accessible fields within it.
- if (!isset($form[$field_name]['#access']) || $form[$field_name]['#access'] !== FALSE) {
- $has_accessible_field = TRUE;
+ $group_rows = array();
+ $field_rows = array();
+
+ //prepare data that will make this easier
+ $groups = fieldgroup_groups($form['type']['#value']);
+ if (!empty($groups)) {
+ foreach ($groups as $name => $more) {
+ $group_rows[] = $name;
+ }
+ }
+
+ $fields = $form['#field_info'];
+ if (!empty($fields)) {
+ foreach ($fields as $name => $more) {
+ $field_rows[] = $name;
+ }
+ }
+
+ $max_depth = fieldgroup_order_fields_groups($group_rows, $groups, $field_rows);
+
+ //cover the top level fields that aren't in fieldgroups
+ if (isset($field_rows)) {
+ foreach ($field_rows as $name) {
+ $form[$name]['#depth'] = 0;
+ }
+ }
+
+ //now that we have the order of things as we want them, let's create the fieldsets for the fieldgroups
+ foreach ($groups as $group_name => $group) {
+ _fieldgroup_add_group_to_form($form, $form_state, $form_id, $group_name, $group, $groups);
+ }
+
+ //reorder the groups from the inside-out in order to avoid a recursive function
+ while ($max_depth >= 0) {
+ foreach ($group_rows as $name) {
+ if ($form[$name]['#depth'] == $max_depth) {
+ $parent = $form[$name]['#group_parent'];
+ if (isset($parent) && $parent != '') {
+ $form[$parent][$name] = $form[$name];
+ if ($form[$name]['#access']) {
+ $form[$parent]['#access'] = TRUE;
+ }
+ unset($form[$name]);
+ $index = array_search($name, $group_rows);
+ unset($group_rows[$index]);
}
- unset($form[$field_name]);
}
}
- if (!empty($group['fields']) && !element_children($form[$group_name])) {
- //hide the fieldgroup, because the fields are hidden too
- unset($form[$group_name]);
- }
-
- if (!$has_accessible_field) {
- // Hide the fieldgroup, because the fields are inaccessible.
- $form[$group_name]['#access'] = FALSE;
- }
-
- // Allow other modules to alter the form.
- // Can't use module_invoke_all because we want
- // to be able to use a reference to $form and $form_state.
- foreach (module_implements('fieldgroup_form') as $module) {
- $function = $module .'_fieldgroup_form';
- $function($form, $form_state, $form_id, $group);
- }
-
+ $max_depth--;
}
}
@@ -463,6 +617,10 @@
// Parse incoming rows.
$add_field_rows = array('_add_new_field', '_add_existing_field');
$field_rows = array_merge($form['#fields'], $add_field_rows);
+ $add_group_rows = array($new_group_name);
+ $group_rows = array_merge($form['#groups'], $add_group_rows);
+
+
foreach ($form_values as $key => $values) {
// If 'field' row: update field parenting.
if (in_array($key, $field_rows)) {
@@ -486,12 +644,15 @@
// TODO: check the parent group does exist ?
fieldgroup_update_fields(array('field_name' => $key, 'group' => $parent, 'type_name' => $type_name));
}
-
- // If 'group' row: update groups weights
+ }
+
+ foreach ($form_state['values'] as $key => $values) {
+ // If 'group' row: update groups weights and parent
// (possible newly created group has already been taken care of).
- elseif (in_array($key, $form['#groups'])) {
- db_query("UPDATE {". fieldgroup_tablename() ."} SET weight = %d WHERE type_name = '%s' AND group_name = '%s'",
- $values['weight'], $type_name, $key);
+ if (in_array($key, $group_rows)) {
+ $parent = ($values['parent'] == '_add_new_group' && isset($new_group_name)) ? $new_group_name : $values['parent'];
+ $weight = $values['weight'];
+ db_query("UPDATE {". fieldgroup_tablename() ."} SET weight = %d, parent_group_name = '%s' WHERE type_name = '%s' AND group_name = '%s'", $weight, $parent, $type_name, $key);
}
}
@@ -543,10 +704,51 @@
case 'view':
// Prevent against invalid 'nodes' built by broken 3rd party code.
if (isset($node->type)) {
+ //prepare data that will make this easier
+ $group_rows = array();
+ $field_rows = array();
+ $groups = fieldgroup_groups($node->type);
+ if (!empty($groups)) {
+ foreach ($groups as $name => $more) {
+ $group_rows[] = $name;
+ }
+ }
+
+ $fields = $node->content;
+ if (!empty($fields)) {
+ foreach ($fields as $name => $more) {
+ if (strstr($fields, 'field_')) {
+ $field_rows[] = $name;
+ }
+ }
+ }
+
+ $max_depth = fieldgroup_order_fields_groups($group_rows, $groups, $field_rows);
+
+ //cover the top level fields that aren't in fieldgroups
+ if (isset($field_rows)) {
+ foreach ($field_rows as $name) {
+ $node->content[$name]['#depth'] = 0;
+ }
+ }
+
// Build the node content element needed to render each fieldgroup.
- foreach (fieldgroup_groups($node->type) as $group) {
+ foreach ($groups as $group) {
fieldgroup_build_content($group, $node, $teaser, $page);
}
+ //reorder the groups from the inside-out in order to avoid writing a recursive function
+ while ($max_depth >= 0) {
+ foreach ($group_rows as $name) {
+ if ($node->content[$name]['#depth'] == $max_depth) {
+ $parent = $node->content[$name]['#group_parent'];
+ if (isset($parent) && $parent != '') {
+ $node->content[$parent]['group'][$name] = $node->content[$name];
+ unset($node->content[$name]);
+ }
+ }
+ }
+ $max_depth--;
+ }
}
break;
}
@@ -611,6 +813,8 @@
foreach ($group['fields'] as $field_name => $field) {
if (isset($node->content[$field_name])) {
$element[$field_name] = $node->content[$field_name];
+ $element[$field_name]['#weight'] = $field['weight'];
+ $element[$field_name]['#depth'] = $field['depth'];
}
}
@@ -636,10 +840,12 @@
$wrapper = array(
'group' => $element,
'#weight' => $group['weight'],
+ '#depth' => $group['depth'],
'#post_render' => array('fieldgroup_wrapper_post_render'),
'#group_name' => $group_name,
'#type_name' => $node->type,
'#context' => $context,
+ '#group_parent' => $group['parent_group_name'],
);
$node->content[$group_name] = $wrapper;
@@ -734,7 +940,7 @@
return $content;
}
-/*
+/**
* Get the group name for a field.
* If the field isn't in a group, FALSE will be returned.
* @return The name of the group, or FALSE.
@@ -792,7 +998,7 @@
* @todo
* Make this into more of a real API for groups.
*/
-/*
+/**
* Saves the given group for this content-type
*/
function fieldgroup_save_group($type_name, $group) {
@@ -803,18 +1009,19 @@
$function = $module .'_fieldgroup_save_group';
$function($group);
}
-
+
if (!isset($groups[$group['group_name']])) {
// Accept group name from programmed submissions if valid.
- db_query("INSERT INTO {". fieldgroup_tablename() ."} (group_type, type_name, group_name, label, settings, weight)".
- " VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $group['group_type'], $type_name, $group['group_name'], $group['label'], serialize($group['settings']), $group['weight']);
+ db_query("INSERT INTO {". fieldgroup_tablename() ."} (parent_group_name, group_type, type_name, group_name, label, settings, weight)".
+ " VALUES ('%s','%s', '%s', '%s', '%s', '%s', %d)",
+ isset($group['parent']) ? $group['parent'] : $group['parent_group_name'], $group['group_type'], $type_name, $group['group_name'], $group['label'], serialize($group['settings']), $group['weight']);
cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
return SAVED_NEW;
}
else {
- db_query("UPDATE {". fieldgroup_tablename() ."} SET group_type = '%s', label = '%s', settings = '%s', weight = %d ".
- "WHERE type_name = '%s' AND group_name = '%s'",
- $group['group_type'], $group['label'], serialize($group['settings']), $group['weight'], $type_name, $group['group_name']);
+ db_query("UPDATE {". fieldgroup_tablename() ."} SET parent_group_name = '%s', group_type = '%s', label = '%s', settings = '%s', weight = %d ".
+ "WHERE type_name = '%s' AND group_name = '%s'",
+ isset($group['parent']) ? $group['parent'] : $group['parent_group_name'], $group['group_type'], $group['label'], serialize($group['settings']), $group['weight'], $type_name, $group['group_name']);
cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
return SAVED_UPDATED;
}
@@ -884,6 +1091,7 @@
function fieldgroup_preprocess_fieldgroup_simple(&$vars) {
$element = $vars['element'];
+ $vars['parent_group_name'] = $element['#parent_group_name'];
$vars['group_name'] = $element['#group_name'];
$vars['group_name_css'] = strtr($element['#group_name'], '_', '-');
$vars['label'] = isset($element['#title']) ? $element['#title'] : '';;
Index: theme/theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/cck/theme/theme.inc,v
retrieving revision 1.1.2.13.2.1
diff -u -r1.1.2.13.2.1 theme.inc
--- theme/theme.inc 7 Jun 2009 00:31:35 -0000 1.1.2.13.2.1
+++ theme/theme.inc 19 Aug 2009 18:09:59 -0000
@@ -28,6 +28,8 @@
$add_rows[] = $key;
}
}
+ $parent_list = array();
+ $parent_list['top'] = 'top';
while ($order) {
$key = reset($order);
$element = &$form[$key];
@@ -48,7 +50,16 @@
$row = new stdClass();
// Add target classes for the tabledrag behavior.
- $element['weight']['#attributes']['class'] = 'field-weight';
+ if ($element['#row_type'] == 'group') {
+ $parent_list[$element['group_name']['#value']] = strtr($element['group_name']['#value'], '_', '-');
+ }
+ if (empty($element['parent']['#value']) || !isset($element['parent']['#value'])) {
+ $element['weight']['#attributes']['class'] = 'field-weight field-weight-' . 'top';
+ }
+ else {
+ $element['weight']['#attributes']['class'] = 'field-weight field-weight-' . strtr($element['parent']['#value'], '_', '-');
+ }
+
$element['parent']['#attributes']['class'] = 'group-parent';
$element['hidden_name']['#attributes']['class'] = 'field-name';
// Add target classes for the update selects behavior.
@@ -74,6 +85,8 @@
$row->class .= isset($element['#add_new']) ? ' content-add-new' : '';
$row->class .= isset($element['#leaf']) ? ' tabledrag-leaf' : '';
$row->class .= isset($element['#root']) ? ' tabledrag-root' : '';
+ $row->class .= (isset($element['group_type']['#value']) && $element['group_type']['#value'] == 'Standard group') ? ' tabledrag-standardgroup' : '';
+ $row->class .= (isset($element['group_type']['#value']) && $element['group_type']['#value'] == 'Multigroup') ? ' tabledrag-multigroup' : '';
$rows[] = $row;
array_shift($order);
@@ -82,10 +95,15 @@
$vars['submit'] = drupal_render($form);
// Add tabledrag behavior.
-// drupal_add_tabledrag('content-field-overview', 'match', 'parent', 'group-parent', 'group-parent', 'field-name', FALSE, 1);
- drupal_add_tabledrag('content-field-overview', 'match', 'parent', 'group-parent', 'group-parent', 'field-name', TRUE, 1);
-// drupal_add_tabledrag('content-field-overview', 'order', 'sibling', 'field-weight', NULL, NULL, FALSE);
- drupal_add_tabledrag('content-field-overview', 'order', 'sibling', 'field-weight');
+ //drupal_add_tabledrag('content-field-overview', 'match', 'parent', 'group-parent', 'group-parent', 'field-name', FALSE, 10);
+ drupal_add_tabledrag('content-field-overview', 'match', 'parent', 'group-parent', 'group-parent', 'field-name', TRUE, 10);
+ foreach ($parent_list as $name => $parent) {
+ //drupal_add_tabledrag('content-field-overview', 'order', 'sibling', 'field-weight', 'field-weight-' . $parent, NULL, FALSE);
+ drupal_add_tabledrag('content-field-overview', 'order', 'sibling', 'field-weight', 'field-weight-' . $parent, NULL, TRUE);
+ }
+
+ // Override methods in Drupal core tabledrag.js.
+ drupal_add_js(drupal_get_path('module', 'fieldgroup') .'/fieldgroup.tabledrag.js');
// Add settings for the update selects behavior.
$js_fields = array();