Projet

Général

Profil

Paste
Télécharger (23,7 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / views_bulk_operations / actions / modify.action.inc @ 9df8b457

1
<?php
2

    
3
/**
4
 * @file VBO action to modify entity values (properties and fields).
5
 */
6

    
7
// Specifies that all available values should be shown to the user for editing.
8
define('VBO_MODIFY_ACTION_ALL', '_all_');
9

    
10
function views_bulk_operations_modify_action_info() {
11
  return array('views_bulk_operations_modify_action' => array(
12
    'type' => 'entity',
13
    'label' => t('Modify entity values'),
14
    'behavior' => array('changes_property'),
15
    // This action only works when invoked through VBO. That's why it's
16
    // declared as non-configurable to prevent it from being shown in the
17
    // "Create an advanced action" dropdown on admin/config/system/actions.
18
    'configurable' => FALSE,
19
    'vbo_configurable' => TRUE,
20
    'triggers' => array('any'),
21
  ));
22
}
23

    
24
/**
25
 * Action function.
26
 *
27
 * Goes through new values and uses them to modify the passed entity by either
28
 * replacing the existing values, or appending to them (based on user input).
29
 */
30
function views_bulk_operations_modify_action($entity, $context) {
31
  list(,,$bundle_name) = entity_extract_ids($context['entity_type'], $entity);
32
  // Handle Field API fields.
33
  if (!empty($context['selected']['bundle_' . $bundle_name])) {
34
    // The pseudo entity is cloned so that changes to it don't get carried
35
    // over to the next execution.
36
    $pseudo_entity = clone $context['entities'][$bundle_name];
37
    foreach ($context['selected']['bundle_' . $bundle_name] as $key) {
38
      // Get this field's language. We can just pull it from the pseudo entity
39
      // as it was created using field_attach_form and entity_language so it's
40
      // already been figured out if this field is translatable or not and
41
      // applied the appropriate language code to the field
42
      $language = key($pseudo_entity->{$key});
43
      // Replace any tokens that might exist in the field columns.
44
      foreach ($pseudo_entity->{$key}[$language] as $delta => &$item) {
45
        foreach ($item as $column => $value) {
46
          if (is_string($value)) {
47
            $item[$column] = token_replace($value, array($context['entity_type'] => $entity), array('sanitize' => FALSE));
48
          }
49
        }
50
      }
51

    
52
      if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->$key)) {
53
        $entity->{$key}[$language] = array_merge($entity->{$key}[$language], $pseudo_entity->{$key}[$language]);
54

    
55
        // Check if we breached cardinality, and notify the user.
56
        $field_info = field_info_field($key);
57
        $field_count = count($entity->{$key}[$language]);
58
        if ($field_info['cardinality'] != FIELD_CARDINALITY_UNLIMITED && $field_count > $field_info['cardinality']) {
59
          $entity_label = entity_label($context['entity_type'], $entity);
60
          $warning = t('Tried to set !field_count values for field !field_name that supports a maximum of !cardinality.',
61
                       array('!field_count' => $field_count,
62
                             '!field_name' => $field_info['field_name'],
63
                             '!cardinality' => $field_info['cardinality']));
64
          drupal_set_message($warning, 'warning', FALSE);
65
        }
66

    
67
        // Prevent storing duplicate references.
68
        if (strpos($field_info['type'], 'reference') !== FALSE) {
69
          $entity->{$key}[$language] = array_unique($entity->{$key}[LANGUAGE_NONE], SORT_REGULAR);
70
        }
71
      }
72
      else {
73
        $entity->{$key}[$language] = $pseudo_entity->{$key}[$language];
74
      }
75
    }
76
  }
77

    
78
  // Handle properties.
79
  if (!empty($context['selected']['properties'])) {
80
    // Use the wrapper to set property values, since some properties need
81
    // additional massaging by their setter callbacks.
82
    // The wrapper will automatically modify $entity itself.
83
    $wrapper = entity_metadata_wrapper($context['entity_type'], $entity);
84
    foreach ($context['selected']['properties'] as $key) {
85
      if (!$wrapper->$key->access('update')) {
86
        // No access.
87
        continue;
88
      }
89

    
90
      if (in_array($key, $context['append']['properties'])) {
91
        $old_values = $wrapper->$key->value();
92
        $wrapper->$key->set($context['properties'][$key]);
93
        $new_values = $wrapper->{$key}->value();
94
        $all_values = array_merge($old_values, $new_values);
95
        $wrapper->$key->set($all_values);
96
      }
97
      else {
98
        $value = $context['properties'][$key];
99
        if (is_string($value)) {
100
          $value = token_replace($value, array($context['entity_type'] => $entity), array('sanitize' => FALSE));
101
        }
102
        $wrapper->$key->set($value);
103
      }
104
    }
105
  }
