field.api.php 93.1 KB
Newer Older
1
2
3
4
5
6
7
<?php

/**
 * @ingroup field_fieldable_type
 * @{
 */

8
/**
9
 * Exposes "pseudo-field" components on fieldable entities.
10
 *
11
12
13
 * Field UI's "Manage fields" and "Manage display" pages let users re-order
 * fields, but also non-field components. For nodes, these include the title,
 * poll choices, and other elements exposed by modules through hook_form() or
14
15
 * hook_form_alter().
 *
16
17
 * Fieldable entities or modules that want to have their components supported
 * should expose them using this hook. The user-defined settings (weight,
18
 * visible) are automatically applied on rendered forms and displayed
19
20
21
22
23
 * entities in a #pre_render callback added by field_attach_form() and
 * field_attach_view().
 *
 * @see _field_extra_fields_pre_render()
 * @see hook_field_extra_fields_alter()
24
 *
25
 * @return
26
27
28
29
30
 *   A nested array of 'pseudo-field' components. Each list is nested within
 *   the following keys: entity type, bundle name, context (either 'form' or
 *   'display'). The keys are the name of the elements as appearing in the
 *   renderable array (either the entity form or the displayed entity). The
 *   value is an associative array:
31
32
33
34
 *   - label: The human readable name of the component.
 *   - description: A short description of the component contents.
 *   - weight: The default weight of the element.
 */
35
function hook_field_extra_fields() {
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  $extra['node']['poll'] = array(
    'form' => array(
      'choice_wrapper' => array(
        'label' => t('Poll choices'),
        'description' => t('Poll choices'),
        'weight' => -4,
      ),
      'settings' => array(
        'label' => t('Poll settings'),
        'description' => t('Poll module settings'),
        'weight' => -3,
      ),
    ),
    'display' => array(
      'poll_view_voting' => array(
        'label' => t('Poll vote'),
        'description' => t('Poll vote'),
        'weight' => 0,
      ),
      'poll_view_results' => array(
        'label' => t('Poll results'),
        'description' => t('Poll results'),
        'weight' => 0,
      ),
    )
  );
62

63
64
65
  return $extra;
}

66
67
68
69
70
71
72
73
74
/**
 * Alter "pseudo-field" components on fieldable entities.
 *
 * @param $info
 *   The associative array of 'pseudo-field' components.
 *
 * @see hook_field_extra_fields()
 */
function hook_field_extra_fields_alter(&$info) {
75
  // Force node title to always be at the top of the list by default.
76
  foreach (node_type_get_types() as $bundle) {
77
78
    if (isset($info['node'][$bundle->type]['form']['title'])) {
      $info['node'][$bundle->type]['form']['title']['weight'] = -20;
79
    }
80
81
82
  }
}

83
84
85
86
87
88
89
/**
 * @} End of "ingroup field_fieldable_type"
 */

/**
 * @defgroup field_types Field Types API
 * @{
90
 * Define field types, widget types, display formatter types, storage types.
91
 *
92
 * The bulk of the Field Types API are related to field types. A field type
93
 * represents a particular type of data (integer, string, date, etc.) that
94
 * can be attached to a fieldable entity. hook_field_info() defines the basic
95
96
 * properties of a field type, and a variety of other field hooks are called by
 * the Field Attach API to perform field-type-specific actions.
97
 *
98
99
100
101
102
103
104
105
106
107
108
109
 * @see hook_field_info()
 * @see hook_field_info_alter()
 * @see hook_field_schema()
 * @see hook_field_load()
 * @see hook_field_validate()
 * @see hook_field_presave()
 * @see hook_field_insert()
 * @see hook_field_update()
 * @see hook_field_delete()
 * @see hook_field_delete_revision()
 * @see hook_field_prepare_view()
 * @see hook_field_is_empty()
110
111
112
 *
 * The Field Types API also defines two kinds of pluggable handlers: widgets
 * and formatters, which specify how the field appears in edit forms and in
113
 * displayed entities. Widgets and formatters can be implemented by a field-type
114
 * module for its own field types, or by a third-party module to extend the
115
 * behavior of existing field types.
116
 *
117
118
 * @see hook_field_widget_info()
 * @see hook_field_formatter_info()
119
120
121
 *
 * A third kind of pluggable handlers, storage backends, is defined by the
 * @link field_storage Field Storage API @endlink.
122
123
124
125
126
127
 */

/**
 * Define Field API field types.
 *
 * @return
128
129
130
131
132
133
134
135
136
 *   An array whose keys are field type names and whose values are arrays
 *   describing the field type, with the following key/value pairs:
 *   - label: The human-readable name of the field type.
 *   - description: A short description for the field type.
 *   - settings: An array whose keys are the names of the settings available
 *     for the field type, and whose values are the default values for those
 *     settings.
 *   - instance_settings: An array whose keys are the names of the settings
 *     available for instances of the field type, and whose values are the
137
138
139
140
141
142
 *     default values for those settings. Instance-level settings can have
 *     different values on each field instance, and thus allow greater
 *     flexibility than field-level settings. It is recommended to put settings
 *     at the instance level whenever possible. Notable exceptions: settings
 *     acting on the schema definition, or settings that Views needs to use
 *     across field instances (for example, the list of allowed values).
143
144
145
146
147
148
149
150
151
152
 *   - default_widget: The machine name of the default widget to be used by
 *     instances of this field type, when no widget is specified in the
 *     instance definition. This widget must be available whenever the field
 *     type is available (i.e. provided by the field type module, or by a module
 *     the field type module depends on).
 *   - default_formatter: The machine name of the default formatter to be used
 *     by instances of this field type, when no formatter is specified in the
 *     instance definition. This formatter must be available whenever the field
 *     type is available (i.e. provided by the field type module, or by a module
 *     the field type module depends on).
153
154
155
156
 *   - no_ui: (optional) A boolean specifying that users should not be allowed
 *     to create fields and instances of this field type through the UI. Such
 *     fields can only be created programmatically with field_create_field()
 *     and field_create_instance(). Defaults to FALSE.
157
158
 *
 * @see hook_field_info_alter()
159
160
161
162
163
164
165
166
167
168
169
 */
