Newer
Older
<?php
// $Id$
/**
* @file
* Create field groups for CCK fields.
Karen Stevenson
committed
*
* Hooks for other modules to intervene include:
* - hook_fieldgroup_view: Alter the group $element added to $node->content.
* - hook_fieldgroup_form: Alter the group portion of the node form.
* - hook_fieldgroup_types: Add additional fieldgroup group_types.
Karen Stevenson
committed
* - hook_fieldgroup_default_settings: Add additional fieldgroup default settings.
Karen Stevenson
committed
* - hook_fieldgroup_save: Do additional processing when a fieldgroup is saved.
/**
* Implementation of hook_init().
*/
Karen Stevenson
committed
function fieldgroup_init() {
drupal_add_css(drupal_get_path('module', 'fieldgroup') .'/fieldgroup.css');
if (module_exists('panels')) {
module_load_include('inc', 'fieldgroup', 'fieldgroup.panels');
}
Karen Stevenson
committed
}
Karen Stevenson
committed
/**
* Implementation of hook_menu().
*/
function fieldgroup_menu() {
$items = array();
Karen Stevenson
committed
// Make sure this doesn't fire until content_types is working,
// needed to avoid errors on initial installation.
if (!defined('MAINTENANCE_MODE')) {
foreach (node_get_types() as $type) {
$type_name = $type->type;
Yves Chedemois
committed
$content_type = content_types($type_name);
Karen Stevenson
committed
$type_url_str = $content_type['url_str'];
$items['admin/content/node-type/'. $type_url_str .'/groups/%'] = array(
Karen Stevenson
committed
'title' => 'Edit group',
'page callback' => 'drupal_get_form',
Yves Chedemois
committed
'page arguments' => array('fieldgroup_group_edit_form', $type_name, 5),
Karen Stevenson
committed
'access arguments' => array('administer content types'),
'type' => MENU_CALLBACK,
);
$items['admin/content/node-type/'. $type_url_str .'/groups/%/remove'] = array(
Karen Stevenson
committed
'title' => 'Edit group',
'page callback' => 'drupal_get_form',
Yves Chedemois
committed
'page arguments' => array('fieldgroup_remove_group', $type_name, 5),
Karen Stevenson
committed
'access arguments' => array('administer content types'),
'type' => MENU_CALLBACK,
);
}
Karen Stevenson
committed
}
Karen Stevenson
committed
/**
* Implementation of hook_theme().
*/
function fieldgroup_theme() {
return array(
'fieldgroup_simple' => array(
Karen Stevenson
committed
'arguments' => array('element' => NULL),
'fieldgroup_fieldset' => array(
'arguments' => array('element' => NULL),
),
Karen Stevenson
committed
'fieldgroup_display_overview_form' => array(
Karen Stevenson
committed
'arguments' => array('form' => NULL),
Karen Stevenson
committed
);
/**
* Implementation of hook_elements().
*/
function fieldgroup_elements() {
return array(
'fieldgroup_simple' => array(),
'fieldgroup_fieldset' => array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL,),
Karen Stevenson
committed
/**
* Implementation of hook_fieldapi().
*/
Karen Stevenson
committed
function fieldgroup_content_fieldapi($op, $field) {
Karen Stevenson
committed
switch ($op) {
case 'delete':
Yves Chedemois
committed
db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE field_name = '%s'", $field['field_name']);
Karen Stevenson
committed
break;
}
Karen Stevenson
committed
cache_clear_all('fieldgroup_data', content_cache_tablename());
Karen Stevenson
committed
}
Yves Chedemois
committed
function fieldgroup_group_edit_form(&$form_state, $type_name, $group_name) {
Yves Chedemois
committed
$content_type = content_types($type_name);
$groups = fieldgroup_groups($content_type['type']);
Yves Chedemois
committed
if (!$group = $groups[$group_name]) {
drupal_not_found();
exit;
}
$form['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
Yves Chedemois
committed
'#default_value' => $group['label'],
Karen Stevenson
committed
// Set a default value for group type early in the form so it
// can be overridden by subsequent form elements added by other modules.
$group_type = !empty($group['group_type']) ? $group['group_type'] : 'standard';
$form['group_type'] = array('#type' => 'hidden', '#default_value' => $group_type);
$form['settings']['#tree'] = TRUE;
$form['settings']['form'] = array(
'#type' => 'fieldset',
'#title' => t('Form settings'),
'#description' => t('These settings apply to the group in the node editing form.'),
$form['settings']['form']['style'] = array(
'#type' => 'radios',
'#title' => t('Style'),
Yves Chedemois
committed
'#default_value' => $group['settings']['form']['style'],
'#options' => array(
'fieldset' => t('always open'),
'fieldset_collapsible' => t('collapsible'),
'fieldset_collapsed' => t('collapsed'),
)
$form['settings']['form']['description'] = array(
'#type' => 'textarea',
'#title' => t('Help text'),
Yves Chedemois
committed
'#default_value' => $group['settings']['form']['description'],
'#rows' => 5,
'#description' => t('Instructions to present to the user on the editing form.'),
'#required' => FALSE,
);
$form['settings']['display'] = array(
'#type' => 'fieldset',
'#title' => t('Display settings'),
'#description' => t('These settings apply to the group on node display.'),
);
$form['settings']['display']['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
Yves Chedemois
committed
'#default_value' => $group['settings']['display']['description'],
'#rows' => 5,
'#description' => t('A description of the group.'),
'#required' => FALSE,
);
Karen Stevenson
committed
module_load_include('inc', 'content', 'includes/content.admin');
foreach (array_merge(array_keys(content_build_modes()), array('label')) as $key) {
Yves Chedemois
committed
$form['settings']['display'][$key] = array('#type' => 'value', '#value' => $group['settings']['display'][$key]);
Yves Chedemois
committed
$form['weight'] = array('#type' => 'hidden', '#default_value' => $group['weight']);
$form['group_name'] = array('#type' => 'hidden', '#default_value' => $group_name);
$form['#content_type'] = $content_type;
Yves Chedemois
committed
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#weight' => 10,
);
Karen Stevenson
committed
Yves Chedemois
committed
return $form;
Karen Stevenson
committed
}
function fieldgroup_group_edit_form_submit($form, &$form_state) {
$form_values = $form_state['values'];
$content_type = $form['#content_type'];
fieldgroup_save_group($content_type['type'], $form_values);
$form_state['redirect'] = 'admin/content/node-type/'. $content_type['url_str'] .'/fields';
Yves Chedemois
committed
function fieldgroup_remove_group(&$form_state, $type_name, $group_name) {
$content_type = content_types($type_name);
$groups = fieldgroup_groups($content_type['type']);
$group = isset($groups[$group_name]) ? $groups[$group_name] : '';
drupal_not_found();
exit;
}
$form['#submit'][] = 'fieldgroup_remove_group_submit';
$form['#content_type'] = $content_type;
$form['#group_name'] = $group_name;
return confirm_form($form,
t('Are you sure you want to remove the group %label?',
array('%label' => t($group['label']))),
'admin/content/node-type/'. $content_type['url_str'] .'/fields', t('This action cannot be undone.'),
t('Remove'), t('Cancel'));
}
function fieldgroup_remove_group_submit($form, &$form_state) {
$form_values = $form_state['values'];
$content_type = $form['#content_type'];
$group_name = $form['#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';
}
/*
* Returns all groups for a content type
*/
Karen Stevenson
committed
function fieldgroup_groups($content_type = '', $sorted = FALSE, $reset = FALSE) {
Wolfgang Ziegler
committed
static $groups, $groups_sorted;
if (!isset($groups) || $reset) {
Karen Stevenson
committed
if ($cached = cache_get('fieldgroup_data', content_cache_tablename())) {
Karen Stevenson
committed
$data = $cached->data;
Wolfgang Ziegler
committed
$groups = $data['groups'];
$groups_sorted = $data['groups_sorted'];
$result = db_query("SELECT * FROM {". fieldgroup_tablename() ."} ORDER BY weight, group_name");
Wolfgang Ziegler
committed
$groups = array();
$groups_sorted = array();
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 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 ".
Karen Stevenson
committed
"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;
}
Karen Stevenson
committed
cache_set('fieldgroup_data', array('groups' => $groups, 'groups_sorted' => $groups_sorted), content_cache_tablename());
Karen Stevenson
committed
if (empty($content_type)) {
return $groups;
}
elseif (empty($groups) || empty($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);
Yves Chedemois
committed
$labels[''] = '<'. t('none') .'>';
foreach ($groups as $group_name => $group) {
$labels[$group_name] = t($group['label']);
}
return $labels;
}
function _fieldgroup_field_get_group($content_type, $field_name) {
return db_result(db_query("SELECT group_name FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $content_type, $field_name));
Yves Chedemois
committed
/**
* Implementation of hook_form_alter()
*/
function fieldgroup_form_alter(&$form, $form_state, $form_id) {
Yves Chedemois
committed
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',
Yves Chedemois
committed
'#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')),
Yves Chedemois
committed
'#description' => content_filter_xss(t($group['settings']['form']['description'])),
'#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
Yves Chedemois
committed
Karen Stevenson
committed
$has_accessible_field = FALSE;
foreach ($group['fields'] as $field_name => $field) {
if (isset($form[$field_name])) {
$form[$group_name][$field_name] = $form[$field_name];
Karen Stevenson
committed
// Track whether this group has any accessible fields within it.
Yves Chedemois
committed
if (!isset($form[$field_name]['#access']) || $form[$field_name]['#access'] !== FALSE) {
Karen Stevenson
committed
$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]);
}
Yves Chedemois
committed
Karen Stevenson
committed
if (!$has_accessible_field) {
// Hide the fieldgroup, because the fields are inaccessible.
$form[$group_name]['#access'] = FALSE;
}
Karen Stevenson
committed
// 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);
}
Karen Stevenson
committed
// The group is only added here so it will appear in the export
elseif ($form_id == 'content_field_edit_form' && isset($form['widget'])) {
$content_type = content_types($form['type_name']['#value']);
$form['widget']['group'] = array(
'#type' => 'value',
'#value' => _fieldgroup_field_get_group($content_type['type'], $form['field_name']['#value']),
);
}
Yves Chedemois
committed
elseif ($form_id == 'content_field_overview_form') {
$form['#validate'][] = 'fieldgroup_field_overview_form_validate';
$form['#submit'][] = 'fieldgroup_field_overview_form_submit';
elseif ($form_id == 'content_display_overview_form' && !empty($form['#groups'])) {
$form['#submit'][] = 'fieldgroup_display_overview_form_submit';
if (!isset($form['submit'])) {
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 10);
elseif ($form_id == 'content_field_remove_form') {
$form['#submit'][] = 'fieldgroup_field_remove_form_submit';
Karen Stevenson
committed
/**
* API for group name validation.
*
* Pulled into separate function to be re-usable.
*/
function fieldgroup_validate_name($group) {
$errors = array();
// No label.
if (!$group['label']) {
$errors['label'][] = t('You need to provide a label.');
}
Yves Chedemois
committed
Karen Stevenson
committed
// No group name.
if (!$group['group_name']) {
$errors['group_name'][] = t('You need to provide a group name.');
}
// Group name validation.
else {
$group_name = $group['group_name'];
$group['group_type'] = !empty($group['group_type']) ? $group['group_type'] : 'standard';
// Add the 'group_' prefix.
if (substr($group_name, 0, 6) != 'group_') {
$group_name = 'group_'. $group_name;
Yves Chedemois
committed
}
Karen Stevenson
committed
// Invalid field name.
if (!preg_match('!^group_[a-z0-9_]+$!', $group_name)) {
$errors['group_name'][] = t('The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%group_name' => $group_name));
}
if (strlen($group_name) > 32) {
$errors['group_name'][] = t('The group name %group_name is too long. The name is limited to 32 characters, including the \'group_\' prefix.', array('%group_name' => $group_name));
Yves Chedemois
committed
}
Karen Stevenson
committed
// Group name already exists.
$used = FALSE;
$groups = fieldgroup_groups();
foreach ($groups as $type => $groups_per_type) {
foreach ($groups_per_type as $existing_group) {
$used |= ($existing_group['group_name'] == $group_name);
Yves Chedemois
committed
}
Karen Stevenson
committed
}
if ($used) {
$errors['group_name'][] = t('The group name %group_name already exists.', array('%group_name' => $group_name));
}
if (empty($errors['group_name'])) {
$group['group_name'] = $group_name;
}
}
return array('group_name' => $group['group_name'], 'errors' => $errors);
}
function fieldgroup_field_overview_form_validate($form, &$form_state) {
$form_values = $form_state['values'];
$group = $form_values['_add_new_group'];
Yves Chedemois
committed
Karen Stevenson
committed
if (array_filter(array($group['label'], $group['group_name']))) {
$validation = fieldgroup_validate_name($group);
if (!empty($validation['errors'])) {
foreach ($validation['errors'] as $type => $messages) {
foreach ($messages as $message) {
if ($type == 'label') {
form_set_error('_add_new_group][label', t('Add new group:') .' '. $message);
}
else {
form_set_error('_add_new_group][group_name', t('Add new group:') .' '. $message);
}
Yves Chedemois
committed
}
}
}
Karen Stevenson
committed
$group_name = $validation['group_name'];
form_set_value($form['_add_new_group']['group_name'], $group_name, $form_state);
Yves Chedemois
committed
}
else {
// Fail validation if attempt to nest fields under a new group without the
// proper information. Not raising an error would cause the nested fields
// to get weights the user doesn't expect.
Karen Stevenson
committed
Yves Chedemois
committed
foreach ($form_values as $key => $values) {
if ($values['parent'] == '_add_new_group') {
form_set_error('_add_new_group][label', t('Add new group: you need to provide a label.'));
form_set_error('_add_new_group][group_name', t('Add new group: you need to provide a group name.'));
break;
}
}
}
}
function fieldgroup_field_overview_form_submit($form, &$form_state) {
Karen Stevenson
committed
$form_values = $form_state['values'];
$type_name = $form['#type_name'];
Yves Chedemois
committed
// Create new group if needed.
if (!empty($form_values['_add_new_group']['label'])) {
$group = $form_values['_add_new_group'];
Karen Stevenson
committed
$group['settings'] = field_group_default_settings($group['group_type']);
Yves Chedemois
committed
fieldgroup_save_group($type_name, $group);
$new_group_name = $group['group_name'];
}
// Parse incoming rows.
$add_field_rows = array('_add_new_field', '_add_existing_field');
$field_rows = array_merge($form['#fields'], $add_field_rows);
foreach ($form_values as $key => $values) {
Yves Chedemois
committed
// If 'field' row: update field parenting.
if (in_array($key, $field_rows)) {
// If newly added fields were added to a group:
if (in_array($key, $add_field_rows)) {
// We replace the '_add_*_field' key with the actual name of
// the field that got added.
// content_field_overview_form_submit() placed those
// in $form_state['fields_added'] for us.
if (isset($form_state['fields_added'][$key])) {
$key = $form_state['fields_added'][$key];
}
else {
// No field was actually created : skip to next row.
continue;
}
}
// If the field was added to the newly created group, replace the
// '_add_new_group' value with the actual name of the group.
$parent = ($values['parent'] == '_add_new_group' && isset($new_group_name)) ? $new_group_name : $values['parent'];
// TODO: check the parent group does exist ?
Yves Chedemois
committed
fieldgroup_update_fields(array('field_name' => $key, 'group' => $parent, 'type_name' => $type_name));
Karen Stevenson
committed
}
Yves Chedemois
committed
// If 'group' row: update groups weights
// (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);
Karen Stevenson
committed
}
}
Karen Stevenson
committed
cache_clear_all('fieldgroup_data', content_cache_tablename());
Karen Stevenson
committed
}
Karen Stevenson
committed
function field_group_default_settings($group_type) {
Yves Chedemois
committed
$settings = array(
'form' => array('style' => 'fieldset', 'description' => ''),
'display' => array('description' => '', 'label' => 'above'),
);
module_load_include('inc', 'content', 'includes/content.admin');
foreach (array_keys(content_build_modes()) as $key) {
Yves Chedemois
committed
$settings['display'][$key]['format'] = 'fieldset';
}
Karen Stevenson
committed
// Allow other modules to add new default settings.
$settings = array_merge($settings, module_invoke_all('fieldgroup_default_settings', $group_type));
Yves Chedemois
committed
return $settings;
}
function fieldgroup_display_overview_form_submit($form, &$form_state) {
$form_values = $form_state['values'];
$groups = fieldgroup_groups($form['#type_name']);
foreach ($form_values as $key => $values) {
if (in_array($key, $form['#groups'])) {
$group = $groups[$key];
Yves Chedemois
committed
// We have some numeric keys here, so we can't use array_merge.
$group['settings']['display'] = $values + $group['settings']['display'];
fieldgroup_save_group($form['#type_name'], $group);
}
}
}
function fieldgroup_field_remove_form_submit($form, &$form_state) {
$form_values = $form_state['values'];
// TODO:
// - when a (non last) field is removed from a group, a 'ghost row' remains in the fields overview
// - when the last field is removed, the group disappears
// seems to be fixed when emptying the cache.
db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']);
/**
* Implementation of hook_nodeapi().
*/
function fieldgroup_nodeapi(&$node, $op, $teaser, $page) {
switch ($op) {
case 'view':
Karen Stevenson
committed
// NODE_BUILD_NORMAL is 0, and ('whatever' == 0) is TRUE, so we need a ===.
if ($node->build_mode === NODE_BUILD_NORMAL || $node->build_mode == NODE_BUILD_PREVIEW) {
$context = $teaser ? 'teaser' : 'full';
}
else {
$context = $node->build_mode;
}
foreach (fieldgroup_groups($node->type) as $group_name => $group) {
Yves Chedemois
committed
// Do not include group labels when indexing content.
if ($context == NODE_BUILD_SEARCH_INDEX) {
$group['settings']['display']['label'] = 'hidden';
}
$label = $group['settings']['display']['label'] == 'above';
$element = array(
Yves Chedemois
committed
'#title' => $label ? check_plain(t($group['label'])) : '',
'#description' => $label ? content_filter_xss(t($group['settings']['display']['description'])) : '',
Yves Chedemois
committed
$format = isset($group['settings']['display'][$context]['format']) ? $group['settings']['display'][$context]['format'] : 'fieldset';
Karen Stevenson
committed
Yves Chedemois
committed
switch ($format) {
case 'simple':
$element['#type'] = 'fieldgroup_simple';
$element['#group_name'] = $group_name;
break;
case 'hidden':
$element['#access'] = FALSE;
break;
case 'fieldset_collapsed':
$element['#collapsed'] = TRUE;
case 'fieldset_collapsible':
$element['#collapsible'] = TRUE;
case 'fieldset':
$element['#type'] = 'fieldgroup_fieldset';
$element['#attributes'] = array('class' => 'fieldgroup '. strtr($group['group_name'], '_', '-'));
break;
}
foreach ($group['fields'] as $field_name => $field) {
if (isset($node->content[$field_name])) {
Yves Chedemois
committed
$element[$field_name] = $node->content[$field_name];
Karen Stevenson
committed
}
}
// Allow other modules to alter the group view.
// Can't use module_invoke_all because we want
// to be able to use a reference to $node and $element.
foreach (module_implements('fieldgroup_view') as $module) {
$function = $module .'_fieldgroup_view';
$function($node, $element, $group, $context);
}
foreach ($group['fields'] as $field_name => $field) {
if (isset($node->content[$field_name])) {
unset($node->content[$field_name]);
}
}
Yves Chedemois
committed
Yves Chedemois
committed
// The wrapper lets us get the themed output for the whole group
// once the $node->content has been rendered.
// See fieldgroup_preprocess_node().
$wrapper = array(
'group' => $element,
Yves Chedemois
committed
'#weight' => $group['weight'],
Yves Chedemois
committed
);
$node->content[$group_name] = $wrapper;
Yves Chedemois
committed
}
break;
* 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;
}
/**
* Implementation of hook_node_type()
* React to change in node types
*/
function fieldgroup_node_type($op, $info) {
Karen Stevenson
committed
if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) {
db_query("UPDATE {". fieldgroup_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
Karen Stevenson
committed
cache_clear_all('fieldgroup_data', content_cache_tablename());
db_query("DELETE FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s'", $info->type);
db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s'", $info->type);
Karen Stevenson
committed
function fieldgroup_types() {
$types = array('standard' => t('Standard'));
// Allow other modules to add new group_types.
$types = array_merge($types, module_invoke_all('fieldgroup_types'));
return $types;
}
function fieldgroup_tablename($version = NULL) {
if (is_null($version)) {
$version = variable_get('fieldgroup_schema_version', 0);
}
return $version < 6000 ? 'node_group' : 'content_group';
}
function fieldgroup_fields_tablename($version = NULL) {
if (is_null($version)) {
$version = variable_get('fieldgroup_schema_version', 0);
}
return $version < 6000 ? 'node_group_fields' : 'content_group_fields';
Karen Stevenson
committed
}
/**
* CRUD API for fieldgroup module.
*
* @todo
* Make this into more of a real API for groups.
Karen Stevenson
committed
*/
/*
* Saves the given group for this content-type
*/
function fieldgroup_save_group($type_name, $group) {
$groups = fieldgroup_groups($type_name);
Karen Stevenson
committed
// Allow other modules to intervene when the group is saved.
foreach (module_implements('fieldgroup_save_group') as $module) {
$function = $module .'_fieldgroup_save_group';
$function($group);
}
Karen Stevenson
committed
if (!isset($groups[$group['group_name']])) {
// Accept group name from programmed submissions if valid.
Karen Stevenson
committed
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']);
Karen Stevenson
committed
cache_clear_all('fieldgroup_data', content_cache_tablename());
Karen Stevenson
committed
return SAVED_NEW;
Karen Stevenson
committed
}
else {
db_query("UPDATE {". fieldgroup_tablename() ."} SET group_type = '%s', label = '%s', settings = '%s', weight = %d ".
Karen Stevenson
committed
"WHERE type_name = '%s' AND group_name = '%s'",
$group['group_type'], $group['label'], serialize($group['settings']), $group['weight'], $type_name, $group['group_name']);
Karen Stevenson
committed
cache_clear_all('fieldgroup_data', content_cache_tablename());
Karen Stevenson
committed
return SAVED_UPDATED;
Karen Stevenson
committed
}
}
function fieldgroup_update_fields($form_values) {
$default = _fieldgroup_field_get_group($form_values['type_name'], $form_values['field_name']);
if ($default != $form_values['group']) {
if ($form_values['group'] && !$default) {
Karen Stevenson
committed
db_query("INSERT INTO {". fieldgroup_fields_tablename() ."} (type_name, group_name, field_name) VALUES ('%s', '%s', '%s')", $form_values['type_name'], $form_values['group'], $form_values['field_name']);
Karen Stevenson
committed
}
elseif ($form_values['group']) {
Karen Stevenson
committed
db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET group_name = '%s' WHERE type_name = '%s' AND field_name = '%s'", $form_values['group'], $form_values['type_name'], $form_values['field_name']);
Karen Stevenson
committed
}
else {
db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']);
Karen Stevenson
committed
}
cache_clear_all('fieldgroup_data', content_cache_tablename());
}
}
function fieldgroup_delete($content_type, $group_name) {
db_query("DELETE FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name);
db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name);
Karen Stevenson
committed
cache_clear_all('fieldgroup_data', content_cache_tablename());
}
/**
* Format a fieldgroup using a 'fieldset'.
*
* Derived from core's theme_fieldset, with no output if the content is empty.
*/
function theme_fieldgroup_fieldset($element) {
if (empty($element['#children']) && empty($element['#value'])) {
return '';
}
if ($element['#collapsible']) {
drupal_add_js('misc/collapse.js');
if (!isset($element['#attributes']['class'])) {
$element['#attributes']['class'] = '';
}
$element['#attributes']['class'] .= ' collapsible';
if ($element['#collapsed']) {
$element['#attributes']['class'] .= ' collapsed';
}
}
return '<fieldset'. drupal_attributes($element['#attributes']) .'>'. ($element['#title'] ? '<legend>'. $element['#title'] .'</legend>' : '') . (isset($element['#description']) && $element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : '') . (!empty($element['#children']) ? $element['#children'] : '') . (isset($element['#value']) ? $element['#value'] : '') ."</fieldset>\n";
}
Yves Chedemois
committed
Karen Stevenson
committed
Yves Chedemois
committed
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
/**
* Process variables for fieldgroup.tpl.php.
*
* The $variables array contains the following arguments:
* - $group_name
* - $group_name_css
* - $label
* - $description
* - $content
*
* @see fieldgroup.tpl.php
*/
function fieldgroup_preprocess_fieldgroup_simple(&$vars) {
$element = $vars['element'];
$vars['group_name'] = $element['#group_name'];
$vars['group_name_css'] = strtr($element['#group_name'], '_', '-');
$vars['label'] = isset($element['#title']) ? $element['#title'] : '';;
$vars['description'] = isset($element['#description']) ? $element['#description'] : '';;
$vars['content'] = isset($element['#children']) ? $element['#children'] : '';
}
/**
* Theme preprocess function for node.
*
* Adds $GROUP_NAME_rendered variables,
* containing the themed output for the whole group.
*/
function fieldgroup_preprocess_node(&$vars) {
$node = $vars['node'];
foreach (fieldgroup_groups($node->type) as $group_name => $group) {
// '#chilren' might not be set if the group is empty.
$vars[$group_name .'_rendered'] = isset($node->content[$group_name]['#children']) ? $node->content[$group_name]['#children'] : '';
}