Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
// $Id$
/**
* @file
* Create field groups for CCK fields.
*
* 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.
* - hook_fieldgroup_default_settings: Add additional fieldgroup default settings.
* - hook_fieldgroup_save: Do additional processing when a fieldgroup is saved.
*/
/**
* Implementation of hook_init().
*/
function fieldgroup_init() {
drupal_add_css(drupal_get_path('module', 'fieldgroup') .'/fieldgroup.css');
}
/**
* Implementation of hook_menu().
*/
function fieldgroup_menu() {
$items = array();
// Make sure this doesn't fire until field_info_fieldable_types() is working,
// needed to avoid errors on initial installation.
if (!defined('MAINTENANCE_MODE')) {
// Create tabs for all possible bundles.
$bundles = field_info_bundles();
foreach ($bundles as $bundle_name => $bundle_label) {
$admin_path = cck_bundle_admin_path($bundle_name);
$items[$admin_path .'/groups/%'] = array(
'title' => 'Edit group',
'page callback' => 'drupal_get_form',
'page arguments' => array('fieldgroup_group_edit_form', $bundle_name, 5),
'access arguments' => array('administer content types'),
'type' => MENU_CALLBACK,
);
$items[$admin_path .'/groups/%/remove'] = array(
'title' => 'Edit group',
'page callback' => 'drupal_get_form',
'page arguments' => array('fieldgroup_remove_group', $bundle_name, 5),
'access arguments' => array('administer content types'),
'type' => MENU_CALLBACK,
);
}
}
return $items;
}
/**
* Implementation of hook_theme().
*/
function fieldgroup_theme() {
return array(
'fieldgroup_simple' => array(
Yves Chedemois
committed
'template' => 'fieldgroup-simple',
'arguments' => array('element' => NULL),
),
'fieldgroup_fieldset' => array(
'arguments' => array('element' => NULL),
),
'fieldgroup_display_overview_form' => array(
'arguments' => array('form' => NULL),
),
);
}
/**
* Implementation of hook_elements().
*/
function fieldgroup_elements() {
return array(
'fieldgroup_simple' => array(),
'fieldgroup_fieldset' => array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL,),
);
}
/**
* Implementation of hook_fieldapi().
*/
function fieldgroup_field_fieldapi($op, $field) {
switch ($op) {
case 'delete instance':
Yves Chedemois
committed
db_query("DELETE FROM {field_group_fields} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']);
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
break;
}
cache_clear_all('fieldgroup_data', 'cache_field');
}
function fieldgroup_group_edit_form(&$form_state, $bundle, $group_name) {
$groups = fieldgroup_groups($bundle);
if (!$group = $groups[$group_name]) {
drupal_not_found();
exit;
}
$form['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
'#default_value' => $group['label'],
'#required' => TRUE,
);
// 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'),
'#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'),
'#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 the display.'),
);
$form['settings']['display']['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#default_value' => $group['settings']['display']['description'],
'#rows' => 5,
'#description' => t('A description of the group.'),
'#required' => FALSE,
);
foreach (array_keys(field_build_modes(field_info_bundle_entity($bundle))) as $key) {
$form['settings']['display'][$key]['format'] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]['format']) ? $group['settings']['display'][$key]['format'] : 'fieldset');
$form['settings']['display'][$key]['exclude'] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]['exclude']) ? $group['settings']['display'][$key]['exclude'] : 0);
}
$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['#bundle'] = $bundle;
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#weight' => 10,
);
return $form;
}
function fieldgroup_group_edit_form_submit($form, &$form_state) {
$form_values = $form_state['values'];
$bundle = $form['#bundle'];
fieldgroup_save_group($bundle, $form_values);
$form_state['redirect'] = cck_bundle_admin_path($bundle) .'/fields';
}
function fieldgroup_remove_group(&$form_state, $bundle, $group_name) {
$groups = fieldgroup_groups($bundle);
$group = isset($groups[$group_name]) ? $groups[$group_name] : '';
if (empty($group)) {
drupal_not_found();
exit;
}
$form['#submit'][] = 'fieldgroup_remove_group_submit';
$form['#bundle'] = $bundle;
$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']))),
cck_bundle_admin_path($bundle) .'/fields', t('This action cannot be undone.'),
t('Remove'), t('Cancel'));
}
function fieldgroup_remove_group_submit($form, &$form_state) {
$form_values = $form_state['values'];
$bundle = $form['#bundle'];
$group_name = $form['#group_name'];
fieldgroup_delete($bundle, $group_name);
drupal_set_message(t('The group %group_name has been removed.', array('%group_name' => $group_name)));
$form_state['redirect'] = cck_bundle_admin_path($bundle) .'/fields';
}
/*
* Returns all groups for a content type
*/
function fieldgroup_groups($bundle = '', $sorted = FALSE, $reset = FALSE) {
static $groups, $groups_sorted;
if (!isset($groups) || $reset) {
if ($cached = cache_get('fieldgroup_data', 'cache_field')) {
$data = $cached->data;
$groups = $data['groups'];
$groups_sorted = $data['groups_sorted'];
}
else {
$result = db_query("SELECT * FROM {field_group} ORDER BY weight, group_name");
$groups = array();
$groups_sorted = array();
while ($group = db_fetch_array($result)) {
$group['settings'] = unserialize($group['settings']);
$group['fields'] = array();
$groups[$group['bundle']][$group['group_name']] = $group;
$groups_sorted[$group['bundle']][] = &$groups[$group['bundle']][$group['group_name']];
}
//load fields
$result = db_query("SELECT nfi.*, ng.group_name FROM {field_group} ng ".
"INNER JOIN {field_group_fields} ngf ON ngf.bundle = ng.bundle AND ngf.group_name = ng.group_name ".
"INNER JOIN {field_config_instance} nfi ON nfi.field_name = ngf.field_name AND nfi.bundle = ngf.bundle ".
"WHERE nfi.widget_active = 1 ORDER BY nfi.weight");
while ($field = db_fetch_array($result)) {
$groups[$field['bundle']][$field['group_name']]['fields'][$field['field_name']] = $field;
}
cache_set('fieldgroup_data', array('groups' => $groups, 'groups_sorted' => $groups_sorted), 'cache_field');
}
}
if (empty($bundle)) {
return $groups;
}
elseif (empty($groups) || empty($groups[$bundle])) {
return array();
}
return $sorted ? $groups_sorted[$bundle] : $groups[$bundle];
}
function _fieldgroup_groups_label($bundle) {
$groups = fieldgroup_groups($bundle);
$labels[''] = '<'. t('none') .'>';
foreach ($groups as $group_name => $group) {
$labels[$group_name] = t($group['label']);
}
return $labels;
}
function _fieldgroup_field_get_group($bundle, $field_name) {
return db_result(db_query("SELECT group_name FROM {field_group_fields} WHERE bundle = '%s' AND field_name = '%s'", $bundle, $field_name));
}
/**
* Implementation of hook_form_alter()
*/
function fieldgroup_form_alter(&$form, $form_state, $form_id) {
// TODO This only works right on a node form, need to make it more general.
if (!empty($form['#fields']) && !empty($form['type'])) {
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' => field_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])) {
// 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;
}
// Move the form element.
$form[$group_name][$field_name] = $form[$field_name];
unset($form[$field_name]);
$form['#fields'][$field_name]['form_path'] = array($group_name, $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);
}
}
}
// The group is only added here so it will appear in the export
// when using Content Copy.
elseif ($form_id == 'cck_field_edit_form' && isset($form['widget'])) {
$bundle = $form['bundle']['#value'];
$form['widget']['group'] = array(
'#type' => 'value',
'#value' => _fieldgroup_field_get_group($bundle, $form['field_name']['#value']),
);
}
elseif ($form_id == 'cck_field_overview_form') {
$form['#validate'][] = 'fieldgroup_field_overview_form_validate';
$form['#submit'][] = 'fieldgroup_field_overview_form_submit';
}
elseif ($form_id == 'cck_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 == 'cck_field_remove_form') {
$form['#submit'][] = 'fieldgroup_field_remove_form_submit';
}
}
/**
* API for group name validation.
*
* Pulled into separate function to be re-usable.
*/
function fieldgroup_validate_name($group, $bundle) {
$errors = array();
// No label.
if (!$group['label']) {
$errors['label'][] = t('You need to provide a label.');
}
// 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;
}
// 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));
}
// Group name already exists.
$groups = fieldgroup_groups($bundle);
if (isset($groups[$group_name])) {
$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'];
if (array_filter(array($group['label'], $group['group_name']))) {
$validation = fieldgroup_validate_name($group, $form['#bundle']);
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);
}
}
}
}
$group_name = $validation['group_name'];
form_set_value($form['_add_new_group']['group_name'], $group_name, $form_state);
}
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.
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) {
$form_values = $form_state['values'];
$bundle = $form['#bundle'];
// 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'], $bundle);
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
fieldgroup_save_group($bundle, $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) {
// 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.
// field_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 ?
fieldgroup_update_fields(array('field_name' => $key, 'group' => $parent, 'bundle' => $bundle));
}
// 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 {field_group} SET weight = %d WHERE bundle = '%s' AND group_name = '%s'",
$values['weight'], $bundle, $key);
}
}
cache_clear_all('fieldgroup_data', 'cache_field');
}
Karen Stevenson
committed
function field_group_default_settings($group_type, $bundle) {
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
$settings = array(
'form' => array('style' => 'fieldset', 'description' => ''),
'display' => array('description' => '', 'label' => 'above'),
);
module_load_include('inc', 'field', 'includes/field.admin');
foreach (array_keys(field_build_modes(field_info_bundle_entity($bundle))) as $key) {
$settings['display'][$key]['format'] = 'fieldset';
$settings['display'][$key]['exclude'] = 0;
}
// Allow other modules to add new default settings.
$settings = array_merge($settings, module_invoke_all('fieldgroup_default_settings', $group_type));
return $settings;
}
function fieldgroup_display_overview_form_submit($form, &$form_state) {
$form_values = $form_state['values'];
$groups = fieldgroup_groups($form['#bundle']);
foreach ($form_values as $key => $values) {
if (in_array($key, $form['#groups'])) {
$group = $groups[$key];
// We have some numeric keys here, so we can't use array_merge.
$group['settings']['display'] = $values + $group['settings']['display'];
fieldgroup_save_group($form['#bundle'], $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 {field_group_fields} WHERE bundle = '%s' AND field_name = '%s'", $form_values['bundle'], $form_values['field_name']);
}
/**
Karen Stevenson
committed
* Implementation of hook_view().
*/
Karen Stevenson
committed
function fieldgroup_view(&$node, $teaser) {
// TODO This will only work on a node, need to make it general enough to work on users.
Karen Stevenson
committed
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
// Prevent against invalid 'nodes' built by broken 3rd party code.
if (isset($node->type)) {
// 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) {
// 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(
'#title' => $label ? check_plain(t($group['label'])) : '',
'#description' => $label ? field_filter_xss(t($group['settings']['display']['description'])) : '',
);
$format = isset($group['settings']['display'][$context]['format']) ? $group['settings']['display'][$context]['format'] : 'fieldset';
switch ($format) {
case 'simple':
$element['#type'] = 'fieldgroup_simple';
$element['#group_name'] = $group_name;
$element['#node'] = $node;
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])) {
$element[$field_name] = $node->content[$field_name];
}
Karen Stevenson
committed
}
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);
}
Karen Stevenson
committed
foreach ($group['fields'] as $field_name => $field) {
if (isset($node->content[$field_name])) {
unset($node->content[$field_name]);
}
}
Karen Stevenson
committed
// The wrapper lets us get the themed output for the group
// to populate the $GROUP_NAME_rendered variable for node templates,
// and hide it from the $content variable if needed.
// See fieldgroup_preprocess_node(), theme_fieldgroup_wrapper().
$wrapper = array(
'group' => $element,
'#weight' => $group['weight'],
'#post_render' => array('fieldgroup_wrapper_post_render'),
'#group_name' => $group_name,
'#bundle' => $node->type,
'#context' => $context,
);
$node->content[$group_name] = $wrapper;
}
}
Karen Stevenson
committed
break;
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
}
/**
* Hide specified fields from the $content variable in node templates.
*/
function fieldgroup_wrapper_post_render($content, $element) {
$groups = fieldgroup_groups($element['#bundle']);
$group = $groups[$element['#group_name']];
// The display settings are not in quite the same place in the
// group and the field, so create the value the theme will expect.
$group['display_settings'] = $group['settings']['display'];
if (theme('field_exclude', $content, $group, $element['#context'])) {
return '';
}
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.
*/
function fieldgroup_get_group($bundle, $field_name) {
foreach (fieldgroup_groups($bundle) 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) {
if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) {
// update the tables
db_query("UPDATE {field_group} SET bundle='%s' WHERE bundle='%s'", array($info->type, $info->old_type));
db_query("UPDATE {field_group_fields} SET bundle='%s' WHERE bundle='%s'", array($info->type, $info->old_type));
cache_clear_all('fieldgroup_data', 'cache_field');
}
elseif ($op == 'delete') {
db_query("DELETE FROM {field_group} WHERE bundle = '%s'", $info->type);
db_query("DELETE FROM {field_group_fields} WHERE bundle = '%s'", $info->type);
}
}
function fieldgroup_types() {
$types = array('standard' => t('Standard group'));
// Allow other modules to add new group_types.
$types = array_merge($types, module_invoke_all('fieldgroup_types'));
return $types;
}
/**
* CRUD API for fieldgroup module.
*
* @todo
* Make this into more of a real API for groups.
*/
/*
* Saves the given group for this content-type
*/
function fieldgroup_save_group($bundle, $group) {
$groups = fieldgroup_groups($bundle);
// 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);
}
if (!isset($groups[$group['group_name']])) {
// Accept group name from programmed submissions if valid.
db_query("INSERT INTO {field_group} (group_type, bundle, group_name, label, settings, weight)".
" VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $group['group_type'], $bundle, $group['group_name'], $group['label'], serialize($group['settings']), $group['weight']);
cache_clear_all('fieldgroup_data', 'cache_field');
return SAVED_NEW;
}
else {
db_query("UPDATE {field_group} SET group_type = '%s', label = '%s', settings = '%s', weight = %d ".
"WHERE bundle = '%s' AND group_name = '%s'",
$group['group_type'], $group['label'], serialize($group['settings']), $group['weight'], $bundle, $group['group_name']);
cache_clear_all('fieldgroup_data', 'cache_field');
return SAVED_UPDATED;
}
}
function fieldgroup_update_fields($form_values) {
$default = _fieldgroup_field_get_group($form_values['bundle'], $form_values['field_name']);
if ($default != $form_values['group']) {
if ($form_values['group'] && !$default) {
db_query("INSERT INTO {field_group_fields} (bundle, group_name, field_name) VALUES ('%s', '%s', '%s')", $form_values['bundle'], $form_values['group'], $form_values['field_name']);
}
elseif ($form_values['group']) {
db_query("UPDATE {field_group_fields} SET group_name = '%s' WHERE bundle = '%s' AND field_name = '%s'", $form_values['group'], $form_values['bundle'], $form_values['field_name']);
}
else {
db_query("DELETE FROM {field_group_fields} WHERE bundle = '%s' AND field_name = '%s'", $form_values['bundle'], $form_values['field_name']);
}
cache_clear_all('fieldgroup_data', 'cache_field');
}
}
function fieldgroup_delete($bundle, $group_name) {
db_query("DELETE FROM {field_group} WHERE bundle = '%s' AND group_name = '%s'", $bundle, $group_name);
db_query("DELETE FROM {field_group_fields} WHERE bundle = '%s' AND group_name = '%s'", $bundle, $group_name);
cache_clear_all('fieldgroup_data', 'cache_field');
}
/**
* 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";
}
/**
* Process variables for fieldgroup.tpl.php.
*
* The $variables array contains the following arguments:
* - $group_name
* - $group_name_css
* - $label
* - $description
* - $content
*
Yves Chedemois
committed
* @see fieldgroup-simple.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'] : '';
Yves Chedemois
committed
$vars['template_files'] = array(
'fieldgroup-simple-',
'fieldgroup-simple-'. $element['#group_name'],
'fieldgroup-simple-'. $element['#node']->type,
'fieldgroup-simple-'. $element['#group_name'] .'-'. $element['#node']->type,
);
}
/**
* 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'] : '';
}
}