function hook_field_info() {
  return array(
    'text' => array(
      'label' => t('Text'),
      'description' => t('This field stores varchar text in the database.'),
      'settings' => array('max_length' => 255),
      'instance_settings' => array('text_processing' => 0),
      'default_widget' => 'text_textfield',
      'default_formatter' => 'text_default',
    ),
170
171
    'text_long' => array(
      'label' => t('Long text'),
172
      'description' => t('This field stores long text in the database.'),
173
      'settings' => array('max_length' => ''),
174
175
176
177
      'instance_settings' => array('text_processing' => 0),
      'default_widget' => 'text_textarea',
      'default_formatter' => 'text_default',
    ),
178
179
180
181
182
183
184
185
    'text_with_summary' => array(
      'label' => t('Long text and summary'),
      'description' => t('This field stores long text in the database along with optional summary text.'),
      'settings' => array('max_length' => ''),
      'instance_settings' => array('text_processing' => 1, 'display_summary' => 0),
      'default_widget' => 'text_textarea_with_summary',
      'default_formatter' => 'text_summary_or_trimmed',
    ),
186
187
188
  );
}

189
190
191
192
/**
 * Perform alterations on Field API field types.
 *
 * @param $info
193
 *   Array of information on field types exposed by hook_field_info()
194
195
196
197
198
 *   implementations.
 */
function hook_field_info_alter(&$info) {
  // Add a setting to all field types.
  foreach ($info as $field_type => $field_type_info) {
199
200
201
    $info[$field_type]['settings'] += array(
      'mymodule_additional_setting' => 'default value',
    );
202
203
204
205
206
207
208
209
  }

  // Change the default widget for fields of type 'foo'.
  if (isset($info['foo'])) {
    $info['foo']['default widget'] = 'mymodule_widget';
  }
}

210
211
212
/**
 * Define the Field API schema for a field structure.
 *
213
214
215
 * This hook MUST be defined in .install for it to be detected during
 * installation and upgrade.
 *
216
217
 * @param $field
 *   A field structure.
218
 *
219
 * @return
220
 *   An associative array with the following keys:
221
222
223
224
225
226
227
228
 *   - columns: An array of Schema API column specifications, keyed by column
 *     name. This specifies what comprises a value for a given field. For
 *     example, a value for a number field is simply 'value', while a value for
 *     a formatted text field is the combination of 'value' and 'format'. It is
 *     recommended to avoid having the column definitions depend on field
 *     settings when possible. No assumptions should be made on how storage
 *     engines internally use the original column name to structure their
 *     storage.
229
230
231
232
233
234
235
236
 *   - indexes: (optional) An array of Schema API indexes definitions. Only
 *     columns that appear in the 'columns' array are allowed. Those indexes
 *     will be used as default indexes. Callers of field_create_field() can
 *     specify additional indexes, or, at their own risk, modify the default
 *     indexes specified by the field-type module. Some storage engines might
 *     not support indexes.
 *   - foreign keys: (optional) An array of Schema API foreign keys
 *     definitions.
237
 */
238
239
function hook_field_schema($field) {
  if ($field['type'] == 'text_long') {
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    $columns = array(
      'value' => array(
        'type' => 'text',
        'size' => 'big',
        'not null' => FALSE,
      ),
    );
  }
  else {
    $columns = array(
      'value' => array(
        'type' => 'varchar',
        'length' => $field['settings']['max_length'],
        'not null' => FALSE,
      ),
    );
  }
  $columns += array(
    'format' => array(
259
260
      'type' => 'varchar',
      'length' => 255,
261
262
263
      'not null' => FALSE,
    ),
  );
264
265
266
267
268
  return array(
    'columns' => $columns,
    'indexes' => array(
      'format' => array('format'),
    ),
269
270
271
272
273
274
    'foreign keys' => array(
      'format' => array(
        'table' => 'filter_format',
        'columns' => array('format' => 'format'),
      ),
    ),
275
  );
276
277
278
}

