summaryrefslogtreecommitdiff
path: root/modules/field_ui/field_ui.admin.inc
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2010-06-26 02:06:53 +0000
committerDries Buytaert <dries@buytaert.net>2010-06-26 02:06:53 +0000
commitf0a49e662de237c4096d6384a07e3ccc2b43999c (patch)
tree845a318cd92ad9f0cc38e034fba1679064b0a0d8 /modules/field_ui/field_ui.admin.inc
parent4114d3ce58d61240faf0b667858bd127436a7a4d (diff)
downloadbrdo-f0a49e662de237c4096d6384a07e3ccc2b43999c.tar.gz
brdo-f0a49e662de237c4096d6384a07e3ccc2b43999c.tar.bz2
- Patch #616240 by yched, marcingy: make field UI screens extensible from contrib.
Diffstat (limited to 'modules/field_ui/field_ui.admin.inc')
-rw-r--r--modules/field_ui/field_ui.admin.inc373
1 files changed, 251 insertions, 122 deletions
diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc
index 064770b9b..94fe876c5 100644
--- a/modules/field_ui/field_ui.admin.inc
+++ b/modules/field_ui/field_ui.admin.inc
@@ -63,6 +63,105 @@ function field_ui_inactive_message($entity_type, $bundle) {
}
/**
+ * Helper function: determines the rendering order of a tree array.
+ *
+ * This is intended as a callback for array_reduce().
+ */
+function _field_ui_reduce_order($array, $a) {
+ $array = is_null($array) ? array() : $array;
+ if ($a['name']) {
+ $array[] = $a['name'];
+ }
+ if (!empty($a['children'])) {
+ uasort($a['children'], 'drupal_sort_weight');
+ $array = array_merge($array, array_reduce($a['children'], '_field_ui_reduce_order'));
+ }
+ return $array;
+}
+
+/**
+ * Theme preprocess function for theme_field_ui_table().
+ *
+ * @see theme_field_ui_table()
+ */
+function template_preprocess_field_ui_table(&$variables) {
+ $elements = &$variables['elements'];
+
+ // Build the tree structure from the weight and parenting data contained in
+ // the flat form structure, to determine row order and indentation.
+ $tree = array('' => array('name' => '', 'children' => array()));
+ $parents = array();
+ $list = drupal_map_assoc(element_children($elements));
+ // Iterate on rows until we can build a known tree path for all of them.
+ while ($list) {
+ foreach ($list as $name) {
+ $row = &$elements[$name];
+ $parent = $row['parent_wrapper']['parent']['#value'];
+ // Proceed if parent is known.
+ if (empty($parent) || isset($parents[$parent])) {
+ // Remove from the next iteration.
+ $parents[$name] = $parent ? array_merge($parents[$parent], array($parent)) : array();
+ unset($list[$name]);
+
+ // Add the element in the tree.
+ $target = &$tree[''];
+ foreach ($parents[$name] as $key) {
+ $target = &$target['children'][$key];
+ }
+ $target['children'][$name] = array('name' => $name, 'weight' => $row['weight']['#value']);
+
+ // Add tabledrag indentation to the first row cell.
+ if ($depth = count($parents[$name])) {
+ $cell = current(element_children($row));
+ $row[$cell]['#prefix'] = theme('indentation', array('size' => $depth)) . (isset($row[$cell]['#prefix']) ? $row[$cell]['#prefix'] : '');
+ }
+ }
+ }
+ }
+
+ // Determine rendering order for the tree.
+ $variables['row_order'] = array_reduce($tree, '_field_ui_reduce_order');
+}
+
+/**
+ * Returns HTML for Field UI overview tables.
+ *
+ * @param $variables
+ * An associative array containing:
+ * - elements: An associative array containing a Form API structure to be
+ * rendered as a table.
+ *
+ * @ingroup themeable
+ */
+function theme_field_ui_table($variables) {
+ $elements = $variables['elements'];
+ $table = array();
+
+ foreach (array('header', 'attributes') as $key) {
+ if (isset($elements["#$key"])) {
+ $table[$key] = $elements["#$key"];
+ }
+ }
+
+ foreach ($variables['row_order'] as $key) {
+ $element = $elements[$key];
+ $row = array('data' => array());
+ $row += $element['#attributes'];
+
+ foreach (element_children($element) as $cell_key) {
+ $cell = array('data' => drupal_render($element[$cell_key]));
+ if (isset($element[$cell_key]['#cell_attributes'])) {
+ $cell += $element[$cell_key]['#cell_attributes'];
+ }
+ $row['data'][] = $cell;
+ }
+ $table['rows'][] = $row;
+ }
+
+ return theme('table', $table);
+}
+
+/**
* Menu callback; listing of fields for a bundle.
*
* Allows fields and pseudo-fields to be re-ordered.
@@ -89,23 +188,60 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
$weights = array();
$form += array(
- '#tree' => TRUE,
'#entity_type' => $entity_type,
'#bundle' => $bundle,
'#fields' => array_keys($instances),
'#extra' => array_keys($extra_fields),
- '#field_rows' => array(),
);
+ $table = array(
+ '#type' => 'table',
+ '#tree' => TRUE,
+ '#header' => array(
+ t('Label'),
+ t('Weight'),
+ t('Parent'),
+ t('Name'),
+ t('Field'),
+ t('Widget'),
+ array('data' => t('Operations'), 'colspan' => 2),
+ ),
+ '#attributes' => array('id' => 'field-overview'),
+ );
+
+ $parent_options = array('' => t('<none>'));
+
// Fields.
foreach ($instances as $name => $instance) {
$field = field_info_field($instance['field_name']);
$admin_field_path = $admin_path . '/fields/' . $instance['field_name'];
$weight = $instance['widget']['weight'];
- $form[$name] = array(
+ $weights[] = $weight;
+ $table[$name] = array(
+ '#parents' => array($name),
+ '#attributes' => array('class' => array('draggable tabledrag-leaf')),
'label' => array(
'#markup' => check_plain($instance['label']),
),
+ 'weight' => array(
+ '#type' => 'textfield',
+ '#default_value' => $weight,
+ '#size' => 3,
+ '#attributes' => array('class' => array('field-weight')),
+ ),
+ 'parent_wrapper' => array(
+ 'parent' => array(
+ '#type' => 'select',
+ '#options' => $parent_options,
+ '#attributes' => array('class' => array('field-parent')),
+ '#parents' => array($name, 'parent'),
+ ),
+ 'hidden_name' => array(
+ '#type' => 'hidden',
+ '#default_value' => $name,
+ '#attributes' => array('class' => array('field-name')),
+ ),
+ ),
'field_name' => array(
'#markup' => $instance['field_name'],
),
@@ -133,64 +269,60 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
'#href' => $admin_field_path . '/delete',
'#options' => array('attributes' => array('title' => t('Delete instance.'))),
),
- 'weight' => array(
- '#type' => 'textfield',
- '#default_value' => $weight,
- '#size' => 3,
- '#title_display' => 'invisible',
- '#title' => t('Weight for @row', array('@row' => $instance['label'])),
- ),
- 'hidden_name' => array(
- '#type' => 'hidden',
- '#default_value' => $instance['field_name'],
- ),
- '#row_type' => 'field',
);
if (!empty($instance['locked'])) {
- $form[$name]['edit'] = array('#value' => t('Locked'));
- $form[$name]['delete'] = array();
- $form[$name]['#disabled_row'] = TRUE;
+ $table[$name]['edit'] = array('#value' => t('Locked'));
+ $table[$name]['delete'] = array();
+ $table[$name]['#attributes']['class'][] = 'menu-disabled';
}
- $form['#field_rows'][] = $name;
- $weights[] = $weight;
}
// Non-field elements.
foreach ($extra_fields as $name => $extra_field) {
$weight = $extra_field['weight'];
- $form[$name] = array(
+ $weights[] = $weight;
+ $table[$name] = array(
+ '#parents' => array($name),
+ '#attributes' => array('class' => array('draggable', 'tabledrag-leaf', 'menu-disabled')),
'label' => array(
'#markup' => check_plain($extra_field['label']),
),
- 'name' => array(
- '#markup' => $name,
- ),
- 'description' => array(
- '#markup' => isset($extra_field['description']) ? $extra_field['description'] : '',
- ),
'weight' => array(
'#type' => 'textfield',
'#default_value' => $weight,
'#size' => 3,
+ '#attributes' => array('class' => array('field-weight')),
'#title_display' => 'invisible',
'#title' => t('Weight for @row', array('@row' => $extra_field['label'])),
),
+ 'parent_wrapper' => array(
+ 'parent' => array(
+ '#type' => 'select',
+ '#options' => $parent_options,
+ '#attributes' => array('class' => array('field-parent')),
+ '#parents' => array($name, 'parent'),
+ ),
+ 'hidden_name' => array(
+ '#type' => 'hidden',
+ '#default_value' => $name,
+ '#attributes' => array('class' => array('field-name')),
+ ),
+ ),
+ 'field_name' => array(
+ '#markup' => $name,
+ ),
+ 'type' => array(
+ '#markup' => isset($extra_field['description']) ? $extra_field['description'] : '',
+ '#cell_attributes' => array('colspan' => 2),
+ ),
'edit' => array(
'#markup' => isset($extra_field['edit']) ? $extra_field['edit'] : '',
),
'delete' => array(
'#markup' => isset($extra_field['delete']) ? $extra_field['delete'] : '',
),
- 'hidden_name' => array(
- '#type' => 'hidden',
- '#default_value' => $name,
- ),
- '#disabled_row' => TRUE,
- '#row_type' => 'extra',
);
- $form['#field_rows'][] = $name;
- $weights[] = $weight;
}
// Additional row: add new field.
@@ -201,11 +333,38 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
array_unshift($field_type_options, t('- Select a field type -'));
array_unshift($widget_type_options, t('- Select a widget -'));
$name = '_add_new_field';
- $form[$name] = array(
+ $table[$name] = array(
+ '#parents' => array($name),
+ '#attributes' => array('class' => array('draggable', 'tabledrag-leaf', 'add-new')),
'label' => array(
'#type' => 'textfield',
'#size' => 15,
'#description' => t('Label'),
+ '#prefix' => '<div class="label-input"><div class="add-new-placeholder">' . t('Add new field') .'</div>',
+ '#suffix' => '</div>',
+ ),
+ 'weight' => array(
+ '#type' => 'textfield',
+ '#default_value' => $weight,
+ '#size' => 3,
+ '#title_display' => 'invisible',
+ '#title' => t('Weight for new field'),
+ '#attributes' => array('class' => array('field-weight')),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
+ ),
+ 'parent_wrapper' => array(
+ 'parent' => array(
+ '#type' => 'select',
+ '#options' => $parent_options,
+ '#attributes' => array('class' => array('field-parent')),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
+ '#parents' => array($name, 'parent'),
+ ),
+ 'hidden_name' => array(
+ '#type' => 'hidden',
+ '#default_value' => $name,
+ '#attributes' => array('class' => array('field-name')),
+ ),
),
'field_name' => array(
'#type' => 'textfield',
@@ -215,32 +374,24 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
'#attributes' => array('dir'=>'ltr'),
'#size' => 15,
'#description' => t('Field name (a-z, 0-9, _)'),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
),
'type' => array(
'#type' => 'select',
'#options' => $field_type_options,
'#description' => t('Type of data to store.'),
+ '#attributes' => array('class' => array('field-type-select')),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
),
'widget_type' => array(
'#type' => 'select',
'#options' => $widget_type_options,
'#description' => t('Form element to edit the data.'),
+ '#attributes' => array('class' => array('widget-type-select')),
+ '#cell_attributes' => array('colspan' => 3),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
),
- 'weight' => array(
- '#type' => 'textfield',
- '#default_value' => $weight,
- '#size' => 3,
- '#title_display' => 'invisible',
- '#title' => t('Weight for new field'),
- ),
- 'hidden_name' => array(
- '#type' => 'hidden',
- '#default_value' => $name,
- ),
- '#add_new' => TRUE,
- '#row_type' => 'add_new_field',
);
- $form['#field_rows'][] = $name;
}
// Additional row: add existing field.
@@ -249,108 +400,85 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle
$weight++;
array_unshift($existing_field_options, t('- Select an existing field -'));
$name = '_add_existing_field';
- $form[$name] = array(
+ $table[$name] = array(
+ '#parents' => array($name),
+ '#attributes' => array('class' => array('draggable', 'tabledrag-leaf', 'menu-disabled')),
'label' => array(
'#type' => 'textfield',
'#size' => 15,
'#description' => t('Label'),
+ '#attributes' => array('class' => array('label-textfield')),
+ '#prefix' => '<div class="label-input"><div class="add-new-placeholder">' . t('Add existing field') .'</div>',
+ '#suffix' => '</div>',
+ ),
+ 'weight' => array(
+ '#type' => 'textfield',
+ '#default_value' => $weight,
+ '#size' => 3,
+ '#title_display' => 'invisible',
+ '#title' => t('Weight for added field'),
+ '#attributes' => array('class' => array('field-weight')),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
+ ),
+ 'parent_wrapper' => array(
+ 'parent' => array(
+ '#type' => 'select',
+ '#options' => $parent_options,
+ '#attributes' => array('class' => array('field-parent')),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
+ '#parents' => array($name, 'parent'),
+ ),
+ 'hidden_name' => array(
+ '#type' => 'hidden',
+ '#default_value' => $name,
+ '#attributes' => array('class' => array('field-name')),
+ ),
),
'field_name' => array(
'#type' => 'select',
'#options' => $existing_field_options,
'#description' => t('Field to share'),
+ '#attributes' => array('class' => array('field-select')),
+ '#cell_attributes' => array('colspan' => 2),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
),
'widget_type' => array(
'#type' => 'select',
'#options' => $widget_type_options,
'#description' => t('Form element to edit the data.'),
+ '#attributes' => array('class' => array('widget-type-select')),
+ '#cell_attributes' => array('colspan' => 3),
+ '#prefix' => '<div class="add-new-placeholder">&nbsp;</div>',
),
- 'weight' => array(
- '#type' => 'textfield',
- '#default_value' => $weight,
- '#size' => 3,
- '#title_display' => 'invisible',
- '#title' => t('Weight for added field'),
- ),
- 'hidden_name' => array(
- '#type' => 'hidden',
- '#default_value' => $name,
- ),
- '#add_new' => TRUE,
- '#row_type' => 'add_existing_field',
);
- $form['#field_rows'][] = $name;
}
+ $form['table'] = $table;
+
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save'));
- return $form;
-}
-
-/**
- * Theme preprocess function for field_ui-field-overview-form.tpl.php.
- */
-function template_preprocess_field_ui_field_overview_form(&$vars) {
- $form = &$vars['form'];
- drupal_add_css(drupal_get_path('module', 'field_ui') . '/field_ui.css');
- drupal_add_tabledrag('field-overview', 'order', 'sibling', 'field-weight');
- drupal_add_js(drupal_get_path('module', 'field_ui') . '/field_ui.js');
+ $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.css';
+ $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js';
// Add settings for the update selects behavior.
$js_fields = array();
- foreach (field_ui_existing_field_options($form['#entity_type'], $form['#bundle']) as $field_name => $fields) {
+ foreach ($existing_field_options as $field_name => $fields) {
$field = field_info_field($field_name);
$instance = field_info_instance($form['#entity_type'], $field_name, $form['#bundle']);
$js_fields[$field_name] = array('label' => $instance['label'], 'type' => $field['type'], 'widget' => $instance['widget']['type']);
}
- drupal_add_js(array('fieldWidgetTypes' => field_ui_widget_type_options(), 'fields' => $js_fields), 'setting');
- $order = _field_ui_overview_order($form, $form['#field_rows']);
- $rows = array();
+ $form['#attached']['js'][] = array(
+ 'type' => 'setting',
+ 'data' => array('fields' => $js_fields, 'fieldWidgetTypes' => field_ui_widget_type_options(),
+ ),
+ );
- // Identify the 'new item' keys in the form.
- $keys = array_keys($form);
- $add_rows = array();
- foreach ($keys as $key) {
- if (substr($key, 0, 4) == '_add') {
- $add_rows[] = $key;
- }
- }
- while ($order) {
- $key = reset($order);
- $element = &$form[$key];
- $row = new stdClass();
-
- // Add target classes for the tabledrag behavior.
- $element['weight']['#attributes']['class'][] = 'field-weight';
- $element['hidden_name']['#attributes']['class'][] = 'field-name';
- // Add target classes for the update selects behavior.
- switch ($element['#row_type']) {
- case 'add_new_field':
- $element['type']['#attributes']['class'][] = 'field-type-select';
- $element['widget_type']['#attributes']['class'][] = 'widget-type-select';
- break;
-
- case 'add_existing_field':
- $element['field_name']['#attributes']['class'][] = 'field-select';
- $element['widget_type']['#attributes']['class'][] = 'widget-type-select';
- $element['label']['#attributes']['class'][] = 'label-textfield';
- break;
- }
- foreach (element_children($element) as $child) {
- $row->{$child} = drupal_render($element[$child]);
- }
- $row->label_class = 'label-' . strtr($element['#row_type'], '_', '-');
- $row->row_type = $element['#row_type'];
- $row->class = 'draggable';
- $row->class .= isset($element['#add_new']) ? ' add-new' : '';
- $row->class .= isset($element['#disabled_row']) ? ' menu-disabled' : '';
+ // Add tabledrag behavior.
+ $form['#attached']['drupal_add_tabledrag'][] = array('field-overview', 'order', 'sibling', 'field-weight');
+ $form['#attached']['drupal_add_tabledrag'][] = array('field-overview', 'match', 'parent', 'field-parent', 'field-parent', 'field-name');
- $rows[] = $row;
- array_shift($order);
- }
- $vars['rows'] = $rows;
- $vars['submit'] = drupal_render_children($form);
+ return $form;
}
/**
@@ -1420,6 +1548,7 @@ function field_ui_next_destination($entity_type, $bundle) {
/**
* Helper function to order fields when theming overview forms.
+ * @todo Remove when 'Manage display' screen is done.
*/
function _field_ui_overview_order(&$form, $field_rows) {
// Put weight and parenting values into a $dummy render structure and let