106
}
107

    
108
/**
109
 * Action form function.
110
 *
111
 * Displays form elements for properties acquired through Entity Metadata
112
 * (hook_entity_property_info()), as well as field widgets for each
113
 * entity bundle, as provided by field_attach_form().
114
 */
115
function views_bulk_operations_modify_action_form($context, &$form_state) {
116
  // This action form uses admin-provided settings. If they were not set, pull the defaults now.
117
  if (!isset($context['settings'])) {
118
    $context['settings'] = views_bulk_operations_modify_action_views_bulk_operations_form_options();
119
  }
120

    
121
  $form_state['entity_type'] = $entity_type = $context['entity_type'];
122
  // For Field API integration to work, a pseudo-entity is constructed for each
123
  // bundle that has fields available for editing.
124
  // The entities then get passed to Field API functions
125
  // (field_attach_form(), field_attach_form_validate(), field_attach_submit()),
126
  // and filled with form data.
127
  // After submit, the pseudo-entities get passed to the actual action
128
  // (views_bulk_operations_modify_action()) which copies the data from the
129
  // relevant pseudo-entity constructed here to the actual entity being modified.
130
  $form_state['entities'] = array();
131

    
132
  $info = entity_get_info($entity_type);
133
  $properties = _views_bulk_operations_modify_action_get_properties($entity_type, $context['settings']['display_values']);
134
  $bundles = _views_bulk_operations_modify_action_get_bundles($entity_type, $context);
135

    
136
  $form['#attached']['css'][] = drupal_get_path('module', 'views_bulk_operations') . '/css/modify.action.css';
137
  $form['#tree'] = TRUE;
138

    
139
  if (!empty($properties)) {
140
    $form['properties'] = array(
141
      '#type' => 'fieldset',
142
      '#title' => t('Properties'),
143
    );
144
    $form['properties']['show_value'] = array(
145
      '#suffix' => '<div class="clearfix"></div>',
146
    );
147

    
148
    foreach ($properties as $key => $property) {
149
      $form['properties']['show_value'][$key] = array(
150
        '#type' => 'checkbox',
151
        '#title' => $property['label'],
152
      );
153

    
154
      $determined_type = ($property['type'] == 'boolean') ? 'checkbox' : 'textfield';
155
      $form['properties'][$key] = array(
156
        '#type' => $determined_type,
157
        '#title' => $property['label'],
158
        '#description' => $property['description'],
159
        '#states' => array(
160
          'visible' => array(
161
            '#edit-properties-show-value-' . str_replace('_', '-', $key) => array('checked' => TRUE),
162
          ),
163
        ),
164
      );
165
      // The default #maxlength for textfields is 128, while most varchar
166
      // columns hold 255 characters, which makes it a saner default here.
167
      if ($determined_type == 'textfield') {
168
        $form['properties'][$key]['#maxlength'] = 255;
169
      }
170

    
171
      if (!empty($property['options list'])) {
172
        $form['properties'][$key]['#type'] = 'select';
173
        $form['properties'][$key]['#options'] = $property['options list']($key, array());
174

    
175
        if ($property['type'] == 'list') {
176
          $form['properties'][$key]['#type'] = 'checkboxes';
177

    
178
          $form['properties']['_append::' . $key] = array(
179
            '#type' => 'checkbox',
180
            '#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array('%label' => $property['label'])),
181
            '#states' => array(
182
              'visible' => array(
183
                '#edit-properties-show-value-' . $key => array('checked' => TRUE),
184
              ),
185
            ),
186
          );
187
        }
188
      }
189
    }
190
  }
191

    
192
  // Going to need this for multilingual nodes
193
  global $language;
194
  foreach ($bundles as $bundle_name => $bundle) {
195
    $bundle_key = $info['entity keys']['bundle'];
196
    $default_values = array();
197
    // If the bundle key exists, it must always be set on an entity.
198
    if (!empty($bundle_key)) {
199
      $default_values[$bundle_key] = $bundle_name;
200
    }
201
    $default_values['language'] = $language->language;
202
    $entity = entity_create($context['entity_type'], $default_values);
203
    $form_state['entities'][$bundle_name] = $entity;
204

    
205
    // Show the more detailed label only if the entity type has multiple bundles.
206
    // Otherwise, it would just be confusing.
207
    if (count($info['bundles']) > 1) {
208
      $label = t('Fields for @bundle_key @label', array('@bundle_key' => $bundle_key, '@label' => $bundle['label']));
209
    }
210
    else {
211
      $label = t('Fields');
212
    }
213

    
214
    $form_key = 'bundle_' . $bundle_name;
215
    $form[$form_key] = array(
216
      '#type' => 'fieldset',
217
      '#title' => $label,
218
      '#parents' => array($form_key),
219
    );
220
    field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, entity_language($context['entity_type'], $entity));
221
    // Now that all the widgets have been added, sort them by #weight.
222
    // This ensures that they will stay in the correct order when they get
223
    // assigned new weights.
224
    uasort($form[$form_key], 'element_sort');
225

    
226
    $display_values = $context['settings']['display_values'];
227
    $instances = field_info_instances($entity_type, $bundle_name);
228
    $weight = 0;
229
    foreach (element_get_visible_children($form[$form_key]) as $field_name) {
230
      // For our use case it makes no sense for any field widget to be required.
231
      if (isset($form[$form_key][$field_name]['#language'])) {
232
        $field_language = $form[$form_key][$field_name]['#language'];
233
        _views_bulk_operations_modify_action_unset_required($form[$form_key][$field_name][$field_language]);
234
      }
235

    
236
      // The admin has specified which fields to display, but this field didn't
237
      // make the cut. Hide it with #access => FALSE and move on.
238
      if (empty($display_values[VBO_MODIFY_ACTION_ALL]) && empty($display_values[$bundle_name . '::' . $field_name])) {
239
        $form[$form_key][$field_name]['#access'] = FALSE;
240
        continue;
241
      }
242

    
243
      if (isset($instances[$field_name])) {
244
        $field = $instances[$field_name];
245
        $form[$form_key]['show_value'][$field_name] = array(
246
          '#type' => 'checkbox',
247
          '#title' => $field['label'],
248
        );
249
        $form[$form_key][$field_name]['#states'] = array(
250
          'visible' => array(
251
            '#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
252
          ),
253
        );
254
        // All field widgets get reassigned weights so that additional elements
255
        // added between them (such as "_append") can be properly ordered.
256
        $form[$form_key][$field_name]['#weight'] = $weight++;
257

    
258
        $field_info = field_info_field($field_name);
259
        if ($field_info['cardinality'] != 1) {
260
          $form[$form_key]['_append::' . $field_name] = array(
261
            '#type' => 'checkbox',
262
            '#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array('%label' => $field['label'])),
263
            '#states' => array(
264
              'visible' => array(
265
                '#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
266
              ),
267
            ),
268
            '#weight' => $weight++,
269
          );
270
        }
271
      }
272
    }
273

    
274
    // Add a clearfix below the checkboxes so that the widgets are not floated.
275
    $form[$form_key]['show_value']['#suffix'] = '<div class="clearfix"></div>';
276
    $form[$form_key]['show_value']['#weight'] = -1;
277
  }
