Implemented schema altering, needs more testing.
[project/data.git] / data_ui / data_ui.admin.inc
CommitLineData
2ace3f91
AB
1<?php
2// $Id$
3a16de16
AB
3/**
4 * @file
5 * Admin UI functions.
6 */
2ace3f91
AB
7
8/**
9 * Overview over all tables.
10 */
11function data_ui_overview() {
2ace3f91
AB
12 $tables = data_get_all_tables();
13 $rows = array();
14 foreach ($tables as $table) {
72ba49d9
AB
15 // Build operations depending on configuration status.
16 $operations = array();
17 if ($table->get('export_type') == EXPORT_IN_CODE) {
18 $status = t('Default');
19 $operations[] = l(t('Override'), 'admin/content/data/edit/'. $table->get('name'));
20 }
21 else if ($table->get('export_type') == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) {
22 $status = t('Overridden');
23 $operations[] = l(t('Edit'), 'admin/content/data/edit/'. $table->get('name'));
24 $operations[] = l(t('Revert'), 'admin/content/data/revert/'. $table->get('name'));
25 }
26 else {
27 $status = t('Normal');
28 $operations[] = l(t('Edit'), 'admin/content/data/edit/'. $table->get('name'));
70a595f9 29 $operations[] = l(t('Drop'), 'admin/content/data/drop/'. $table->get('name'));
72ba49d9
AB
30 }
31 if (module_exists('ctools')) {
32 $operations[] = l(t('Export'), 'admin/content/data/export/'. $table->get('name'));
33 }
34
35 $row = array();
36 $row[] = $table->get('name');
37 $row[] = $status;
38 $row[] = implode(' | ', $operations);
39
40 $rows[] = $row;
2ace3f91 41 }
03608987 42 $rows[] = array(
f48c6947 43 l(t('Create new table'), 'admin/content/data/create'),
03608987 44 '&nbsp;',
12aae5b6 45 '&nbsp;',
03608987 46 );
72ba49d9 47 $header = array(t('Name'), t('Status'), t('Operations'));
2ace3f91
AB
48 return theme('table', $header, $rows);
49}
50
51/**
d4c26f4b
AB
52 * Comparison page.
53 */
54function data_ui_compare() {
55 $rows = array();
56 $tables = data_get_all_tables();
57 foreach ($tables as $table) {
58 $row = array();
59 $comp = $table->compareSchema();
60 $row[] = $table->get('name');
2c44bed5
AB
61 $status = $comp['status'];
62 if ($status != 'same') {
63 $status .= ' - '. l(t('adjust'), 'admin/content/data/compare/'. $table->get('name'));
d4c26f4b 64 }
2c44bed5
AB
65 $row[] = $status;
66 $row[] = empty($comp['warning']) ? '-' : $comp['warning'];
d4c26f4b
AB
67 $rows[] = $row;
68 }
2c44bed5 69 $header = array(t('Name'), t('Status'), t('Warnings'));
d4c26f4b
AB
70 return theme('table', $header, $rows);
71}
72
73/**
2c44bed5
AB
74 * Adjust table schema form: Present the user with the difference between schema information and
75 * the actual schema in the Database and offer three options:
76 *
77 * - Adjust schema info,
78 * - adjust database or
79 * - leave it.
80 */
81function data_ui_adjust_form(&$form_state, $table) {
82 drupal_set_title(t('Adjust !table', array('!table' => $table->get('name'))));
83 $comparison = $table->compareSchema();
84
85 $form = array();
86 $form['#redirect'] = 'admin/content/data/compare';
87 $form['#table'] = $table;
12aae5b6 88 $form['#comparison'] = $comparison;
2c44bed5
AB
89 $form['comparison'] = array(
90 '#type' => 'fieldset',
91 '#title' => t('Comparison'),
92 );
93 $form['comparison']['comparison']['#value'] = theme('data_ui_schema_compare_table', $comparison);
94
95 if ($comparison['status'] == 'different') {
96 $form['update_schema'] = array(
97 '#type' => 'fieldset',
98 '#title' => t('Option 1: Update schema information'),
99 );
100 $form['update_schema']['description'] = array(
101 '#value' => t('<p>This option will update the schema information about this table.</p>'),
102 );
103 $form['update_schema']['submit'] = array(
104 '#type' => 'submit',
105 '#submit' => array('data_ui_adjust_form_submit_update_schema'),
106 '#value' => t('Update schema information'),
107 );
108 $form['alter_table'] = array(
109 '#type' => 'fieldset',
110 '#title' => t('Option 2: Alter table'),
111 );
112 $form['alter_table']['description'] = array(
113 '#value' => t('<p>Review the changes above carefully!
114 This option will alter the database table and can very
115 easily cause data loss.</p>'),
116 );
117 $form['alter_table']['submit'] = array(
118 '#type' => 'submit',
119 '#submit' => array('data_ui_adjust_form_submit_alter_table'),
120 '#value' => t('Alter table'),
121 );
122 }
123 elseif ($comparison['status'] == 'missing') {
124 $form['alter_table'] = array(
125 '#type' => 'fieldset',
126 '#title' => t('Create table'),
127 );
128 $form['alter_table']['description'] = array(
129 '#value' => t('<p>Create a new table from schema information.</p>'),
130 );
131 $form['alter_table']['submit'] = array(
132 '#type' => 'submit',
133 '#submit' => array('data_ui_adjust_form_submit_create_table'),
134 '#value' => t('Create table'),
135 );
136 }
137 $form['cancel'] = array(
138 '#type' => 'fieldset',
139 '#title' => t('Don\'t change anything'),
140 );
141 $form['cancel']['cancel'] = array(
142 '#type' => 'submit',
143 '#value' => t('Cancel'),
144 );
145 return $form;
146}
147
148/**
149 * Submit handler for data_ui_adjust_form().
150 */
151function data_ui_adjust_form_submit_update_schema($form, &$form_state) {
152 $table = $form['#table'];
153 $schema = schema_invoke('inspect');
154 if (isset($schema[$table->get('name')])) {
155 $table->update(array('table_schema' => $schema[$table->get('name')]));
156 drupal_set_message(t('Updated schema for !table', array('!table' => $table->get('name'))));
157 }
158 else {
159 drupal_set_message(t('Error updating schema'), 'error');
160 }
161}
162
163/**
164 * Submit handler for data_ui_adjust_form().
165 */
166function data_ui_adjust_form_submit_alter_table($form, &$form_state) {
12aae5b6
AB
167 $resolved = $resolved = array();
168 if (isset($form['#comparison']['reasons'])) {
169 foreach ($form['#comparison']['reasons'] as $field_reason) {
170 list($field, $reason) = explode(': ', $field_reason);
171 if (data_alter_table($form['#table'], $field, $reason)) {
172 $resolved[] = $field_reason;
173 }
174 else {
175 $unresolved[] = $field_reason;
176 }
177 }
178 }
179 if (count($resolved)) {
180 drupal_set_message(t('Resolved') . theme_item_list($resolved));
181 }
182 if (count($unresolved)) {
183 drupal_set_message(t('Could not resolve') . theme_item_list($unresolved), 'error');
184 }
2c44bed5
AB
185}
186
187/**
188 * Submit handler for data_ui_adjust_form().
189 */
190function data_ui_adjust_form_submit_create_table($form, &$form_state) {
191 $table = $form['#table'];
192 $ret = array();
193 db_create_table($ret, $table->get('name'), $table->get('table_schema'));
194 if ($ret[0]['success']) {
195 drupal_set_message(t('Created table !table', array('!table' => $table->get('name'))));
196 }
197 else {
198 drupal_set_message(t('Error creating table'), 'error');
199 }
200}
201
202/**
e6f88837 203 * Form callback for create table form.
03608987 204 */
dcdaddd1 205function data_ui_create_form(&$form_state) {
03608987 206 $form = array();
120dbbcb 207 if (!$form_state['storage']['field_num']) {
f48c6947
AB
208 $form['name'] = array(
209 '#type' => 'textfield',
210 '#title' => t('Table name'),
211 '#description' => t('Machine readable name of the table - e. g. "my_table". Must only contain lower case letters and _.'),
212 '#required' => TRUE,
213 );
214 $form['title'] = array(
215 '#type' => 'textfield',
216 '#title' => t('Table title'),
217 '#description' => t('Natural name of the table - e. g. "My Table".'),
218 );
219 $form['field_num'] = array(
220 '#type' => 'textfield',
221 '#title' => t('Number of fields'),
222 '#description' => t('The number of fields this table should contain.'),
223 '#default_value' => 1,
224 '#required' => TRUE,
225 );
226 $form['submit'] = array(
227 '#type' => 'submit',
228 '#value' => t('Next'),
229 );
230 }
120dbbcb
AB
231 else {
232 $form['help']['#value'] = t('Define the fields of the new table.');
233 $form['fields'] = array(
234 '#tree' => TRUE,
235 );
236 for ($i = 0; $i < $form_state['storage']['field_num']; $i++) {
237 $form['fields']['field_'. $i] = _data_ui_field_form(TRUE);
238 }
239 $form['submit'] = array(
240 '#type' => 'submit',
241 '#value' => t('Create'),
242 );
243 }
03608987
AB
244 return $form;
245}
246
247/**
e6f88837 248 * Validate handler for create table form.
03608987 249 */
dcdaddd1 250function data_ui_create_form_validate($form, &$form_state) {
03608987
AB
251 if (data_get_table(data_name($form_state['values']['name']))) {
252 form_set_error('name', t('Name is already taken.'));
253 }
f48c6947
AB
254 if (isset($form_state['values']['field_num'])) {
255 if (is_numeric($form_state['values']['field_num'])) {
256 if ($form_state['values']['field_num'] < 1) {
257 form_set_error('field_num', t('At least one field must be created.'));
258 }
259 }
260 else {
261 form_set_error('field_num', t('Enter a number greater than 0.'));
262 }
263 }
264 // Check for dupes.
265 if (isset($form_state['values']['fields'])) {
266 $names = array();
267 foreach ($form_state['values']['fields'] as $field) {
268 if (is_numeric($names[$field['name']])) {
269 form_set_error('name', t('Names can\'t be numbers.'));
270 }
271 if (!isset($names[$field['name']])) {
272 $names[$field['name']] = $field['name'];
273 }
274 else {
275 form_set_error('name', t('Names must be unique.'));
276 }
277 }
278 }
03608987
AB
279}
280
281/**
e6f88837 282 * Submit handler for create table form.
2ace3f91 283 */
dcdaddd1 284function data_ui_create_form_submit($form, &$form_state) {
19aba4f3 285
f48c6947
AB
286 if (isset($form_state['values']['field_num'])) {
287 $form_state['storage'] = $form_state['values'];
288 }
289 elseif (isset($form_state['values']['fields'])) {
120dbbcb
AB
290
291 // Create a schema from user input.
19aba4f3 292 $schema = $index = $primary = $meta = array();
f48c6947 293 foreach ($form_state['values']['fields'] as $field) {
19aba4f3
AB
294 $schema['fields'][$field['name']] = data_build_field_definition($field);
295 $meta['fields'][$field['name']]['label'] = $field['label'];
296
297 // Limit index if field type is text.
120dbbcb 298 if (!empty($field['index'])) {
19aba4f3 299 $index[$field['name']] = data_get_index_definition($field['name'], $field['type']);
120dbbcb
AB
300 }
301 if (!empty($field['primary'])) {
19aba4f3 302 $primary[] = data_get_pk_definition($field['name'], $field['type']);
120dbbcb 303 }
f48c6947 304 }
120dbbcb 305 $schema['indexes'] = $index;
ad756c3e 306 $schema['primary key'] = $primary;
19aba4f3
AB
307
308 // Create table.
f48c6947 309 if ($table = data_create_table(data_name(trim($form_state['storage']['name'])), $schema, trim($form_state['storage']['title']))) {
19aba4f3 310 $meta = $table->update(array('meta' => $meta));
f48c6947
AB
311 drupal_set_message(t('Created table !table', array('!table' => $table->get('name'))));
312 }
313 else {
314 drupal_set_message(t('Error creating table'), 'error');
315 }
19aba4f3 316
120dbbcb
AB
317 // Unset storage to enable redirect.
318 unset($form_state['storage']);
319 $form_state['redirect'] = 'admin/content/data';
f48c6947 320 }
03608987
AB
321}
322
72ba49d9
AB
323/**
324 * Form callback for revert table form.
325 */
326function data_ui_revert_form(&$form_state, $table) {
327 $form = array();
328 $form['#redirect'] = 'admin/content/data';
329 $form['#table'] = $table;
330
331 return confirm_form($form,
332 t('Revert this table?'),
333 'admin/content/data',
334 t('Are you sure you would like to revert table !table? This will reset all information about this table its definition in code. This action cannot be undone.', array('!table' => $table->get('name'))),
335 t('Revert'), t('Cancel')
336 );
337}
338
339/**
fed65212 340 * Submit handler for data_ui_revert_form().
72ba49d9
AB
341 */
342function data_ui_revert_form_submit($form, &$form_state) {
343 $table = $form['#table'];
344 $table->revert();
345}
03608987
AB
346
347/**
fed65212 348 * Form callback for drop table form.
03608987
AB
349 */
350function data_ui_drop_form(&$form_state, $table) {
351 $form = array();
352 $form['#redirect'] = 'admin/content/data';
353 $form['#table'] = $table;
354
355 return confirm_form($form,
356 t('Drop this table?'),
0ef5d565 357 'admin/content/data',
03608987
AB
358 t('Are you sure you would like to drop table !table? This action cannot be undone.', array('!table' => $table->get('name'))),
359 t('Drop'), t('Cancel')
360 );
361}
362
363/**
364 * Submit handler for data_ui_drop_form().
365 */
366function data_ui_drop_form_submit($form, &$form_state) {
367 $table = $form['#table'];
f48c6947 368 data_drop_table($table->get('name'));
03608987
AB
369}
370
371/**
372 * Form callback for editing a table.
373 */
374function data_ui_edit_form(&$form_state, $table) {
2ace3f91
AB
375 drupal_set_title(t('Data table !table', array('!table' => $table->get('name'))));
376 $schema = $table->get('table_schema');
377 $meta = $table->get('meta');
378
379 $form = array();
380 // Keep table.
381 $form['table'] = array(
382 '#type' => 'value',
383 '#value' => $table,
384 );
385
386 // Existing fields.
387 $form['fields'] = array('#tree' => TRUE);
cff26223
AB
388 if (isset($schema['fields'])) {
389 foreach ($schema['fields'] as $field_name => $field) {
390 $form['fields'][$field_name] = array();
391 $form['fields'][$field_name]['selected'] = array(
392 '#type' => 'checkbox',
393 );
394 $form['fields'][$field_name]['name'] = array('#value' => $field_name);
395 $form['fields'][$field_name]['label'] = array(
396 '#type' => 'textfield',
397 '#size' => 20,
398 '#default_value' => $meta['fields'][$field_name]['label'],
399 );
400 $form['fields'][$field_name]['type'] = array(
401 '#type' => 'select',
19aba4f3 402 '#options' => data_get_field_types(),
cff26223
AB
403 '#default_value' => $field['type'],
404 );
405 $form['fields'][$field_name]['unsigned'] = array(
406 '#type' => 'checkbox',
407 '#default_value' => $field['unsigned'],
408 );
120dbbcb
AB
409 $form['fields'][$field_name]['index'] = array(
410 '#type' => 'checkbox',
ad756c3e 411 '#default_value' => isset($schema['indexes'][$field_name]),
120dbbcb
AB
412 );
413 $form['fields'][$field_name]['primary'] = array(
414 '#type' => 'checkbox',
ad756c3e 415 '#default_value' => isset($schema['primary key']) ? in_array($field_name, $schema['primary key']) : FALSE,
120dbbcb 416 );
0cd5c3d6
AB
417 if ($join = _data_ui_get_join($meta['join'], $field_name)) {
418 $join = $join['left_table'] .'.'. $join['left_field'];
3c77dfc3
AB
419 }
420 else {
0cd5c3d6 421 $join = t('<none>');
3c77dfc3 422 }
0cd5c3d6
AB
423 $join = l($join, 'admin/content/data/edit/'. $table->get('name') .'/join/'.$field_name);
424 $form['fields'][$field_name]['join']['#value'] = $join;
cff26223 425 }
2ace3f91
AB
426 }
427
428 // Add a new field.
f48c6947 429 $form['new'] = _data_ui_field_form();
0ef5d565
AB
430 $form['new']['primary'] = array(
431 '#type' => 'markup',
432 '#value' => '&nbsp;',
433 );
0cd5c3d6
AB
434 $form['new']['join'] = array(
435 '#type' => 'markup',
436 '#value' => '&nbsp;',
437 );
2ace3f91
AB
438 $form['new']['add'] = array(
439 '#type' => 'submit',
440 '#value' => t('Add new'),
441 );
442
443 // Bulk operations.
444 $options = array(
445 t('Bulk operations'),
446 'delete' => t('Delete all selected'),
447 );
448 $form['bulk_operation'] = array(
449 '#type' => 'select',
450 '#options' => $options,
451 );
452 $form['submit'] = array(
453 '#type' => 'submit',
454 '#value' => t('Save'),
455 );
456
457 return $form;
458}
459
460/**
461 * Submit form.
462 */
03608987 463function data_ui_edit_form_submit($form, &$form_state) {
2ace3f91
AB
464 $table = $form_state['values']['table'];
465 $schema = $table->get('table_schema');
466
467 if ($form_state['clicked_button']['#value'] == t('Save')) {
468 $fields = $schema['fields'];
469 $new_fields = $form_state['values']['fields'];
44da723a 470
ad756c3e
AB
471 $new_index = array();
472 $new_primary_key = array();
473
03608987 474 if (empty($form_state['values']['bulk_operation']) && isset($fields)) {
44da723a
AB
475
476 // Convert schema.
477 foreach ($fields as $field_name => $field) {
478 if ($new_spec = _data_ui_changed($new_fields[$field_name], $field)) {
479 $table->changeField($field_name, $new_spec);
480 drupal_set_message(t('Changed field !field_name', array('!field_name' => $field_name)));
481 }
ad756c3e
AB
482 if ($new_fields[$field_name]['index']) {
483 $new_index[] = $field_name;
484 }
485 if ($new_fields[$field_name]['primary']) {
486 $new_primary_key[] = $field_name;
487 }
2ace3f91 488 }
ad756c3e
AB
489 $table->changeIndex($new_index);
490 $table->changePrimaryKey($new_primary_key);
491
44da723a
AB
492 // Update meta data.
493 $meta = $table->get('meta');
494 foreach ($new_fields as $field_name => $field) {
495 $meta['fields'][$field_name]['label'] = $field['label'];
496 }
497 $table->update(array('meta' => $meta));
2ace3f91 498 }
44da723a
AB
499 else {
500 // Bulk updates.
501 switch ($form_state['values']['bulk_operation']) {
502 case 'delete':
503 foreach ($new_fields as $field_name => $field) {
f48c6947
AB
504 if (!empty($field['selected'])) {
505 // One field must stay.
506 $schema = $table->get('table_schema');
507 if (count($schema['fields']) > 1) {
03608987
AB
508 $table->dropField($field_name);
509 drupal_set_message(t('Deleted field !field_name', array('!field_name' => $field_name)));
510 }
f48c6947
AB
511 else {
512 drupal_set_message('You cannot delete all fields from a table, drop the table instead.', 'error');
513 }
44da723a 514 }
2ace3f91 515 }
44da723a
AB
516 break;
517 }
2ace3f91
AB
518 }
519 }
520 elseif ($form_state['clicked_button']['#value'] == t('Add new')) {
521 $new = $form_state['values']['new'];
19aba4f3 522 $spec = data_build_field_definition($new);
0ef5d565
AB
523 $table->addField($new['name'], $spec);
524 if (!empty($new['index'])) {
525 $table->addIndex($new['name']);
03608987 526 }
2ace3f91
AB
527 $meta = $table->get('meta');
528 $meta['fields'][$new['name']]['label'] = $new['label'];
529 $table->update(array('meta' => $meta));
530 }
531}
532
f48c6947 533/**
0cd5c3d6
AB
534 * Join form.
535 */
536function data_ui_join_form(&$form_state, $table, $field_name) {
537 // drupal_set_title(t('Join field'));
538
539 $schema = $table->get('table_schema');
540 $meta = $table->get('meta');
541
542 // Validate input.
543 if (!isset($field_name) || !isset($schema['fields'][$field_name])) {
544 drupal_set_message(t('Invalid field.'), 'error');
545 drupal_goto('admin/content/data/edit/'. $table->get('name'));
546 }
547
548 // List all tables that schema API knows about as optoins.
549 // @todo: This is a looong list - needs some AHAH to scale better.
550 $table_schemas = drupal_get_schema();
551 ksort($table_schemas);
552 $options = array();
553 foreach ($table_schemas as $table_name => $schema) {
554 if ($table->get('name') != $table_name) {
555 foreach ($schema['fields'] as $name => $info) {
556 $options[$table_name][$table_name .'.'. $name] = $table_name .'.'. $name;
557 }
558 }
559 }
560
561 // Build form.
562 $form = array();
563 $form['#table'] = $table;
564 $form['#field_name'] = $field_name;
565 $form['#redirect'] = 'admin/content/data/edit/'. $table->get('name');
566 $join = _data_ui_get_join($meta['join'], $field_name);
567 $form['#original_join'] = $join;
568 $form['left'] = array(
569 '#type' => 'select',
570 '#title' => t('Join !table_field to', array('!table_field' => $table->get('name') .'.'. $field_name)),
571 '#options' => $options,
572 '#default_value' => $join['left_table'] .'.'. $join['left_field'],
573 );
574 $form['inner_join'] = array(
575 '#type' => 'radios',
576 '#title' => t('Join type'),
577 '#options' => array(t('Left join'), t('Inner join')),
578 '#default_value' => $join['inner_join'] ? $join['inner_join'] : 0,
579 );
580
581 // Use confirm form for its formatting.
582 $form = confirm_form($form,
583 t('Join field'),
584 'admin/content/data/edit/'. $table->get('name'),
585 '',
586 t('Save'), t('Cancel')
587 );
588 $form['actions']['delete'] = array(
589 '#type' => 'submit',
590 '#value' => t('Delete'),
591 '#submit' => array('data_ui_join_form_submit_delete'),
592 );
593 krsort($form['actions']);
594
595 return $form;
596}
597
598/**
599 * Submit handler for data_ui_join_form().
600 */
601function data_ui_join_form_submit($form, &$form_state) {
602 list($left_table, $left_field) = explode('.', $form_state['values']['left']);
603 $form['#table']->link($left_table, $left_field, $form['#field_name'], $form_state['values']['inner_join']);
604 drupal_set_message(t('Updated join information.'));
605}
606
607/**
608 * Submit handler for data_ui_join_form() - handles deletion.
609 */
610function data_ui_join_form_submit_delete($form, &$form_state) {
611 // Use the original join information.
612 $form['#table']->unlink($form['#original_join']['left_table']);
613 drupal_set_message(t('Removed join information.'));
614}
615
616/**
72ba49d9
AB
617 * Export form.
618 */
619function data_ui_export_form(&$form_state, $table) {
620 $code = data_export($table->get('name'));
621
622 $form['export'] = array(
623 '#title' => t('Export table definition'),
624 '#type' => 'textarea',
625 '#value' => $code,
626 '#rows' => substr_count($code, "\n"),
627 );
628 return $form;
629}
630
631/**
dcdaddd1 632 * Theme data_ui_create_form.
f48c6947 633 */
dcdaddd1 634function theme_data_ui_create_form($form) {
f48c6947
AB
635
636 // Render field definition form elements in a table.
637 if (isset($form['fields'])) {
638 $output = drupal_render($form['help']);
639
640 $rows = array();
641 foreach (element_children($form['fields']) as $e) {
642 $row = array();
643 foreach (element_children($form['fields'][$e]) as $f) {
644 $row[] = drupal_render($form['fields'][$e][$f]);
645 }
646 $rows[] = $row;
647 }
120dbbcb 648 $header = array(t('Name *'), t('Label'), t('Type'), t('Unsigned'), t('Index'), t('Primary key'));
f48c6947
AB
649 $output .= theme('table', $header, $rows);
650
651 $output .= drupal_render($form);
652 return $output;
653 }
654 return drupal_render($form);
655}
2ace3f91
AB
656
657/**
658 * Theme data_ui_admin_form.
659 */
03608987 660function theme_data_ui_edit_form($form) {
2ace3f91
AB
661
662 // Format existing fields.
663 $rows = array();
664 foreach (element_children($form['fields']) as $e) {
665 $row = array();
0ef5d565 666 foreach (element_children($form['fields'][$e]) as $f) {
2ace3f91
AB
667 $row[] = drupal_render($form['fields'][$e][$f]);
668 }
669 $row[] = '&nbsp;';
670 $rows[] = $row;
671 }
672
673 // New fields form.
674 $row = array('&nbsp;');
675 foreach (element_children($form['new']) as $e) {
676 $row[] = drupal_render($form['new'][$e]);
677 }
678 $rows[] = $row;
679
0cd5c3d6 680 $header = array(t('Select'), t('Name'), t('Label'), t('Type'), t('Unsigned'), t('Index'), t('Primary key'), t('Joins'));
2ace3f91
AB
681 $output .= theme('table', $header, $rows);
682 $output .= drupal_render($form);
683 return $output;
684}
685
686/**
2c44bed5
AB
687 * Theme a schema module comparison result. Ie. the result of schema_compare_table().
688 *
689 * @todo: move to schema module - write a patch.
690 */
691function theme_data_ui_schema_compare_table($comparison) {
692 $output = '';
693 foreach ($comparison as $k => $v) {
694 if (!empty($v)) {
695 if (is_string($k)) {
696 $output .= '<dl>';
697 $output .= '<dt>'. ucfirst($k) .':</dt>';
698 $output .= '<dd>';
699 if (is_string($v)) {
700 $output .= $v;
701 }
702 elseif (is_array($v)) {
703 $output .= theme('item_list', $v);
704 }
705 $output .= '</dd>';
706 $output .= '</dl>';
707 }
708 }
709 }
710 return $output;
711}
712
713/**
2ace3f91
AB
714 * Magic helper function. Detect changed between keys in $new and $field
715 * and return a new field spec based on $field IF there are differences.
716 *
717 * Otherwise return FALSE.
718 *
719 * Currently checked: type, unsigned
720 */
721function _data_ui_changed($new, $field) {
722 $changed = FALSE;
723 if ($field['type'] != $new['type']) {
724 $field['type'] = $new['type'];
725 $changed = TRUE;
726 }
727 if ($field['unsigned'] != $new['unsigned']) {
728 $field['unsigned'] = $new['unsigned'];
729 $changed = TRUE;
730 }
731 if ($changed) {
732 return $field;
733 }
734 return FALSE;
f48c6947
AB
735}
736
737/**
738 * Helper function that generates a form snippet for defining a field.
739 */
740function _data_ui_field_form($required = FALSE) {
741 $form = array();
742 $form['#tree'] = TRUE;
743 $form['name'] = array(
744 '#type' => 'textfield',
745 '#size' => 20,
746 '#required' => $required,
747 );
748 $form['label'] = array(
749 '#type' => 'textfield',
750 '#size' => 20,
751 );
752 $form['type'] = array(
753 '#type' => 'select',
19aba4f3 754 '#options' => data_get_field_types(),
f48c6947
AB
755 );
756 $form['unsigned'] = array(
757 '#type' => 'checkbox',
758 );
120dbbcb
AB
759 $form['index'] = array(
760 '#type' => 'checkbox',
761 );
762 $form['primary'] = array(
763 '#type' => 'checkbox',
764 );
f48c6947 765 return $form;
ad756c3e 766}
3c77dfc3
AB
767
768/**
769 * Helper function to get link information for a specific field.
770 */
0cd5c3d6 771function _data_ui_get_join($join, $field) {
3c77dfc3
AB
772 if (is_array($join)) {
773 foreach ($join as $left_table => $info) {
774 if ($info['field'] == $field) {
0cd5c3d6
AB
775 $info['left_table'] = $left_table;
776 return $info;
3c77dfc3
AB
777 }
778 }
779 }
780 return FALSE;
781}