/**
279
 * Define custom load behavior for this module's field types.
280
 *
281
 * Unlike most other field hooks, this hook operates on multiple entities. The
282
 * $entities, $instances and $items parameters are arrays keyed by entity ID.
283
 * For performance reasons, information for all available entity should be
284
285
 * loaded in a single query where possible.
 *
286
287
288
289
290
 * Note that the changes made to the field values get cached by the field cache
 * for subsequent loads. You should never use this hook to load fieldable
 * entities, since this is likely to cause infinite recursions when
 * hook_field_load() is run on those as well. Use
 * hook_field_formatter_prepare_view() instead.
291
 *
292
293
294
 * Make changes or additions to field values by altering the $items parameter by
 * reference. There is no return value.
 *
295
296
297
 * @param $entity_type
 *   The type of $entity.
 * @param $entities
298
 *   Array of entities being loaded, keyed by entity ID.
299
300
 * @param $field
 *   The field structure for the operation.
301
 * @param $instances
302
 *   Array of instance structures for $field for each entity, keyed by entity
303
 *   ID.
304
 * @param $langcode
305
 *   The language code associated with $items.
306
 * @param $items
307
308
 *   Array of field values already loaded for the entities, keyed by entity ID.
 *   Store your changes in this parameter (passed by reference).
309
310
 * @param $age
 *   FIELD_LOAD_CURRENT to load the most recent revision for all fields, or
311
 *   FIELD_LOAD_REVISION to load the version indicated by each entity.
312
 */
313
function hook_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
314
315
  // Sample code from text.module: precompute sanitized strings so they are
  // stored in the field cache.
316
  foreach ($entities as $id => $entity) {
317
    foreach ($items[$id] as $delta => $item) {
318
319
320
321
      // Only process items with a cacheable format, the rest will be handled
      // by formatters if needed.
      if (empty($instances[$id]['settings']['text_processing']) || filter_format_allowcache($item['format'])) {
        $items[$id][$delta]['safe_value'] = isset($item['value']) ? _text_sanitize($instances[$id], $langcode, $item, 'value') : '';
322
        if ($field['type'] == 'text_with_summary') {
323
          $items[$id][$delta]['safe_summary'] = isset($item['summary']) ? _text_sanitize($instances[$id], $langcode, $item, 'summary') : '';
324
325
326
327
328
329
330
        }
      }
    }
  }
}

/**
331
 * Prepare field values prior to display.
332
 *
333
334
335
336
 * This hook is invoked before the field values are handed to formatters
 * for display, and runs before the formatters' own
 * hook_field_formatter_prepare_view().
 *
337
 * Unlike most other field hooks, this hook operates on multiple entities. The
338
 * $entities, $instances and $items parameters are arrays keyed by entity ID.
339
 * For performance reasons, information for all available entities should be
340
 * loaded in a single query where possible.
341
 *
342
343
344
 * Make changes or additions to field values by altering the $items parameter by
 * reference. There is no return value.
 *
345
346
347
 * @param $entity_type
 *   The type of $entity.
 * @param $entities
348
 *   Array of entities being displayed, keyed by entity ID.
349
350
 * @param $field
 *   The field structure for the operation.
351
 * @param $instances
352
 *   Array of instance structures for $field for each entity, keyed by entity
353
 *   ID.
354
355
 * @param $langcode
 *   The language associated to $items.
356
 * @param $items
357
 *   $entity->{$field['field_name']}, or an empty array if unset.
358
 */
359
function hook_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
360
  // Sample code from image.module: if there are no images specified at all,
361
  // use the default image.
362
  foreach ($entities as $id => $entity) {
363
364
365
366
367
368
369
    if (empty($items[$id]) && $field['settings']['default_image']) {
      if ($file = file_load($field['settings']['default_image'])) {
        $items[$id][0] = (array) $file + array(
          'is_default' => TRUE,
          'alt' => '',
          'title' => '',
        );
370
371
372
      }
    }
  }
373
374
375
}

/**
376
377
378
379
 * Validate this module's field data.
 *
 * If there are validation problems, add to the $errors array (passed by
 * reference). There is no return value.
380
 *
381
382
383
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
384
 *   The entity for the operation.
385
386
387
 * @param $field
 *   The field structure for the operation.
 * @param $instance
388
 *   The instance structure for $field on $entity's bundle.
389
 * @param $langcode
390
 *   The language associated with $items.
391
 * @param $items
392
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
393
 * @param $errors
394
395
396
 *   The array of errors (keyed by field name, language code, and delta) that
 *   have already been reported for the entity. The function should add its
 *   errors to this array. Each error is an associative array with the following
397
 *   keys and values:
398
 *   - error: An error code (should be a string prefixed with the module name).
399
 *   - message: The human readable message to be displayed.
400
 */
401
function hook_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
402
403
404
  foreach ($items as $delta => $item) {
    if (!empty($item['value'])) {
      if (!empty($field['settings']['max_length']) && drupal_strlen($item['value']) > $field['settings']['max_length']) {
405
        $errors[$field['field_name']][$langcode][$delta][] = array(
406
407
408
409
410
411
          'error' => 'text_max_length',
          'message' => t('%name: the value may not be longer than %max characters.', array('%name' => $instance['label'], '%max' => $field['settings']['max_length'])),
        );
      }
    }
  }
412
413
414
415
}

/**
 * Define custom presave behavior for this module's field types.
416
 *
417
418
419
 * Make changes or additions to field values by altering the $items parameter by
 * reference. There is no return value.
 *
420
421
422
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
423
 *   The entity for the operation.
424
425
426
 * @param $field
 *   The field structure for the operation.
 * @param $instance
427
 *   The instance structure for $field on $entity's bundle.
428
 * @param $langcode
429
 *   The language associated with $items.
430
 * @param $items
431
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
432
 */
433
function hook_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
434
435
436
437
438
439
440
441
442
  if ($field['type'] == 'number_decimal') {
    // Let PHP round the value to ensure consistent behavior across storage
    // backends.
    foreach ($items as $delta => $item) {
      if (isset($item['value'])) {
        $items[$delta]['value'] = round($item['value'], $field['settings']['scale']);
      }
    }
  }