278

    
279
  // If the form has only one group (for example, "Properties"), remove the
280
  // title and the fieldset, since there's no need to visually group values.
281
  $form_elements = element_get_visible_children($form);
282
  if (count($form_elements) == 1) {
283
    $element_key = reset($form_elements);
284
    unset($form[$element_key]['#type']);
285
    unset($form[$element_key]['#title']);
286

    
287
    // Get a list of all elements in the group, and filter out the non-values.
288
    $values = element_get_visible_children($form[$element_key]);
289
    foreach ($values as $index => $key) {
290
      if ($key == 'show_value' || substr($key, 0, 1) == '_') {
291
        unset($values[$index]);
292
      }
293
    }
294
    // If the group has only one value, no need to hide it through #states.
295
    if (count($values) == 1) {
296
      $value_key = reset($values);
297
      $form[$element_key]['show_value'][$value_key]['#type'] = 'value';
298
      $form[$element_key]['show_value'][$value_key]['#value'] = TRUE;
299
    }
300
  }
301

    
302
  if (module_exists('token') && $context['settings']['show_all_tokens']) {
303
    $token_type = str_replace('_', '-', $entity_type);
304
    $form['tokens'] = array(
305
      '#type' => 'fieldset',
306
      '#title' => t('Available tokens'),
307
      '#collapsible' => TRUE,
308
      '#collapsed' => TRUE,
309
      '#weight' => 998,
310
    );
311
    $form['tokens']['tree'] = array(
312
      '#theme' => 'token_tree',
313
      '#token_types' => array($token_type, 'site'),
314
      '#global_types' => array(),
315
      '#dialog' => TRUE,
316
    );
317
  }
