CCK: Create field groups for CCK fields. Note: Requires content.module.'); } } function fieldgroup_menu($may_cache) { if (!$may_cache) { if (arg(0) == 'admin' && arg(1) == 'node' && arg(2) == 'types' && arg(3)) { if ($type = content_types(arg(3))) { $items[] = array( 'path' => 'admin/node/types/'. arg(3) .'/add_group', 'title' => t('add group'), 'callback' => 'fieldgroup_edit_group', 'access' => user_access('administer content types'), 'callback arguments' => array(arg(3), 'add_group'), 'type' => MENU_LOCAL_TASK, 'weight' => 2, ); if (arg(4) == 'groups' && arg(5)) { $items[] = array( 'path' => 'admin/node/types/'. arg(3) .'/groups/'. arg(5) .'/edit', 'title' => t('edit group'), 'callback' => 'fieldgroup_edit_group', 'access' => user_access('administer content types'), 'callback arguments' => array(arg(3), arg(5)), 'type' => MENU_CALLBACK_ITEM, ); $items[] = array( 'path' => 'admin/node/types/'. arg(3) .'/groups/'. arg(5) .'/remove', 'title' => t('edit group'), 'callback' => 'fieldgroup_remove_group', 'access' => user_access('administer content types'), 'callback arguments' => array(arg(3), arg(5)), 'type' => MENU_CALLBACK_ITEM, ); } } } } return $items; } function fieldgroup_edit_group($content_type, $group_name) { $groups = fieldgroup_groups($content_type); $group = $groups[$group_name]; if ($group_name == 'add_group' && arg(6) != 'edit') { //adding a new one $group = array(); $form['submit'] = array( '#type' => 'submit', '#value' => t('Add'), '#weight' => 10, ); } else if ($group) { $form['submit'] = array( '#type' => 'submit', '#value' => t('Save'), '#weight' => 10, ); } else { drupal_not_found(); exit; } $form['label'] = array( '#type' => 'textfield', '#title' => t('Label'), '#default_value' => $group['label'], '#required' => TRUE, ); $form['settings']['collapsible'] = array( '#type' => 'checkbox', '#title' => t('Collapsible'), '#default_value' => $group['settings']['collapsible'], ); $form['settings']['collapsed'] = array( '#type' => 'checkbox', '#title' => t('Collapsed'), '#default_value' => $group['settings']['collapsed'], ); $form['settings']['#tree'] = TRUE; $form['description'] = array( '#type' => 'textarea', '#title' => t('Help text'), '#default_value' => $group['description'], '#rows' => 5, '#description' => t('Instructions to present to the user on the editing form.'), '#required' => FALSE, ); $form['weight'] = array( '#type' => 'weight', '#title' => t('Weight'), '#default_value' => $group['weight'], '#description' => t('In the node editing form, the heavier groups will sink and the lighter groups will be positioned nearer the top.'), ); $form['#submit'] = array(fieldgroup_edit_group_submit => array($content_type, $group_name)); return drupal_get_form('fieldgroup_edit_group', $form); } function fieldgroup_edit_group_submit($form_id, &$form_values, $content_type, $group_name) { $groups = fieldgroup_groups($content_type); $group = $groups[$group_name]; if (!$group) { // Find a valid, computer-friendly name. $group_name = trim($form_values['label']); $group_name = drupal_strtolower($group_name); $group_name = str_replace(array(' ', '-'), '_', $group_name); $group_name = preg_replace('/[^a-z0-9_]/', '', $group_name); $group_name = 'group_'. $group_name; $group_name = substr($group_name, 0, 30); if (isset($groups[$group_name])) { $group_name_base = $group_name; $counter = 0; while (isset($groups[$group_name])) { $group_name = $group_name_base .'_'. $counter++; } } db_query("INSERT INTO {node_group} (type_name, group_name, label, settings, description, weight) VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $content_type, $group_name, $form_values['label'], serialize($form_values['settings']), $form_values['description'], $form_values['weight']); } else { db_query("UPDATE {node_group} SET label = '%s', settings = '%s', description = '%s', weight = %d ". "WHERE type_name = '%s' AND group_name = '%s'", $form_values['label'], serialize($form_values['settings']), $form_values['description'], $form_values['weight'], $content_type, $group_name); } cache_clear_all('fieldgroup_data'); return 'admin/node/types/'. $content_type .'/fields'; } function fieldgroup_remove_group($content_type, $group_name) { $groups = fieldgroup_groups($content_type); $group = $groups[$group_name]; if (!$group) { drupal_not_found(); exit; } $form['#submit'] = array(fieldgroup_remove_group_submit => array($content_type, $group_name)); return confirm_form('fieldgroup_remove_group', $form, t('Are you sure you want to remove the group %label?', array('%label' => theme('placeholder', $group['label']))), 'admin/node/types/'. $content_type .'/fields', t('This action cannot be undone.'), t('Remove'), t('Cancel')); } function fieldgroup_remove_group_submit($form_id, &$form_values, $content_type, $group_name) { db_query("DELETE FROM {node_group} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name); db_query("DELETE FROM {node_group_fields} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name); cache_clear_all('fieldgroup_data'); drupal_set_message('The group has been removed.'); return 'admin/node/types/'. $content_type .'/fields'; } /* * Returns all groups for a content type */ function fieldgroup_groups($content_type, $sorted = FALSE) { static $groups = array(); static $groups_sorted = array(); if (empty($groups)) { if ($cached = cache_get('fieldgroup_data')) { $data = unserialize($cached->data); $groups = &$data['groups']; $groups_sorted = &$data['groups_sorted']; } else { $result = db_query("SELECT g.* FROM {node_group} g ORDER BY g.weight, g.group_name"); while ($group = db_fetch_array($result)) { $group['settings'] = unserialize($group['settings']); $group['fields'] = array(); $groups[$group['type_name']][$group['group_name']] = $group; $groups_sorted[$group['type_name']][] = &$groups[$group['type_name']][$group['group_name']]; } //load fields $result = db_query("SELECT fi.*, g.group_name FROM {node_group} g ". "INNER JOIN {node_group_fields} f ON f.type_name = g.type_name AND f.group_name = g.group_name ". "INNER JOIN {node_field_instance} fi ON fi.field_name = f.field_name AND fi.type_name = f.type_name ". "ORDER BY fi.weight"); while ($field = db_fetch_array($result)) { $groups[$field['type_name']][$field['group_name']]['fields'][$field['field_name']] = $field; } cache_set('fieldgroup_data', serialize(array('groups' => $groups, 'groups_sorted' => $groups_sorted)), CACHE_PERMANENT); } } if (!$groups[$content_type]) { return array(); } return $sorted ? $groups_sorted[$content_type] : $groups[$content_type]; } function _fieldgroup_groups_label($content_type) { $groups = fieldgroup_groups($content_type); $labels[0] = t('No group'); foreach ($groups as $group_name => $group) { $labels[$group_name] = $group['label']; } return $labels; } function _fieldgroup_field_get_group($content_type, $field_name) { return db_result(db_query("SELECT group_name FROM {node_group_fields} WHERE type_name = '%s' AND field_name = '%s'", $content_type, $field_name)); } /* * Implementation of hook_form_alter() */ function fieldgroup_form_alter($form_id, &$form) { if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id && node_get_base($form['#node']) == 'content') { foreach (fieldgroup_groups($form['type']['#value']) as $group_name => $group) { $form[$group_name] = array( '#type' => 'fieldset', '#title' => t($group['label']), '#collapsed' => $group['settings']['collapsed'], '#collapsible' => $group['settings']['collapsible'], '#description' => t($group['description']), '#weight' => $group['weight'], '#attributes' => array('class' => strtr($group['group_name'], '_', '-')), ); foreach ($group['fields'] as $field_name => $field) { if (isset($form[$field_name])) { $form[$group_name][$field_name] = $form[$field_name]; 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]); } } } else if ($form_id == '_content_admin_field') { $form['widget']['group'] = array( '#type' => 'select', '#title' => t('Display in group'), '#options' => _fieldgroup_groups_label(arg(3)), '#default_value' => _fieldgroup_field_get_group(arg(3), arg(5)), '#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; $form['#submit']['fieldgroup_content_admin_form_submit'] = array($form['widget']['group']['#default_value']); } else if ($form_id == '_content_admin_field_remove' || $form_id == '_content_admin_type_delete') { $form['#submit']['fieldgroup_content_admin_remove_submit'] = array(); } } function fieldgroup_content_admin_form_submit($form_id, &$form_values, $default) { if ($default != $form_values['group']) { if ($form_values['group'] && !$default) { db_query("INSERT INTO {node_group_fields} (type_name, group_name, field_name) VALUES ('%s', '%s', '%s')", $form_values['type_name'], $form_values['group'], $form_values['field_name']); } else if ($form_values['group']) { db_query("UPDATE {node_group_fields} SET group_name = '%s' WHERE type_name = '%s' AND field_name = '%s'", $form_values['group'], $form_values['type_name'], $form_values['field_name']); } else { db_query("DELETE FROM {node_group_fields} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']); } cache_clear_all('fieldgroup_data'); } } function fieldgroup_content_admin_remove_submit($form_id, &$form_values) { if ($form_values['field_name']) { //a field has been removed db_query("DELETE FROM {node_group_fields} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']); } else { //the whole content-type has been deleted db_query("DELETE FROM {node_group_fields} WHERE type_name = '%s'", $form_values['type_name']); db_query("DELETE FROM {node_group} WHERE type_name = '%s'", $form_values['type_name']); } } /* * Gets 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. */ function fieldgroup_get_group($content_type, $field_name) { foreach (fieldgroup_groups($content_type) as $group_name => $group) { if (in_array($field_name, array_keys($group['fields']))) { return $group_name; } } return FALSE; } /* * Duplicates all fieldgroups, used when content types are duplicated */ function fieldgroup_duplicate($original_content_type, $content_type) { foreach (fieldgroup_groups($original_content_type) as $group_name => $group) { db_query("INSERT INTO {node_group} (type_name, group_name, label, settings, description, weight) VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $content_type, $group_name, $group['label'], serialize($group['settings']), $group['description'], $group['weight']); foreach ($group['fields'] as $field_name => $field) { db_query("INSERT INTO {node_group_fields} (type_name, group_name, field_name) VALUES ('%s', '%s', '%s')", $content_type, $group_name, $field_name); } } cache_clear_all('fieldgroup_data'); }