443
444
445
446
447
}

/**
 * Define custom insert behavior for this module's field types.
 *
448
449
 * Invoked from field_attach_insert().
 *
450
451
452
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
453
 *   The entity for the operation.
454
455
456
 * @param $field
 *   The field structure for the operation.
 * @param $instance
457
 *   The instance structure for $field on $entity's bundle.
458
 * @param $langcode
459
 *   The language associated with $items.
460
 * @param $items
461
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
462
 */
463
function hook_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
464
465
466
467
468
469
470
471
472
473
474
475
  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node' && $entity->status) {
    $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', ));
    foreach ($items as $item) {
      $query->values(array(
        'nid' => $entity->nid,
        'tid' => $item['tid'],
        'sticky' => $entity->sticky,
        'created' => $entity->created,
      ));
    }
    $query->execute();
  }
476
477
478
479
480
}

/**
 * Define custom update behavior for this module's field types.
 *
481
482
 * Invoked from field_attach_update().
 *
483
484
485
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
486
 *   The entity for the operation.
487
488
489
 * @param $field
 *   The field structure for the operation.
 * @param $instance
490
 *   The instance structure for $field on $entity's bundle.
491
 * @param $langcode
492
 *   The language associated with $items.
493
 * @param $items
494
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
495
 */
496
function hook_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node') {
    $first_call = &drupal_static(__FUNCTION__, array());

    // We don't maintain data for old revisions, so clear all previous values
    // from the table. Since this hook runs once per field, per object, make
    // sure we only wipe values once.
    if (!isset($first_call[$entity->nid])) {
      $first_call[$entity->nid] = FALSE;
      db_delete('taxonomy_index')->condition('nid', $entity->nid)->execute();
    }
    // Only save data to the table if the node is published.
    if ($entity->status) {
      $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created'));
      foreach ($items as $item) {
        $query->values(array(
          'nid' => $entity->nid,
          'tid' => $item['tid'],
          'sticky' => $entity->sticky,
          'created' => $entity->created,
        ));
      }
      $query->execute();
    }
  }
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
557
558
/**
 * Update the storage information for a field.
 *
 * This is invoked on the field's storage module from field_update_field(),
 * before the new field information is saved to the database. The field storage
 * module should update its storage tables to agree with the new field
 * information. If there is a problem, the field storage module should throw an
 * exception.
 *
 * @param $field
 *   The updated field structure to be saved.
 * @param $prior_field
 *   The previously-saved field structure.
 * @param $has_data
 *   TRUE if the field has data in storage currently.
 */
function hook_field_storage_update_field($field, $prior_field, $has_data) {
  if (!$has_data) {
    // There is no data. Re-create the tables completely.
    $prior_schema = _field_sql_storage_schema($prior_field);
    foreach ($prior_schema as $name => $table) {
      db_drop_table($name, $table);
    }
    $schema = _field_sql_storage_schema($field);
    foreach ($schema as $name => $table) {
      db_create_table($name, $table);
    }
  }
  else {
    // There is data. See field_sql_storage_field_storage_update_field() for
    // an example of what to do to modify the schema in place, preserving the
    // old data as much as possible.
  }
  drupal_get_schema(NULL, TRUE);
}

559
/**
560
 * Define custom delete behavior for this module's field types.
561
 *
562
563
 * This hook is invoked just before the data is deleted from field storage
 * in field_attach_delete().
564
 *
565
566
567
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
568
 *   The entity for the operation.
569
570
571
 * @param $field
 *   The field structure for the operation.
 * @param $instance
572
 *   The instance structure for $field on $entity's bundle.
573
 * @param $langcode
574
 *   The language associated with $items.
575
 * @param $items
576
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
577
 */
578
function hook_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
579
580
581
582
583
584
585
586
587
588
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  foreach ($items as $delta => $item) {
    // For hook_file_references(), remember that this is being deleted.
    $item['file_field_name'] = $field['field_name'];
    // Pass in the ID of the object that is being removed so all references can
    // be counted in hook_file_references().
    $item['file_field_type'] = $entity_type;
    $item['file_field_id'] = $id;
    file_field_delete_file($item, $field);
  }
589
590
591
}

/**
592
 * Define custom revision delete behavior for this module's field types.
593
 *
594
595
596
 * This hook is invoked just before the data is deleted from field storage
 * in field_attach_delete_revision(), and will only be called for fieldable
 * types that are versioned.
597
 *
598
599
600
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
601
 *   The entity for the operation.
602
603
604
 * @param $field
 *   The field structure for the operation.
 * @param $instance
605
 *   The instance structure for $field on $entity's bundle.
606
 * @param $langcode
607
 *   The language associated with $items.
608
 * @param $items
609
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
610
 */
611
function hook_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
612
613
614
615
616
617
618
  foreach ($items as $delta => $item) {
    // For hook_file_references, remember that this file is being deleted.
    $item['file_field_name'] = $field['field_name'];
    if (file_field_delete_file($item, $field)) {
      $items[$delta] = NULL;
    }
  }
619
620
621
}