318

    
319
  return $form;
320
}
321

    
322
/**
323
 * Action form validate function.
324
 *
325
 * Checks that the user selected at least one value to modify, validates
326
 * properties and calls Field API to validate fields for each bundle.
327
 */
328
function views_bulk_operations_modify_action_validate($form, &$form_state) {
329
  // The form structure for "Show" checkboxes is a bit bumpy.
330
  $search = array('properties');
331
  foreach ($form_state['entities'] as $bundle => $entity) {
332
    $search[] = 'bundle_' . $bundle;
333
  }
334

    
335
  $has_selected = FALSE;
336
  foreach ($search as $group) {
337
    // Store names of selected and appended entity values in a nicer format.
338
    $form_state['selected'][$group] = array();
339
    $form_state['append'][$group] = array();
340

    
341
    // This group has no values, move on.
342
    if (!isset($form_state['values'][$group])) {
343
      continue;
344
    }
345

    
346
    foreach ($form_state['values'][$group]['show_value'] as $key => $value) {
347
      if ($value) {
348
        $has_selected = TRUE;
349
        $form_state['selected'][$group][] = $key;
350
      }
351
      if (!empty($form_state['values'][$group]['_append::' . $key])) {
352
        $form_state['append'][$group][] = $key;
353
        unset($form_state['values'][$group]['_append::' . $key]);
354
      }
355
    }
356
    unset($form_state['values'][$group]['show_value']);
357
  }
358

    
359
  if (!$has_selected) {
360
    form_set_error('', t('You must select at least one value to modify.'));
361
    return;
362
  }
363

    
364
  // Use the wrapper to validate property values.
365
  if (!empty($form_state['selected']['properties'])) {
366
    // The entity used is irrelevant, and we can't rely on
367
    // $form_state['entities'] being non-empty, so a new one is created.
368
    $info = entity_get_info($form_state['entity_type']);
369
    $bundle_key = $info['entity keys']['bundle'];
370
    $default_values = array();
371
    // If the bundle key exists, it must always be set on an entity.
372
    if (!empty($bundle_key)) {
373
      $bundle_names = array_keys($info['bundles']);
374
      $bundle_name = reset($bundle_names);
375
      $default_values[$bundle_key] = $bundle_name;
376
    }
377
    $entity = entity_create($form_state['entity_type'], $default_values);
378
    $wrapper = entity_metadata_wrapper($form_state['entity_type'], $entity);
379

    
380
    $properties = _views_bulk_operations_modify_action_get_properties($form_state['entity_type']);
381
    foreach ($form_state['selected']['properties'] as $key) {
382
      $value = $form_state['values']['properties'][$key];
383
      if (!$wrapper->$key->validate($value)) {
384
        $label = $properties[$key]['label'];
385
        form_set_error('properties][' . $key, t('%label contains an invalid value.', array('%label' => $label)));
386
      }
387
    }
388
  }
389

    
390
  foreach ($form_state['entities'] as $bundle_name => $entity) {
391
    field_attach_form_validate($form_state['entity_type'], $entity, $form['bundle_' . $bundle_name], $form_state);
392
  }
393
}
394

    
395
/**
396
 * Action form submit function.
397
 *
398
 * Fills each constructed entity with property and field values, then
399
 * passes them to views_bulk_operations_modify_action().
400
 */