/**
622
623
 * Define custom prepare_translation behavior for this module's field types.
 *
624
625
626
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
627
 *   The entity for the operation.
628
629
630
 * @param $field
 *   The field structure for the operation.
 * @param $instance
631
 *   The instance structure for $field on $entity's bundle.
632
633
 * @param $langcode
 *   The language associated to $items.
634
 * @param $items
635
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
636
637
638
639
 * @param $source_entity
 *   The source entity from which field values are being copied.
 * @param $source_langcode
 *   The source language from which field values are being copied.
640
 */
641
642
643
644
645
646
647
648
649
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
  // If the translating user is not permitted to use the assigned text format,
  // we must not expose the source values.
  $field_name = $field['field_name'];
  $formats = filter_formats();
  $format_id = $source_entity->{$field_name}[$source_langcode][0]['format'];
  if (!filter_access($formats[$format_id])) {
    $items = array();
  }
650
651
}

652
653
654
655
656
657
658
/**
 * Define what constitutes an empty item for a field type.
 *
 * @param $item
 *   An item that may or may not be empty.
 * @param $field
 *   The field to which $item belongs.
659
 *
660
661
662
663
664
 * @return
 *   TRUE if $field's type considers $item not to contain any data;
 *   FALSE otherwise.
 */
function hook_field_is_empty($item, $field) {
665
  if (empty($item['value']) && (string) $item['value'] !== '0') {
666
667
668
669
670
    return TRUE;
  }
  return FALSE;
}

671
/**
672
 * Expose Field API widget types.
673
 *
674
675
676
 * Widgets are Form API elements with additional processing capabilities.
 * Widget hooks are typically called by the Field Attach API during the
 * creation of the field form structure with field_attach_form().
677
 *
678
679
680
681
682
683
684
685
686
687
688
689
 * @return
 *   An array describing the widget types implemented by the module.
 *   The keys are widget type names. To avoid name clashes, widget type
 *   names should be prefixed with the name of the module that exposes them.
 *   The values are arrays describing the widget type, with the following
 *   key/value pairs:
 *   - label: The human-readable name of the widget type.
 *   - description: A short description for the widget type.
 *   - field types: An array of field types the widget supports.
 *   - settings: An array whose keys are the names of the settings available
 *     for the widget type, and whose values are the default values for those
 *     settings.
690
691
692
693
694
695
696
697
698
699
700
701
702
 *   - behaviors: (optional) An array describing behaviors of the widget, with
 *     the following elements:
 *     - multiple values: One of the following constants:
 *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget allows the input of
 *         one single field value (most common case). The widget will be
 *         repeated for each value input.
 *       - FIELD_BEHAVIOR_CUSTOM: If one single copy of the widget can receive
 *         several field values. Examples: checkboxes, multiple select,
 *         comma-separated textfield.
 *     - default value: One of the following constants:
 *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts default
 *         values.
 *       - FIELD_BEHAVIOR_NONE: if the widget does not support default values.
703
704
705
706
707
708
 *
 * @see hook_field_widget_info_alter()
 * @see hook_field_widget_form()
 * @see hook_field_widget_form_alter()
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
 * @see hook_field_widget_error()
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
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
function hook_field_widget_info() {
    return array(
    'text_textfield' => array(
      'label' => t('Text field'),
      'field types' => array('text'),
      'settings' => array('size' => 60),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
    'text_textarea' => array(
      'label' => t('Text area (multiple rows)'),
      'field types' => array('text_long'),
      'settings' => array('rows' => 5),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
    'text_textarea_with_summary' => array(
      'label' => t('Text area with a summary'),
      'field types' => array('text_with_summary'),
      'settings' => array('rows' => 20, 'summary_rows' => 5),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
  );
}

/**
 * Perform alterations on Field API widget types.
 *
 * @param $info
 *   Array of informations on widget types exposed by hook_field_widget_info()
 *   implementations.
 */
function hook_field_widget_info_alter(&$info) {
  // Add a setting to a widget type.
  $info['text_textfield']['settings'] += array(
    'mymodule_additional_setting' => 'default value',
  );

  // Let a new field type re-use an existing widget.
  $info['options_select']['field types'][] = 'my_field_type';
757
758
759
}