401
function views_bulk_operations_modify_action_submit($form, $form_state) {
402
  foreach ($form_state['entities'] as $bundle_name => $entity) {
403
    field_attach_submit($form_state['entity_type'], $entity, $form['bundle_' . $bundle_name], $form_state);
404
  }
405

    
406
  return array(
407
    'append' => $form_state['append'],
408
    'selected' => $form_state['selected'],
409
    'entities' => $form_state['entities'],
410
    'properties' => isset($form_state['values']['properties']) ? $form_state['values']['properties'] : array(),
411
  );
412
}
413

    
414
/**
415
 * Returns all properties that can be modified.
416
 *
417
 * Properties that can't be changed are entity keys, timestamps, and the ones
418
 * without a setter callback.
419
 *
420
 * @param $entity_type
421
 *   The entity type whose properties will be fetched.
422
 * @param $display_values
423
 *   An optional, admin-provided list of properties and fields that should be
424
 *   displayed for editing, used to filter the returned list of properties.
425
 */
426
function _views_bulk_operations_modify_action_get_properties($entity_type, $display_values = NULL) {
427
  $properties = array();
428
  $info = entity_get_info($entity_type);
429

    
430
  // List of properties that can't be modified.
431
  $disabled_properties = array('created', 'changed');
432
  foreach (array('id', 'bundle', 'revision') as $key) {
433
    if (!empty($info['entity keys'][$key])) {
434
      $disabled_properties[] = $info['entity keys'][$key];
435
    }
436
  }
437
  // List of supported types.
438
  $supported_types = array('text', 'token', 'integer', 'decimal', 'date', 'duration',
439
                           'boolean', 'uri', 'list');
440
  $property_info = entity_get_property_info($entity_type);
441
  if (empty($property_info['properties'])) {
442
    // Stop here if no properties were found.
443
    return array();
444
  }
445

    
446
  foreach ($property_info['properties'] as $key => $property) {
447
    if (in_array($key, $disabled_properties)) {
448
      continue;
449
    }
450
    // Filter out properties that can't be set (they are usually generated by a
451
    // getter callback based on other properties, and not stored in the DB).
452
    if (empty($property['setter callback'])) {
453
      continue;
454
    }
455
    // Determine the property type. If it's empty (permitted), default to text.
456
    // If it's a list type such as list<boolean>, extract the "boolean" part.
457
    $property['type'] = empty($property['type']) ? 'text' : $property['type'];
458
    $type = $property['type'];
459
    if ($list_type = entity_property_list_extract_type($type)) {
460
      $type = $list_type;
461
      $property['type'] = 'list';
462
    }
463
    // Filter out non-supported types (such as the Field API fields that
464
    // Commerce adds to its entities so that they show up in tokens).
465
    if (!in_array($type, $supported_types)) {
466
      continue;
467
    }
468

    
469
    $properties[$key] = $property;
470
  }
471

    
472
  if (isset($display_values) && empty($display_values[VBO_MODIFY_ACTION_ALL])) {
473
    // Return only the properties that the admin specified.
474
    return array_intersect_key($properties, $display_values);
475
  }
476

    
477
  return $properties;
478
}
479

    
480
/**
481
 * Returns all bundles for which field widgets should be displayed.
482
 *
483
 * If the admin decided to limit the modify form to certain properties / fields
484
 * (through the action settings) then only bundles that have at least one field
485
 * selected are returned.
486
 *
487
 * @param $entity_type
488
 *   The entity type whose bundles will be fetched.
489
 * @param $context
490
 *   The VBO context variable.
491
 */