/**
760
 * Return the form for a single field widget.
761
 *
762
 * Field widget form elements should be based on the passed-in $element, which
763
764
 * contains the base form element properties derived from the field
 * configuration.
765
 *
766
767
 * Field API will set the weight, field name and delta values for each form
 * element. If there are multiple values for this field, the Field API will
768
 * invoke this hook as many times as needed.
769
770
 *
 * Note that, depending on the context in which the widget is being included
771
772
773
774
775
 * (regular entity form, field configuration form, advanced search form...),
 * the values for $field and $instance might be different from the "official"
 * definitions returned by field_info_field() and field_info_instance().
 * Examples: mono-value widget even if the field is multi-valued, non-required
 * widget even if the field is 'required'...
776
 *
777
778
779
780
781
782
783
784
785
786
787
 * Therefore, the FAPI element callbacks (such as #process, #element_validate,
 * #value_callback...) used by the widget cannot use the field_info_field()
 * or field_info_instance() functions to retrieve the $field or $instance
 * definitions they should operate on. The field_widget_field() and
 * field_widget_instance() functions should be used instead to fetch the
 * current working definitions from $form_state, where Field API stores them.
 *
 * Alternatively, hook_field_widget_form() can extract the needed specific
 * properties from $field and $instance and set them as ad-hoc
 * $element['#custom'] properties, for later use by its element callbacks.
 *
788
789
 * Other modules may alter the form element provided by this function using
 * hook_field_widget_form_alter().
790
791
 *
 * @param $form
792
793
 *   The form structure where widgets are being attached to. This might be a
 *   full form structure, or a sub-element of a larger form.
794
 * @param $form_state
795
 *   An associative array containing the current state of the form.
796
797
798
799
 * @param $field
 *   The field structure.
 * @param $instance
 *   The field instance.
800
 * @param $langcode
801
 *   The language associated with $items.
802
803
804
805
 * @param $items
 *   Array of default values for this field.
 * @param $delta
 *   The order of this item in the array of subelements (0, 1, 2, etc).
806
 * @param $element
807
 *   A form element array containing basic properties for the widget:
808
 *   - #entity_type: The name of the entity the field is attached to.
809
810
 *   - #bundle: The name of the field bundle the field is contained in.
 *   - #field_name: The name of the field.
811
 *   - #language: The language the field is being edited in.
812
813
814
815
816
817
 *   - #field_parents: The 'parents' space for the field in the form. Most
 *       widgets can simply overlook this property. This identifies the
 *       location where the field values are placed within
 *       $form_state['values'], and is used to access processing information
 *       for the field through the field_form_get_state() and
 *       field_form_set_state() functions.
818
819
820
821
822
823
824
825
826
827
 *   - #columns: A list of field storage columns of the field.
 *   - #title: The sanitized element label for the field instance, ready for
 *     output.
 *   - #description: The sanitized element description for the field instance,
 *     ready for output.
 *   - #required: A Boolean indicating whether the element value is required;
 *     for required multiple value fields, only the first widget's values are
 *     required.
 *   - #delta: The order of this item in the array of subelements; see $delta
 *     above.
828
 *
829
 * @return
830
 *   The form elements for a single widget for this field.
831
832
833
834
835
 *
 * @see field_widget_field()
 * @see field_widget_instance()
 * @see hook_field_widget_form_alter()
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
836
 */
837
function hook_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
838
  $element += array(
839
840
841
842
843
844
    '#type' => $instance['widget']['type'],
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
  );
  return $element;
}

845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
/**
 * Alter forms for field widgets provided by other modules.
 *
 * @param $element
 *   The field widget form element as constructed by hook_field_widget_form().
 * @param $form_state
 *   An associative array containing the current state of the form.
 * @param $context
 *   An associative array containing the following key-value pairs, matching the
 *   arguments received by hook_field_widget_form():
 *   - "form": The form structure where widgets are being attached to. This
 *     might be a full form structure, or a sub-element of a larger form.
 *   - "field": The field structure.
 *   - "instance": The field instance structure.
 *   - "langcode": The language associated with $items.
 *   - "items": Array of default values for this field.
 *   - "delta": The order of this item in the array of subelements (0, 1, 2,
 *     etc).
 *
 * @see hook_field_widget_form()
 * @see hook_field_widget_WIDGET_TYPE_form_alter
 */
function hook_field_widget_form_alter(&$element, &$form_state, $context) {
  // Add a css class to widget form elements for all fields of type mytype.
  if ($context['field']['type'] == 'mytype') {
    // Be sure not to overwrite existing attributes.
    $element['#attributes']['class'][] = 'myclass';
  }
}

/**
 * Alter widget forms for a specific widget provided by another module.
 *
 * Modules can implement hook_field_widget_WIDGET_TYPE_form_alter() to modify a
 * specific widget form, rather than using hook_field_widget_form_alter() and
 * checking the widget type.
 *
 * @param $element
 *   The field widget form element as constructed by hook_field_widget_form().
 * @param $form_state
 *   An associative array containing the current state of the form.
 * @param $context
 *   An associative array containing the following key-value pairs, matching the
 *   arguments received by hook_field_widget_form():
 *   - "form": The form structure where widgets are being attached to. This
 *     might be a full form structure, or a sub-element of a larger form.
 *   - "field": The field structure.
 *   - "instance": The field instance structure.
 *   - "langcode": The language associated with $items.
 *   - "items": Array of default values for this field.
 *   - "delta": The order of this item in the array of subelements (0, 1, 2,
 *     etc).
 *
 * @see hook_field_widget_form()
 * @see hook_field_widget_form_alter()
 */
function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $context) {
  // Code here will only act on widgets of type WIDGET_TYPE.  For example,
  // hook_field_widget_mymodule_autocomplete_form_alter() will only act on
  // widgets of type 'mymodule_autocomplete'.
  $element['#autocomplete_path'] = 'mymodule/autocomplete_path';
}

908
909
910
911
912
913
914
915
916
917
/**
 * Flag a field-level validation error.
 *
 * @param $element
 *   An array containing the form element for the widget. The error needs to be
 *   flagged on the right sub-element, according to the widget's internal
 *   structure.
 * @param $error
 *   An associative array with the following key-value pairs, as returned by
 *   hook_field_validate():
918
 *   - error: the error code. Complex widgets might need to report different
919
 *     errors to different form elements inside the widget.
920
 *   - message: the human readable message to be displayed.
921
 * @param $form
922
923
 *   The form structure where field elements are attached to. This might be a
 *   full form structure, or a sub-element of a larger form.
924
925
 * @param $form_state
 *   An associative array containing the current state of the form.
926
 */
927
function hook_field_widget_error($element, $error, $form, &$form_state) {
928
929
930
  form_error($element['value'], $error['message']);
}

931
932
933
/**
 * Expose Field API formatter types.
 *
934
935
936
 * Formatters handle the display of field values. Formatter hooks are typically
 * called by the Field Attach API field_attach_prepare_view() and
 * field_attach_view() functions.
937
938
939
940
941
942
943
944
945
946
947
948
949
 *
 * @return
 *   An array describing the formatter types implemented by the module.
 *   The keys are formatter type names. To avoid name clashes, formatter type
 *   names should be prefixed with the name of the module that exposes them.
 *   The values are arrays describing the formatter type, with the following
 *   key/value pairs:
 *   - label: The human-readable name of the formatter type.
 *   - description: A short description for the formatter type.
 *   - field types: An array of field types the formatter supports.
 *   - settings: An array whose keys are the names of the settings available
 *     for the formatter type, and whose values are the default values for
 *     those settings.
950
951
952
953
 *
 * @see hook_field_formatter_info_alter()
 * @see hook_field_formatter_view()
 * @see hook_field_formatter_prepare_view()
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
 */
function hook_field_formatter_info() {
  return array(
    'text_default' => array(
      'label' => t('Default'),
      'field types' => array('text', 'text_long', 'text_with_summary'),
    ),
    'text_plain' => array(
      'label' => t('Plain text'),
      'field types' => array('text', 'text_long', 'text_with_summary'),
    ),

    // The text_trimmed formatter displays the trimmed version of the
    // full element of the field. It is intended to be used with text
    // and text_long fields. It also works with text_with_summary
    // fields though the text_summary_or_trimmed formatter makes more
    // sense for that field type.
    'text_trimmed' => array(
      'label' => t('Trimmed'),
      'field types' => array('text', 'text_long', 'text_with_summary'),
    ),

    // The 'summary or trimmed' field formatter for text_with_summary
    // fields displays returns the summary element of the field or, if
    // the summary is empty, the trimmed version of the full element
    // of the field.
    'text_summary_or_trimmed' => array(
      'label' => t('Summary or trimmed'),
      'field types' => array('text_with_summary'),
    ),
  );
}

/**
 * Perform alterations on Field API formatter types.
 *
 * @param $info
 *   Array of informations on formatter types exposed by
 *   hook_field_field_formatter_info() implementations.
 */
function hook_field_formatter_info_alter(&$info) {
  // Add a setting to a formatter type.
  $info['text_default']['settings'] += array(
    'mymodule_additional_setting' => 'default value',
  );

  // Let a new field type re-use an existing formatter.
  $info['text_default']['field types'][] = 'my_field_type';
}

/**
1005
 * Allow formatters to load information for field values being displayed.
1006
1007
1008
 *
 * This should be used when a formatter needs to load additional information
 * from the database in order to render a field, for example a reference field
1009
 * which displays properties of the referenced entities such as name or type.
1010
 *
1011
1012
 * This hook is called after the field type's own hook_field_prepare_view().
 *
1013
 * Unlike most other field hooks, this hook operates on multiple entities. The
1014
 * $entities, $instances and $items parameters are arrays keyed by entity ID.
1015
 * For performance reasons, information for all available entities should be
1016
1017
 * loaded in a single query where possible.
 *
1018
1019
1020
 * @param $entity_type
 *   The type of $entity.
 * @param $entities
1021
 *   Array of entities being displayed, keyed by entity ID.
1022
1023
1024
 * @param $field
 *   The field structure for the operation.
 * @param $instances
1025
 *   Array of instance structures for $field for each entity, keyed by entity
1026
 *   ID.
1027
1028
1029
1030
 * @param $langcode
 *   The language the field values are to be shown in. If no language is
 *   provided the current language is used.
 * @param $items
1031
 *   Array of field values for the entities, keyed by entity ID.
1032
 * @param $displays
1033
1034
 *   Array of display settings to use for each entity, keyed by entity ID.
 *
1035
1036
1037
1038
 * @return
 *   Changes or additions to field values are done by altering the $items
 *   parameter by reference.
 */
1039
function hook_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
  $tids = array();

  // Collect every possible term attached to any of the fieldable entities.
  foreach ($entities as $id => $entity) {
    foreach ($items[$id] as $delta => $item) {
      // Force the array key to prevent duplicates.
      $tids[$item['tid']] = $item['tid'];
    }
  }

  if ($tids) {
    $terms = taxonomy_term_load_multiple($tids);

    // Iterate through the fieldable entities again to attach the loaded term
    // data.
    foreach ($entities as $id => $entity) {
      $rekey = FALSE;

      foreach ($items[$id] as $delta => $item) {
        // Check whether the taxonomy term field instance value could be loaded.
        if (isset($terms[$item['tid']])) {
          // Replace the instance value with the term data.
          $items[$id][$delta]['taxonomy_term'] = $terms[$item['tid']];
        }
        // Otherwise, unset the instance value, since the term does not exist.
        else {
          unset($items[$id][$delta]);
          $rekey = TRUE;
        }
      }

      if ($rekey) {
        // Rekey the items array.
        $items[$id] = array_values($items[$id]);
      }
    }
  }
1077
}
1078