492
function _views_bulk_operations_modify_action_get_bundles($entity_type, $context) {
493
  $bundles = array();
494

    
495
  $view = $context['view'];
496
  $vbo = _views_bulk_operations_get_field($view);
497
  $display_values = $context['settings']['display_values'];
498
  $info = entity_get_info($entity_type);
499
  $bundle_key = $info['entity keys']['bundle'];
500

    
501
  // Check if this View has a filter on the bundle key and assemble a list
502
  // of allowed bundles according to the filter.
503
  $filtered_bundles = array_keys($info['bundles']);
504

    
505
  // Go over all the filters and find any relevant ones.
506
  foreach ($view->filter as $key => $filter) {
507
    // Check it's the right field on the right table.
508
    if ($filter->table == $vbo->table && $filter->field == $bundle_key) {
509
      // Exposed filters may have no bundles, so check that there is a value.
510
      if (empty($filter->value)) {
511
        continue;
512
      }
513

    
514
      $operator = $filter->operator;
515
      if ($operator == 'in') {
516
        $filtered_bundles = array_intersect($filtered_bundles, $filter->value);
517
      }
518
      elseif ($operator == 'not in') {
519
        $filtered_bundles = array_diff($filtered_bundles, $filter->value);
520
      }
521
    }
522
  }
523

    
524
  foreach ($info['bundles'] as $bundle_name => $bundle) {
525
    // The view is limited to specific bundles, but this bundle isn't one of
526
    // them. Ignore it.
527
    if (!in_array($bundle_name, $filtered_bundles)) {
528
      continue;
529
    }
530

    
531
    $instances = field_info_instances($entity_type, $bundle_name);
532
    // Ignore bundles that don't have any field instances attached.
533
    if (empty($instances)) {
534
      continue;
535
    }
536

    
537
    $has_enabled_fields = FALSE;
538
    foreach ($display_values as $key) {
539
      if (strpos($key, $bundle_name . '::') !== FALSE) {
540
        $has_enabled_fields = TRUE;
541
      }
542
    }
543
    // The admin has either specified that all values should be modifiable, or
544
    // selected at least one field belonging to this bundle.
545
    if (!empty($display_values[VBO_MODIFY_ACTION_ALL]) || $has_enabled_fields) {
546
      $bundles[$bundle_name] = $bundle;
547
    }
548
  }
549

    
550
  return $bundles;
551
}
552

    
553
/**
554
 * Helper function that recursively strips #required from field widgets.
555
 */
556
function _views_bulk_operations_modify_action_unset_required(&$element) {
557
  unset($element['#required']);
558
  foreach (element_children($element) as $key) {
559
    _views_bulk_operations_modify_action_unset_required($element[$key]);
560
  }
561
}
562

    
563
/**
564
 * VBO settings form function.
565
 */
566
function views_bulk_operations_modify_action_views_bulk_operations_form_options() {
567
  $options['show_all_tokens'] = TRUE;
568
  $options['display_values'] = array(VBO_MODIFY_ACTION_ALL);
569
  return $options;
570
}
571

    
572
/**
573
 * The settings form for this action.
574
 */
575
function views_bulk_operations_modify_action_views_bulk_operations_form($options, $entity_type, $dom_id) {
576
  // Initialize default values.
577
  if (empty($options)) {
578
    $options = views_bulk_operations_modify_action_views_bulk_operations_form_options();
579
  }
580

    
581
  $form['show_all_tokens'] = array(
582
    '#type' => 'checkbox',
583
    '#title' => t('Show available tokens'),
584
    '#description' => t('Check this to show a list of all available tokens in the bottom of the form. Requires the token module.'),
585
    '#default_value' => $options['show_all_tokens'],
586
  );
587

    
588
  $info = entity_get_info($entity_type);
589
  $properties = _views_bulk_operations_modify_action_get_properties($entity_type);
590
  $values = array(VBO_MODIFY_ACTION_ALL => t('- All -'));
591
  foreach ($properties as $key => $property) {
592
    $label = t('Properties');
593
    $values[$label][$key] = $property['label'];
594
  }
595
  foreach ($info['bundles'] as $bundle_name => $bundle) {
596
    $bundle_key = $info['entity keys']['bundle'];
597
    // Show the more detailed label only if the entity type has multiple bundles.
598
    // Otherwise, it would just be confusing.
599
    if (count($info['bundles']) > 1) {
600
      $label = t('Fields for @bundle_key @label', array('@bundle_key' => $bundle_key, '@label' => $bundle['label']));
601
    }
602
    else {
603
      $label = t('Fields');
604
    }
605

    
606
    $instances = field_info_instances($entity_type, $bundle_name);
607
    foreach ($instances as $field_name => $field) {
608
      $values[$label][$bundle_name . '::' . $field_name] = $field['label'];
609
    }
610
  }
611

    
612
  $form['display_values'] = array(
613
    '#type' => 'select',
614
    '#title' => t('Display values'),
615
    '#options' => $values,
616
    '#multiple' => TRUE,
617
    '#description' => t('Select which values the action form should present to the user.'),
618
    '#default_value' => $options['display_values'],
619
    '#size' => 10,
620
  );
621
  return $form;
622
}