1079
/**
1080
 * Build a renderable array for a field value.
1081
 *
1082
1083
1084
 * @param $entity_type
 *   The type of $entity.
 * @param $entity
1085
 *   The entity being displayed.
1086
1087
1088
1089
1090
 * @param $field
 *   The field structure.
 * @param $instance
 *   The field instance.
 * @param $langcode
1091
 *   The language associated with $items.
1092
1093
 * @param $items
 *   Array of values for this field.
1094
1095
1096
1097
1098
 * @param $display
 *   The display settings to use, as found in the 'display' entry of instance
 *   definitions. The array notably contains the following keys and values;
 *   - type: The name of the formatter to use.
 *   - settings: The array of formatter settings.
1099
1100
 *
 * @return
1101
1102
 *   A renderable array for the $items, as an array of child elements keyed
 *   by numeric indexes starting from 0.
1103
 */
1104
function hook_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
1105
  $element = array();
1106
1107
1108
  $settings = $display['settings'];

  switch ($display['type']) {
1109
1110
1111
1112
1113
1114
1115
    case 'sample_field_formatter_simple':
      // Common case: each value is displayed individually in a sub-element
      // keyed by delta. The field.tpl.php template specifies the markup
      // wrapping each value.
      foreach ($items as $delta => $item) {
        $element[$delta] = array('#markup' => $settings['some_setting'] . $item['value']);
      }
1116
1117
      break;

1118
1119
1120
    case 'sample_field_formatter_themeable':
      // More elaborate formatters can defer to a theme function for easier
      // customization.
1121
      foreach ($items as $delta => $item) {
1122
1123
1124
1125
1126
        $element[$delta] = array(
          '#theme' => 'mymodule_theme_sample_field_formatter_themeable',
          '#data' => $item['value'],
          '#some_setting' => $settings['some_setting'],
        );
1127
      }
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
      break;

    case 'sample_field_formatter_combined':
      // Some formatters might need to display all values within a single piece
      // of markup.
      $rows = array();
      foreach ($items as $delta => $item) {
        $rows[] = array($delta, $item['value']);
      }
      $element[0] = array(
        '#theme' => 'table',
        '#header' => array(t('Delta'), t('Value')),
        '#rows' => $rows,
1141
1142
1143
1144
      );
      break;
  }

1145
  return $element;
1146
1147
}

1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
/**
 * @} End of "ingroup field_type"
 */

/**
 * @ingroup field_attach
 * @{
 */

/**
1158
 * Act on field_attach_form().
1159
 *
1160
 * This hook is invoked after the field module has performed the operation.
1161
 * Implementing modules should alter the $form or $form_state parameters.
1162
 *
1163
1164
1165
 * @param $entity_type
 *   The type of $entity; for example, 'node' or 'user'.
 * @param $entity
1166
 *   The entity for which an edit form is being built.
1167
 * @param $form
1168
1169
1170
1171
1172
1173
1174
 *   The form structure where field elements are attached to. This might be a
 *   full form structure, or a sub-element of a larger form. The
 *   $form['#parents'] property can be used to identify the corresponding part
 *   of $form_state['values']. Hook implementations that need to act on the
 *   top-level properties of the global form (like #submit, #validate...) can
 *   add a #process callback to the array received in the $form parameter, and
 *   act on the $complete_form parameter in the process callback.
1175
1176
1177
1178
1179
 * @param $form_state
 *   An associative array containing the current state of the form.
 * @param $langcode
 *   The language the field values are going to be entered in. If no language
 *   is provided the default site language will be used.
1180
 */
1181
function hook_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
1182
1183
1184
1185
1186
1187
  // Add a checkbox allowing a given field to be emptied.
  // See hook_field_attach_submit() for the corresponding processing code.
  $form['empty_field_foo'] = array(
    '#type' => 'checkbox',
    '#title' => t("Empty the 'field_foo' field"),
  );
1188
1189
1190
}

/**
1191
 * Act on field_attach_load().
1192
 *
1193
 * This hook is invoked after the field module has performed the operation.
1194
 *
1195
 * Unlike other field_attach hooks, this hook accounts for 'multiple loads'.
1196
 * Instead of the usual $entity parameter, it accepts an array of entities,
1197
 * indexed by entity ID. For performance reasons, information for all available
1198
 * entities should be loaded in a single query where possible.
1199
 *
1200
 * The changes made to the entities' field values get cached by the field cache
1201
 * for subsequent loads.
1202
 *
1203
 * See field_attach_load() for details and arguments.
1204
 */
1205
function hook_field_attach_load($entity_type, $entities, $age, $options) {
1206
  // @todo Needs function body.
1207
1208
1209
}

/**
1210
 * Act on field_attach_validate().
1211
 *
1212
 * This hook is invoked after the field module has performed the operation.
1213
1214
1215
 *
 * See field_attach_validate() for details and arguments.
 */
1216
function hook_field_attach_validate($entity_type, $entity, &$errors) {
1217
  // @todo Needs function body.
1218
1219
1220
}

/**
1221
 * Act on field_attach_submit().
1222
 *
1223
 * This hook is invoked after the field module has performed the operation.
1224
 *
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
 * @param $entity_type
 *   The type of $entity; for example, 'node' or 'user'.
 * @param $entity
 *   The entity for which an edit form is being submitted. The incoming form
 *   values have been extracted as field values of the $entity object.
 * @param $form
 *   The form structure where field elements are attached to. This might be a
 *   full form structure, or a sub-part of a larger form. The $form['#parents']
 *   property can be used to identify the corresponding part of
 *   $form_state['values'].
 * @param $form_state
 *   An associative array containing the current state of the form.
1237
 */