Projet

Général

Profil

Paste
Télécharger (95,9 ko) Statistiques
| Branche: | Révision:

root / htmltest / modules / field / field.api.php @ 85ad3d82

1
<?php
2

    
3
/**
4
 * @addtogroup hooks
5
 * @{
6
 */
7

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

    
69
  return $extra;
70
}
71

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

    
89
/**
90
 * @defgroup field_types Field Types API
91
 * @{
92
 * Define field types.
93
 *
94
 * In the Field API, each field has a type, which determines what kind of data
95
 * (integer, string, date, etc.) the field can hold, which settings it provides,
96
 * and so on. The data type(s) accepted by a field are defined in
97
 * hook_field_schema(); other basic properties of a field are defined in
98
 * hook_field_info(). The other hooks below are called by the Field Attach API
99
 * to perform field-type-specific actions.
100
 *
101
 * The Field Types API also defines two kinds of pluggable handlers: widgets
102
 * and formatters. @link field_widget Widgets @endlink specify how the field
103
 * appears in edit forms, while @link field_formatter formatters @endlink
104
 * specify how the field appears in displayed entities.
105
 *
106
 * A third kind of pluggable handlers, storage backends, is defined by the
107
 * @link field_storage Field Storage API @endlink.
108
 *
109
 * See @link field Field API @endlink for information about the other parts of
110
 * the Field API.
111
 */
112

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

    
181
/**
182
 * Perform alterations on Field API field types.
183
 *
184
 * @param $info
185
 *   Array of information on field types exposed by hook_field_info()
186
 *   implementations.
187
 */
188
function hook_field_info_alter(&$info) {
189
  // Add a setting to all field types.
190
  foreach ($info as $field_type => $field_type_info) {
191
    $info[$field_type]['settings'] += array(
192
      'mymodule_additional_setting' => 'default value',
193
    );
194
  }
195

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

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

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

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

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

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

    
440
/**
441
 * Define custom insert behavior for this module's field data.
442
 *
443
 * This hook is invoked from field_attach_insert() on the module that defines a
444
 * field, during the process of inserting an entity object (node, taxonomy term,
445
 * etc.). It is invoked just before the data for this field on the particular
446
 * entity object is inserted into field storage. Only field modules that are
447
 * storing or tracking information outside the standard field storage mechanism
448
 * need to implement this hook.
449
 *
450
 * @param $entity_type
451
 *   The type of $entity.
452
 * @param $entity
453
 *   The entity for the operation.
454
 * @param $field
455
 *   The field structure for the operation.
456
 * @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
 * @see hook_field_update()
464
 * @see hook_field_delete()
465
 */
466
function hook_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
467
  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node' && $entity->status) {
468
    $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', ));
469
    foreach ($items as $item) {
470
      $query->values(array(
471
        'nid' => $entity->nid,
472
        'tid' => $item['tid'],
473
        'sticky' => $entity->sticky,
474
        'created' => $entity->created,
475
      ));
476
    }
477
    $query->execute();
478
  }
479
}
480

    
481
/**
482
 * Define custom update behavior for this module's field data.
483
 *
484
 * This hook is invoked from field_attach_update() on the module that defines a
485
 * field, during the process of updating an entity object (node, taxonomy term,
486
 * etc.). It is invoked just before the data for this field on the particular
487
 * entity object is updated into field storage. Only field modules that are
488
 * storing or tracking information outside the standard field storage mechanism
489
 * need to implement this hook.
490
 *
491
 * @param $entity_type
492
 *   The type of $entity.
493
 * @param $entity
494
 *   The entity for the operation.
495
 * @param $field
496
 *   The field structure for the operation.
497
 * @param $instance
498
 *   The instance structure for $field on $entity's bundle.
499
 * @param $langcode
500
 *   The language associated with $items.
501
 * @param $items
502
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
503
 *
504
 * @see hook_field_insert()
505
 * @see hook_field_delete()
506
 */
507
function hook_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
508
  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node') {
509
    $first_call = &drupal_static(__FUNCTION__, array());
510

    
511
    // We don't maintain data for old revisions, so clear all previous values
512
    // from the table. Since this hook runs once per field, per object, make
513
    // sure we only wipe values once.
514
    if (!isset($first_call[$entity->nid])) {
515
      $first_call[$entity->nid] = FALSE;
516
      db_delete('taxonomy_index')->condition('nid', $entity->nid)->execute();
517
    }
518
    // Only save data to the table if the node is published.
519
    if ($entity->status) {
520
      $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created'));
521
      foreach ($items as $item) {
522
        $query->values(array(
523
          'nid' => $entity->nid,
524
          'tid' => $item['tid'],
525
          'sticky' => $entity->sticky,
526
          'created' => $entity->created,
527
        ));
528
      }
529
      $query->execute();
530
    }
531
  }
532
}
533

    
534
/**
535
 * Update the storage information for a field.
536
 *
537
 * This is invoked on the field's storage module from field_update_field(),
538
 * before the new field information is saved to the database. The field storage
539
 * module should update its storage tables to agree with the new field
540
 * information. If there is a problem, the field storage module should throw an
541
 * exception.
542
 *
543
 * @param $field
544
 *   The updated field structure to be saved.
545
 * @param $prior_field
546
 *   The previously-saved field structure.
547
 * @param $has_data
548
 *   TRUE if the field has data in storage currently.
549
 */
550
function hook_field_storage_update_field($field, $prior_field, $has_data) {
551
  if (!$has_data) {
552
    // There is no data. Re-create the tables completely.
553
    $prior_schema = _field_sql_storage_schema($prior_field);
554
    foreach ($prior_schema as $name => $table) {
555
      db_drop_table($name, $table);
556
    }
557
    $schema = _field_sql_storage_schema($field);
558
    foreach ($schema as $name => $table) {
559
      db_create_table($name, $table);
560
    }
561
  }
562
  else {
563
    // There is data. See field_sql_storage_field_storage_update_field() for
564
    // an example of what to do to modify the schema in place, preserving the
565
    // old data as much as possible.
566
  }
567
  drupal_get_schema(NULL, TRUE);
568
}
569

    
570
/**
571
 * Define custom delete behavior for this module's field data.
572
 *
573
 * This hook is invoked from field_attach_delete() on the module that defines a
574
 * field, during the process of deleting an entity object (node, taxonomy term,
575
 * etc.). It is invoked just before the data for this field on the particular
576
 * entity object is deleted from field storage. Only field modules that are
577
 * storing or tracking information outside the standard field storage mechanism
578
 * need to implement this hook.
579
 *
580
 * @param $entity_type
581
 *   The type of $entity.
582
 * @param $entity
583
 *   The entity for the operation.
584
 * @param $field
585
 *   The field structure for the operation.
586
 * @param $instance
587
 *   The instance structure for $field on $entity's bundle.
588
 * @param $langcode
589
 *   The language associated with $items.
590
 * @param $items
591
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
592
 *
593
 * @see hook_field_insert()
594
 * @see hook_field_update()
595
 */
596
function hook_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
597
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
598
  foreach ($items as $delta => $item) {
599
    // For hook_file_references(), remember that this is being deleted.
600
    $item['file_field_name'] = $field['field_name'];
601
    // Pass in the ID of the object that is being removed so all references can
602
    // be counted in hook_file_references().
603
    $item['file_field_type'] = $entity_type;
604
    $item['file_field_id'] = $id;
605
    file_field_delete_file($item, $field, $entity_type, $id);
606
  }
607
}
608

    
609
/**
610
 * Define custom revision delete behavior for this module's field types.
611
 *
612
 * This hook is invoked just before the data is deleted from field storage
613
 * in field_attach_delete_revision(), and will only be called for fieldable
614
 * types that are versioned.
615
 *
616
 * @param $entity_type
617
 *   The type of $entity.
618
 * @param $entity
619
 *   The entity for the operation.
620
 * @param $field
621
 *   The field structure for the operation.
622
 * @param $instance
623
 *   The instance structure for $field on $entity's bundle.
624
 * @param $langcode
625
 *   The language associated with $items.
626
 * @param $items
627
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
628
 */
629
function hook_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
630
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
631
  foreach ($items as $delta => $item) {
632
    // For hook_file_references, remember that this file is being deleted.
633
    $item['file_field_name'] = $field['field_name'];
634
    if (file_field_delete_file($item, $field, $entity_type, $id)) {
635
      $items[$delta] = NULL;
636
    }
637
  }
638
}
639

    
640
/**
641
 * Define custom prepare_translation behavior for this module's field types.
642
 *
643
 * @param $entity_type
644
 *   The type of $entity.
645
 * @param $entity
646
 *   The entity for the operation.
647
 * @param $field
648
 *   The field structure for the operation.
649
 * @param $instance
650
 *   The instance structure for $field on $entity's bundle.
651
 * @param $langcode
652
 *   The language associated to $items.
653
 * @param $items
654
 *   $entity->{$field['field_name']}[$langcode], or an empty array if unset.
655
 * @param $source_entity
656
 *   The source entity from which field values are being copied.
657
 * @param $source_langcode
658
 *   The source language from which field values are being copied.
659
 */
660
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
661
  // If the translating user is not permitted to use the assigned text format,
662
  // we must not expose the source values.
663
  $field_name = $field['field_name'];
664
  $formats = filter_formats();
665
  $format_id = $source_entity->{$field_name}[$source_langcode][0]['format'];
666
  if (!filter_access($formats[$format_id])) {
667
    $items = array();
668
  }
669
}
670

    
671
/**
672
 * Define what constitutes an empty item for a field type.
673
 *
674
 * @param $item
675
 *   An item that may or may not be empty.
676
 * @param $field
677
 *   The field to which $item belongs.
678
 *
679
 * @return
680
 *   TRUE if $field's type considers $item not to contain any data;
681
 *   FALSE otherwise.
682
 */
683
function hook_field_is_empty($item, $field) {
684
  if (empty($item['value']) && (string) $item['value'] !== '0') {
685
    return TRUE;
686
  }
687
  return FALSE;
688
}
689

    
690
/**
691
 * @} End of "defgroup field_types".
692
 */
693

    
694
/**
695
 * @defgroup field_widget Field Widget API
696
 * @{
697
 * Define Field API widget types.
698
 *
699
 * Field API widgets specify how fields are displayed in edit forms. Fields of a
700
 * given @link field_types field type @endlink may be edited using more than one
701
 * widget. In this case, the Field UI module allows the site builder to choose
702
 * which widget to use. Widget types are defined by implementing
703
 * hook_field_widget_info().
704
 *
705
 * Widgets are @link forms_api_reference.html Form API @endlink elements with
706
 * additional processing capabilities. Widget hooks are typically called by the
707
 * Field Attach API during the creation of the field form structure with
708
 * field_attach_form().
709
 *
710
 * @see field
711
 * @see field_types
712
 * @see field_formatter
713
 */
714

    
715
/**
716
 * Expose Field API widget types.
717
 *
718
 * @return
719
 *   An array describing the widget types implemented by the module.
720
 *   The keys are widget type names. To avoid name clashes, widget type
721
 *   names should be prefixed with the name of the module that exposes them.
722
 *   The values are arrays describing the widget type, with the following
723
 *   key/value pairs:
724
 *   - label: The human-readable name of the widget type.
725
 *   - description: A short description for the widget type.
726
 *   - field types: An array of field types the widget supports.
727
 *   - settings: An array whose keys are the names of the settings available
728
 *     for the widget type, and whose values are the default values for those
729
 *     settings.
730
 *   - behaviors: (optional) An array describing behaviors of the widget, with
731
 *     the following elements:
732
 *     - multiple values: One of the following constants:
733
 *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget allows the input of
734
 *         one single field value (most common case). The widget will be
735
 *         repeated for each value input.
736
 *       - FIELD_BEHAVIOR_CUSTOM: If one single copy of the widget can receive
737
 *         several field values. Examples: checkboxes, multiple select,
738
 *         comma-separated textfield.
739
 *     - default value: One of the following constants:
740
 *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts default
741
 *         values.
742
 *       - FIELD_BEHAVIOR_NONE: if the widget does not support default values.
743
 *   - weight: (optional) An integer to determine the weight of this widget
744
 *     relative to other widgets in the Field UI when selecting a widget for a
745
 *     given field instance.
746
 *
747
 * @see hook_field_widget_info_alter()
748
 * @see hook_field_widget_form()
749
 * @see hook_field_widget_form_alter()
750
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
751
 * @see hook_field_widget_error()
752
 * @see hook_field_widget_settings_form()
753
 */
754
function hook_field_widget_info() {
755
  return array(
756
    'text_textfield' => array(
757
      'label' => t('Text field'),
758
      'field types' => array('text'),
759
      'settings' => array('size' => 60),
760
      'behaviors' => array(
761
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
762
        'default value' => FIELD_BEHAVIOR_DEFAULT,
763
      ),
764
    ),
765
    'text_textarea' => array(
766
      'label' => t('Text area (multiple rows)'),
767
      'field types' => array('text_long'),
768
      'settings' => array('rows' => 5),
769
      'behaviors' => array(
770
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
771
        'default value' => FIELD_BEHAVIOR_DEFAULT,
772
      ),
773
    ),
774
    'text_textarea_with_summary' => array(
775
      'label' => t('Text area with a summary'),
776
      'field types' => array('text_with_summary'),
777
      'settings' => array('rows' => 20, 'summary_rows' => 5),
778
      'behaviors' => array(
779
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
780
        'default value' => FIELD_BEHAVIOR_DEFAULT,
781
      ),
782
      // As an advanced widget, force it to sink to the bottom of the choices.
783
      'weight' => 2,
784
    ),
785
  );
786
}
787

    
788
/**
789
 * Perform alterations on Field API widget types.
790
 *
791
 * @param $info
792
 *   Array of informations on widget types exposed by hook_field_widget_info()
793
 *   implementations.
794
 */
795
function hook_field_widget_info_alter(&$info) {
796
  // Add a setting to a widget type.
797
  $info['text_textfield']['settings'] += array(
798
    'mymodule_additional_setting' => 'default value',
799
  );
800

    
801
  // Let a new field type re-use an existing widget.
802
  $info['options_select']['field types'][] = 'my_field_type';
803
}
804

    
805
/**
806
 * Return the form for a single field widget.
807
 *
808
 * Field widget form elements should be based on the passed-in $element, which
809
 * contains the base form element properties derived from the field
810
 * configuration.
811
 *
812
 * Field API will set the weight, field name and delta values for each form
813
 * element. If there are multiple values for this field, the Field API will
814
 * invoke this hook as many times as needed.
815
 *
816
 * Note that, depending on the context in which the widget is being included
817
 * (regular entity form, field configuration form, advanced search form...),
818
 * the values for $field and $instance might be different from the "official"
819
 * definitions returned by field_info_field() and field_info_instance().
820
 * Examples: mono-value widget even if the field is multi-valued, non-required
821
 * widget even if the field is 'required'...
822
 *
823
 * Therefore, the FAPI element callbacks (such as #process, #element_validate,
824
 * #value_callback...) used by the widget cannot use the field_info_field()
825
 * or field_info_instance() functions to retrieve the $field or $instance
826
 * definitions they should operate on. The field_widget_field() and
827
 * field_widget_instance() functions should be used instead to fetch the
828
 * current working definitions from $form_state, where Field API stores them.
829
 *
830
 * Alternatively, hook_field_widget_form() can extract the needed specific
831
 * properties from $field and $instance and set them as ad-hoc
832
 * $element['#custom'] properties, for later use by its element callbacks.
833
 *
834
 * Other modules may alter the form element provided by this function using
835
 * hook_field_widget_form_alter().
836
 *
837
 * @param $form
838
 *   The form structure where widgets are being attached to. This might be a
839
 *   full form structure, or a sub-element of a larger form.
840
 * @param $form_state
841
 *   An associative array containing the current state of the form.
842
 * @param $field
843
 *   The field structure.
844
 * @param $instance
845
 *   The field instance.
846
 * @param $langcode
847
 *   The language associated with $items.
848
 * @param $items
849
 *   Array of default values for this field.
850
 * @param $delta
851
 *   The order of this item in the array of subelements (0, 1, 2, etc).
852
 * @param $element
853
 *   A form element array containing basic properties for the widget:
854
 *   - #entity_type: The name of the entity the field is attached to.
855
 *   - #bundle: The name of the field bundle the field is contained in.
856
 *   - #field_name: The name of the field.
857
 *   - #language: The language the field is being edited in.
858
 *   - #field_parents: The 'parents' space for the field in the form. Most
859
 *       widgets can simply overlook this property. This identifies the
860
 *       location where the field values are placed within
861
 *       $form_state['values'], and is used to access processing information
862
 *       for the field through the field_form_get_state() and
863
 *       field_form_set_state() functions.
864
 *   - #columns: A list of field storage columns of the field.
865
 *   - #title: The sanitized element label for the field instance, ready for
866
 *     output.
867
 *   - #description: The sanitized element description for the field instance,
868
 *     ready for output.
869
 *   - #required: A Boolean indicating whether the element value is required;
870
 *     for required multiple value fields, only the first widget's values are
871
 *     required.
872
 *   - #delta: The order of this item in the array of subelements; see $delta
873
 *     above.
874
 *
875
 * @return
876
 *   The form elements for a single widget for this field.
877
 *
878
 * @see field_widget_field()
879
 * @see field_widget_instance()
880
 * @see hook_field_widget_form_alter()
881
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
882
 */
883
function hook_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
884
  $element += array(
885
    '#type' => $instance['widget']['type'],
886
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
887
  );
888
  return array('value' => $element);
889
}
890

    
891
/**
892
 * Alter forms for field widgets provided by other modules.
893
 *
894
 * @param $element
895
 *   The field widget form element as constructed by hook_field_widget_form().
896
 * @param $form_state
897
 *   An associative array containing the current state of the form.
898
 * @param $context
899
 *   An associative array containing the following key-value pairs, matching the
900
 *   arguments received by hook_field_widget_form():
901
 *   - form: The form structure to which widgets are being attached. This may be
902
 *     a full form structure, or a sub-element of a larger form.
903
 *   - field: The field structure.
904
 *   - instance: The field instance structure.
905
 *   - langcode: The language associated with $items.
906
 *   - items: Array of default values for this field.
907
 *   - delta: The order of this item in the array of subelements (0, 1, 2, etc).
908
 *
909
 * @see hook_field_widget_form()
910
 * @see hook_field_widget_WIDGET_TYPE_form_alter()
911
 */
912
function hook_field_widget_form_alter(&$element, &$form_state, $context) {
913
  // Add a css class to widget form elements for all fields of type mytype.
914
  if ($context['field']['type'] == 'mytype') {
915
    // Be sure not to overwrite existing attributes.
916
    $element['#attributes']['class'][] = 'myclass';
917
  }
918
}
919

    
920
/**
921
 * Alter widget forms for a specific widget provided by another module.
922
 *
923
 * Modules can implement hook_field_widget_WIDGET_TYPE_form_alter() to modify a
924
 * specific widget form, rather than using hook_field_widget_form_alter() and
925
 * checking the widget type.
926
 *
927
 * @param $element
928
 *   The field widget form element as constructed by hook_field_widget_form().
929
 * @param $form_state
930
 *   An associative array containing the current state of the form.
931
 * @param $context
932
 *   An associative array containing the following key-value pairs, matching the
933
 *   arguments received by hook_field_widget_form():
934
 *   - "form": The form structure where widgets are being attached to. This
935
 *     might be a full form structure, or a sub-element of a larger form.
936
 *   - "field": The field structure.
937
 *   - "instance": The field instance structure.
938
 *   - "langcode": The language associated with $items.
939
 *   - "items": Array of default values for this field.
940
 *   - "delta": The order of this item in the array of subelements (0, 1, 2,
941
 *     etc).
942
 *
943
 * @see hook_field_widget_form()
944
 * @see hook_field_widget_form_alter()
945
 */
946
function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $context) {
947
  // Code here will only act on widgets of type WIDGET_TYPE.  For example,
948
  // hook_field_widget_mymodule_autocomplete_form_alter() will only act on
949
  // widgets of type 'mymodule_autocomplete'.
950
  $element['#autocomplete_path'] = 'mymodule/autocomplete_path';
951
}
952

    
953
/**
954
 * Alters the widget properties of a field instance before it gets displayed.
955
 *
956
 * Note that instead of hook_field_widget_properties_alter(), which is called
957
 * for all fields on all entity types,
958
 * hook_field_widget_properties_ENTITY_TYPE_alter() may be used to alter widget
959
 * properties for fields on a specific entity type only.
960
 *
961
 * This hook is called once per field per added or edit entity. If the result
962
 * of the hook involves reading from the database, it is highly recommended to
963
 * statically cache the information.
964
 *
965
 * @param $widget
966
 *   The instance's widget properties.
967
 * @param $context
968
 *   An associative array containing:
969
 *   - entity_type: The entity type; e.g., 'node' or 'user'.
970
 *   - entity: The entity object.
971
 *   - field: The field that the widget belongs to.
972
 *   - instance: The instance of the field.
973
 *
974
 * @see hook_field_widget_properties_ENTITY_TYPE_alter()
975
 */
976
function hook_field_widget_properties_alter(&$widget, $context) {
977
  // Change a widget's type according to the time of day.
978
  $field = $context['field'];
979
  if ($context['entity_type'] == 'node' && $field['field_name'] == 'field_foo') {
980
    $time = date('H');
981
    $widget['type'] = $time < 12 ? 'widget_am' : 'widget_pm';
982
  }
983
}
984

    
985
/**
986
 * Flag a field-level validation error.
987
 *
988
 * @param $element
989
 *   An array containing the form element for the widget. The error needs to be
990
 *   flagged on the right sub-element, according to the widget's internal
991
 *   structure.
992
 * @param $error
993
 *   An associative array with the following key-value pairs, as returned by
994
 *   hook_field_validate():
995
 *   - error: the error code. Complex widgets might need to report different
996
 *     errors to different form elements inside the widget.
997
 *   - message: the human readable message to be displayed.
998
 * @param $form
999
 *   The form structure where field elements are attached to. This might be a
1000
 *   full form structure, or a sub-element of a larger form.
1001
 * @param $form_state
1002
 *   An associative array containing the current state of the form.
1003
 */
1004
function hook_field_widget_error($element, $error, $form, &$form_state) {
1005
  form_error($element, $error['message']);
1006
}
1007

    
1008

    
1009
/**
1010
 * @} End of "defgroup field_widget".
1011
 */
1012

    
1013

    
1014
/**
1015
 * @defgroup field_formatter Field Formatter API
1016
 * @{
1017
 * Define Field API formatter types.
1018
 *
1019
 * Field API formatters specify how fields are displayed when the entity to
1020
 * which the field is attached is displayed. Fields of a given
1021
 * @link field_types field type @endlink may be displayed using more than one
1022
 * formatter. In this case, the Field UI module allows the site builder to
1023
 * choose which formatter to use. Field formatters are defined by implementing
1024
 * hook_field_formatter_info().
1025
 *
1026
 * @see field
1027
 * @see field_types
1028
 * @see field_widget
1029
 */
1030

    
1031
/**
1032
 * Expose Field API formatter types.
1033
 *
1034
 * Formatters handle the display of field values. Formatter hooks are typically
1035
 * called by the Field Attach API field_attach_prepare_view() and
1036
 * field_attach_view() functions.
1037
 *
1038
 * @return
1039
 *   An array describing the formatter types implemented by the module.
1040
 *   The keys are formatter type names. To avoid name clashes, formatter type
1041
 *   names should be prefixed with the name of the module that exposes them.
1042
 *   The values are arrays describing the formatter type, with the following
1043
 *   key/value pairs:
1044
 *   - label: The human-readable name of the formatter type.
1045
 *   - description: A short description for the formatter type.
1046
 *   - field types: An array of field types the formatter supports.
1047
 *   - settings: An array whose keys are the names of the settings available
1048
 *     for the formatter type, and whose values are the default values for
1049
 *     those settings.
1050
 *
1051
 * @see hook_field_formatter_info_alter()
1052
 * @see hook_field_formatter_view()
1053
 * @see hook_field_formatter_prepare_view()
1054
 */
1055
function hook_field_formatter_info() {
1056
  return array(
1057
    'text_default' => array(
1058
      'label' => t('Default'),
1059
      'field types' => array('text', 'text_long', 'text_with_summary'),
1060
    ),
1061
    'text_plain' => array(
1062
      'label' => t('Plain text'),
1063
      'field types' => array('text', 'text_long', 'text_with_summary'),
1064
    ),
1065

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

    
1076
    // The 'summary or trimmed' field formatter for text_with_summary
1077
    // fields displays returns the summary element of the field or, if
1078
    // the summary is empty, the trimmed version of the full element
1079
    // of the field.
1080
    'text_summary_or_trimmed' => array(
1081
      'label' => t('Summary or trimmed'),
1082
      'field types' => array('text_with_summary'),
1083
    ),
1084
  );
1085
}
1086

    
1087
/**
1088
 * Perform alterations on Field API formatter types.
1089
 *
1090
 * @param $info
1091
 *   An array of information on formatter types exposed by
1092
 *   hook_field_formatter_info() implementations.
1093
 */
1094
function hook_field_formatter_info_alter(&$info) {
1095
  // Add a setting to a formatter type.
1096
  $info['text_default']['settings'] += array(
1097
    'mymodule_additional_setting' => 'default value',
1098
  );
1099

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

    
1104
/**
1105
 * Allow formatters to load information for field values being displayed.
1106
 *
1107
 * This should be used when a formatter needs to load additional information
1108
 * from the database in order to render a field, for example a reference field
1109
 * which displays properties of the referenced entities such as name or type.
1110
 *
1111
 * This hook is called after the field type's own hook_field_prepare_view().
1112
 *
1113
 * Unlike most other field hooks, this hook operates on multiple entities. The
1114
 * $entities, $instances and $items parameters are arrays keyed by entity ID.
1115
 * For performance reasons, information for all available entities should be
1116
 * loaded in a single query where possible.
1117
 *
1118
 * @param $entity_type
1119
 *   The type of $entity.
1120
 * @param $entities
1121
 *   Array of entities being displayed, keyed by entity ID.
1122
 * @param $field
1123
 *   The field structure for the operation.
1124
 * @param $instances
1125
 *   Array of instance structures for $field for each entity, keyed by entity
1126
 *   ID.
1127
 * @param $langcode
1128
 *   The language the field values are to be shown in. If no language is
1129
 *   provided the current language is used.
1130
 * @param $items
1131
 *   Array of field values for the entities, keyed by entity ID.
1132
 * @param $displays
1133
 *   Array of display settings to use for each entity, keyed by entity ID.
1134
 *
1135
 * @return
1136
 *   Changes or additions to field values are done by altering the $items
1137
 *   parameter by reference.
1138
 */
1139
function hook_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
1140
  $tids = array();
1141

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

    
1150
  if ($tids) {
1151
    $terms = taxonomy_term_load_multiple($tids);
1152

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

    
1158
      foreach ($items[$id] as $delta => $item) {
1159
        // Check whether the taxonomy term field instance value could be loaded.
1160
        if (isset($terms[$item['tid']])) {
1161
          // Replace the instance value with the term data.
1162
          $items[$id][$delta]['taxonomy_term'] = $terms[$item['tid']];
1163
        }
1164
        // Otherwise, unset the instance value, since the term does not exist.
1165
        else {
1166
          unset($items[$id][$delta]);
1167
          $rekey = TRUE;
1168
        }
1169
      }
1170

    
1171
      if ($rekey) {
1172
        // Rekey the items array.
1173
        $items[$id] = array_values($items[$id]);
1174
      }
1175
    }
1176
  }
1177
}
1178

    
1179
/**
1180
 * Build a renderable array for a field value.
1181
 *
1182
 * @param $entity_type
1183
 *   The type of $entity.
1184
 * @param $entity
1185
 *   The entity being displayed.
1186
 * @param $field
1187
 *   The field structure.
1188
 * @param $instance
1189
 *   The field instance.
1190
 * @param $langcode
1191
 *   The language associated with $items.
1192
 * @param $items
1193
 *   Array of values for this field.
1194
 * @param $display
1195
 *   The display settings to use, as found in the 'display' entry of instance
1196
 *   definitions. The array notably contains the following keys and values;
1197
 *   - type: The name of the formatter to use.
1198
 *   - settings: The array of formatter settings.
1199
 *
1200
 * @return
1201
 *   A renderable array for the $items, as an array of child elements keyed
1202
 *   by numeric indexes starting from 0.
1203
 */
1204
function hook_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
1205
  $element = array();
1206
  $settings = $display['settings'];
1207

    
1208
  switch ($display['type']) {
1209
    case 'sample_field_formatter_simple':
1210
      // Common case: each value is displayed individually in a sub-element
1211
      // keyed by delta. The field.tpl.php template specifies the markup
1212
      // wrapping each value.
1213
      foreach ($items as $delta => $item) {
1214
        $element[$delta] = array('#markup' => $settings['some_setting'] . $item['value']);
1215
      }
1216
      break;
1217

    
1218
    case 'sample_field_formatter_themeable':
1219
      // More elaborate formatters can defer to a theme function for easier
1220
      // customization.
1221
      foreach ($items as $delta => $item) {
1222
        $element[$delta] = array(
1223
          '#theme' => 'mymodule_theme_sample_field_formatter_themeable',
1224
          '#data' => $item['value'],
1225
          '#some_setting' => $settings['some_setting'],
1226
        );
1227
      }
1228
      break;
1229

    
1230
    case 'sample_field_formatter_combined':
1231
      // Some formatters might need to display all values within a single piece
1232
      // of markup.
1233
      $rows = array();
1234
      foreach ($items as $delta => $item) {
1235
        $rows[] = array($delta, $item['value']);
1236
      }
1237
      $element[0] = array(
1238
        '#theme' => 'table',
1239
        '#header' => array(t('Delta'), t('Value')),
1240
        '#rows' => $rows,
1241
      );
1242
      break;
1243
  }
1244

    
1245
  return $element;
1246
}
1247

    
1248
/**
1249
 * @} End of "defgroup field_formatter".
1250
 */
1251

    
1252
/**
1253
 * @ingroup field_attach
1254
 * @{
1255
 */
1256

    
1257
/**
1258
 * Act on field_attach_form().
1259
 *
1260
 * This hook is invoked after the field module has performed the operation.
1261
 * Implementing modules should alter the $form or $form_state parameters.
1262
 *
1263
 * @param $entity_type
1264
 *   The type of $entity; for example, 'node' or 'user'.
1265
 * @param $entity
1266
 *   The entity for which an edit form is being built.
1267
 * @param $form
1268
 *   The form structure where field elements are attached to. This might be a
1269
 *   full form structure, or a sub-element of a larger form. The
1270
 *   $form['#parents'] property can be used to identify the corresponding part
1271
 *   of $form_state['values']. Hook implementations that need to act on the
1272
 *   top-level properties of the global form (like #submit, #validate...) can
1273
 *   add a #process callback to the array received in the $form parameter, and
1274
 *   act on the $complete_form parameter in the process callback.
1275
 * @param $form_state
1276
 *   An associative array containing the current state of the form.
1277
 * @param $langcode
1278
 *   The language the field values are going to be entered in. If no language
1279
 *   is provided the default site language will be used.
1280
 */
1281
function hook_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
1282
  // Add a checkbox allowing a given field to be emptied.
1283
  // See hook_field_attach_submit() for the corresponding processing code.
1284
  $form['empty_field_foo'] = array(
1285
    '#type' => 'checkbox',
1286
    '#title' => t("Empty the 'field_foo' field"),
1287
  );
1288
}
1289

    
1290
/**
1291
 * Act on field_attach_load().
1292
 *
1293
 * This hook is invoked after the field module has performed the operation.
1294
 *
1295
 * Unlike other field_attach hooks, this hook accounts for 'multiple loads'.
1296
 * Instead of the usual $entity parameter, it accepts an array of entities,
1297
 * indexed by entity ID. For performance reasons, information for all available
1298
 * entities should be loaded in a single query where possible.
1299
 *
1300
 * The changes made to the entities' field values get cached by the field cache
1301
 * for subsequent loads.
1302
 *
1303
 * See field_attach_load() for details and arguments.
1304
 */
1305
function hook_field_attach_load($entity_type, $entities, $age, $options) {
1306
  // @todo Needs function body.
1307
}
1308

    
1309
/**
1310
 * Act on field_attach_validate().
1311
 *
1312
 * This hook is invoked after the field module has performed the operation.
1313
 *
1314
 * See field_attach_validate() for details and arguments.
1315
 */
1316
function hook_field_attach_validate($entity_type, $entity, &$errors) {
1317
  // @todo Needs function body.
1318
}
1319

    
1320
/**
1321
 * Act on field_attach_submit().
1322
 *
1323
 * This hook is invoked after the field module has performed the operation.
1324
 *
1325
 * @param $entity_type
1326
 *   The type of $entity; for example, 'node' or 'user'.
1327
 * @param $entity
1328
 *   The entity for which an edit form is being submitted. The incoming form
1329
 *   values have been extracted as field values of the $entity object.
1330
 * @param $form
1331
 *   The form structure where field elements are attached to. This might be a
1332
 *   full form structure, or a sub-part of a larger form. The $form['#parents']
1333
 *   property can be used to identify the corresponding part of
1334
 *   $form_state['values'].
1335
 * @param $form_state
1336
 *   An associative array containing the current state of the form.
1337
 */
1338
function hook_field_attach_submit($entity_type, $entity, $form, &$form_state) {
1339
  // Sample case of an 'Empty the field' checkbox added on the form, allowing
1340
  // a given field to be emptied.
1341
  $values = drupal_array_get_nested_value($form_state['values'], $form['#parents']);
1342
  if (!empty($values['empty_field_foo'])) {
1343
    unset($entity->field_foo);
1344
  }
1345
}
1346

    
1347
/**
1348
 * Act on field_attach_presave().
1349
 *
1350
 * This hook is invoked after the field module has performed the operation.
1351
 *
1352
 * See field_attach_presave() for details and arguments.
1353
 */
1354
function hook_field_attach_presave($entity_type, $entity) {
1355
  // @todo Needs function body.
1356
}
1357

    
1358
/**
1359
 * Act on field_attach_insert().
1360
 *
1361
 * This hook is invoked after the field module has performed the operation.
1362
 *
1363
 * See field_attach_insert() for details and arguments.
1364
 */
1365
function hook_field_attach_insert($entity_type, $entity) {
1366
  // @todo Needs function body.
1367
}
1368

    
1369
/**
1370
 * Act on field_attach_update().
1371
 *
1372
 * This hook is invoked after the field module has performed the operation.
1373
 *
1374
 * See field_attach_update() for details and arguments.
1375
 */
1376
function hook_field_attach_update($entity_type, $entity) {
1377
  // @todo Needs function body.
1378
}
1379

    
1380
/**
1381
 * Alter field_attach_preprocess() variables.
1382
 *
1383
 * This hook is invoked while preprocessing the field.tpl.php template file
1384
 * in field_attach_preprocess().
1385
 *
1386
 * @param $variables
1387
 *   The variables array is passed by reference and will be populated with field
1388
 *   values.
1389
 * @param $context
1390
 *   An associative array containing:
1391
 *   - entity_type: The type of $entity; for example, 'node' or 'user'.
1392
 *   - entity: The entity with fields to render.
1393
 *   - element: The structured array containing the values ready for rendering.
1394
 */
1395
function hook_field_attach_preprocess_alter(&$variables, $context) {
1396
  // @todo Needs function body.
1397
}
1398

    
1399
/**
1400
 * Act on field_attach_delete().
1401
 *
1402
 * This hook is invoked after the field module has performed the operation.
1403
 *
1404
 * See field_attach_delete() for details and arguments.
1405
 */
1406
function hook_field_attach_delete($entity_type, $entity) {
1407
  // @todo Needs function body.
1408
}
1409

    
1410
/**
1411
 * Act on field_attach_delete_revision().
1412
 *
1413
 * This hook is invoked after the field module has performed the operation.
1414
 *
1415
 * See field_attach_delete_revision() for details and arguments.
1416
 */
1417
function hook_field_attach_delete_revision($entity_type, $entity) {
1418
  // @todo Needs function body.
1419
}
1420

    
1421
/**
1422
 * Act on field_purge_data().
1423
 *
1424
 * This hook is invoked in field_purge_data() and allows modules to act on
1425
 * purging data from a single field pseudo-entity. For example, if a module
1426
 * relates data in the field with its own data, it may purge its own data
1427
 * during this process as well.
1428
 *
1429
 * @param $entity_type
1430
 *   The type of $entity; for example, 'node' or 'user'.
1431
 * @param $entity
1432
 *   The pseudo-entity whose field data is being purged.
1433
 * @param $field
1434
 *   The (possibly deleted) field whose data is being purged.
1435
 * @param $instance
1436
 *   The deleted field instance whose data is being purged.
1437
 *
1438
 * @see @link field_purge Field API bulk data deletion @endlink
1439
 * @see field_purge_data()
1440
 */
1441
function hook_field_attach_purge($entity_type, $entity, $field, $instance) {
1442
  // find the corresponding data in mymodule and purge it
1443
  if ($entity_type == 'node' && $field->field_name == 'my_field_name') {
1444
    mymodule_remove_mydata($entity->nid);
1445
  }
1446
}
1447

    
1448
/**
1449
 * Perform alterations on field_attach_view() or field_view_field().
1450
 *
1451
 * This hook is invoked after the field module has performed the operation.
1452
 *
1453
 * @param $output
1454
 *   The structured content array tree for all of the entity's fields.
1455
 * @param $context
1456
 *   An associative array containing:
1457
 *   - entity_type: The type of $entity; for example, 'node' or 'user'.
1458
 *   - entity: The entity with fields to render.
1459
 *   - view_mode: View mode; for example, 'full' or 'teaser'.
1460
 *   - display: Either a view mode string or an array of display settings. If
1461
 *     this hook is being invoked from field_attach_view(), the 'display'
1462
 *     element is set to the view mode string. If this hook is being invoked
1463
 *     from field_view_field(), this element is set to the $display argument
1464
 *     and the view_mode element is set to '_custom'. See field_view_field()
1465
 *     for more information on what its $display argument contains.
1466
 *   - language: The language code used for rendering.
1467
 */
1468
function hook_field_attach_view_alter(&$output, $context) {
1469
  // Append RDF term mappings on displayed taxonomy links.
1470
  foreach (element_children($output) as $field_name) {
1471
    $element = &$output[$field_name];
1472
    if ($element['#field_type'] == 'taxonomy_term_reference' && $element['#formatter'] == 'taxonomy_term_reference_link') {
1473
      foreach ($element['#items'] as $delta => $item) {
1474
        $term = $item['taxonomy_term'];
1475
        if (!empty($term->rdf_mapping['rdftype'])) {
1476
          $element[$delta]['#options']['attributes']['typeof'] = $term->rdf_mapping['rdftype'];
1477
        }
1478
        if (!empty($term->rdf_mapping['name']['predicates'])) {
1479
          $element[$delta]['#options']['attributes']['property'] = $term->rdf_mapping['name']['predicates'];
1480
        }
1481
      }
1482
    }
1483
  }
1484
}
1485

    
1486
/**
1487
 * Perform alterations on field_attach_prepare_translation().
1488
 *
1489
 * This hook is invoked after the field module has performed the operation.
1490
 *
1491
 * @param $entity
1492
 *   The entity being prepared for translation.
1493
 * @param $context
1494
 *   An associative array containing:
1495
 *   - entity_type: The type of $entity; e.g. 'node' or 'user'.
1496
 *   - langcode: The language the entity has to be translated in.
1497
 *   - source_entity: The entity holding the field values to be translated.
1498
 *   - source_langcode: The source language from which translate.
1499
 */
1500
function hook_field_attach_prepare_translation_alter(&$entity, $context) {
1501
  if ($context['entity_type'] == 'custom_entity_type') {
1502
    $entity->custom_field = $context['source_entity']->custom_field;
1503
  }
1504
}
1505

    
1506
/**
1507
 * Perform alterations on field_language() values.
1508
 *
1509
 * This hook is invoked to alter the array of display languages for the given
1510
 * entity.
1511
 *
1512
 * @param $display_language
1513
 *   A reference to an array of language codes keyed by field name.
1514
 * @param $context
1515
 *   An associative array containing:
1516
 *   - entity_type: The type of the entity to be displayed.
1517
 *   - entity: The entity with fields to render.
1518
 *   - langcode: The language code $entity has to be displayed in.
1519
 */
1520
function hook_field_language_alter(&$display_language, $context) {
1521
  // Do not apply core language fallback rules if they are disabled or if Locale
1522
  // is not registered as a translation handler.
1523
  if (variable_get('locale_field_language_fallback', TRUE) && field_has_translation_handler($context['entity_type'], 'locale')) {
1524
    locale_field_language_fallback($display_language, $context['entity'], $context['language']);
1525
  }
1526
}
1527

    
1528
/**
1529
 * Alter field_available_languages() values.
1530
 *
1531
 * This hook is invoked from field_available_languages() to allow modules to
1532
 * alter the array of available languages for the given field.
1533
 *
1534
 * @param $languages
1535
 *   A reference to an array of language codes to be made available.
1536
 * @param $context
1537
 *   An associative array containing:
1538
 *   - entity_type: The type of the entity the field is attached to.
1539
 *   - field: A field data structure.
1540
 */
1541
function hook_field_available_languages_alter(&$languages, $context) {
1542
  // Add an unavailable language.
1543
  $languages[] = 'xx';
1544

    
1545
  // Remove an available language.
1546
  $index = array_search('yy', $languages);
1547
  unset($languages[$index]);
1548
}
1549

    
1550
/**
1551
 * Act on field_attach_create_bundle().
1552
 *
1553
 * This hook is invoked after the field module has performed the operation.
1554
 *
1555
 * See field_attach_create_bundle() for details and arguments.
1556
 */
1557
function hook_field_attach_create_bundle($entity_type, $bundle) {
1558
  // When a new bundle is created, the menu needs to be rebuilt to add the
1559
  // Field UI menu item tabs.
1560
  variable_set('menu_rebuild_needed', TRUE);
1561
}
1562

    
1563
/**
1564
 * Act on field_attach_rename_bundle().
1565
 *
1566
 * This hook is invoked after the field module has performed the operation.
1567
 *
1568
 * See field_attach_rename_bundle() for details and arguments.
1569
 */
1570
function hook_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) {
1571
  // Update the extra weights variable with new information.
1572
  if ($bundle_old !== $bundle_new) {
1573
    $extra_weights = variable_get('field_extra_weights', array());
1574
    if (isset($info[$entity_type][$bundle_old])) {
1575
      $extra_weights[$entity_type][$bundle_new] = $extra_weights[$entity_type][$bundle_old];
1576
      unset($extra_weights[$entity_type][$bundle_old]);
1577
      variable_set('field_extra_weights', $extra_weights);
1578
    }
1579
  }
1580
}
1581

    
1582
/**
1583
 * Act on field_attach_delete_bundle.
1584
 *
1585
 * This hook is invoked after the field module has performed the operation.
1586
 *
1587
 * @param $entity_type
1588
 *   The type of entity; for example, 'node' or 'user'.
1589
 * @param $bundle
1590
 *   The bundle that was just deleted.
1591
 * @param $instances
1592
 *   An array of all instances that existed for the bundle before it was
1593
 *   deleted.
1594
 */
1595
function hook_field_attach_delete_bundle($entity_type, $bundle, $instances) {
1596
  // Remove the extra weights variable information for this bundle.
1597
  $extra_weights = variable_get('field_extra_weights', array());
1598
  if (isset($extra_weights[$entity_type][$bundle])) {
1599
    unset($extra_weights[$entity_type][$bundle]);
1600
    variable_set('field_extra_weights', $extra_weights);
1601
  }
1602
}
1603

    
1604
/**
1605
 * @} End of "defgroup field_attach".
1606
 */
1607

    
1608
/**
1609
 * @addtogroup field_storage
1610
 * @{
1611
 */
1612

    
1613
/**
1614
 * Expose Field API storage backends.
1615
 *
1616
 * @return
1617
 *   An array describing the storage backends implemented by the module.
1618
 *   The keys are storage backend names. To avoid name clashes, storage backend
1619
 *   names should be prefixed with the name of the module that exposes them.
1620
 *   The values are arrays describing the storage backend, with the following
1621
 *   key/value pairs:
1622
 *   - label: The human-readable name of the storage backend.
1623
 *   - description: A short description for the storage backend.
1624
 *   - settings: An array whose keys are the names of the settings available
1625
 *     for the storage backend, and whose values are the default values for
1626
 *     those settings.
1627
 */
1628
function hook_field_storage_info() {
1629
  return array(
1630
    'field_sql_storage' => array(
1631
      'label' => t('Default SQL storage'),
1632
      'description' => t('Stores fields in the local SQL database, using per-field tables.'),
1633
      'settings' => array(),
1634
    ),
1635
  );
1636
}
1637

    
1638
/**
1639
 * Perform alterations on Field API storage types.
1640
 *
1641
 * @param $info
1642
 *   Array of informations on storage types exposed by
1643
 *   hook_field_field_storage_info() implementations.
1644
 */
1645
function hook_field_storage_info_alter(&$info) {
1646
  // Add a setting to a storage type.
1647
  $info['field_sql_storage']['settings'] += array(
1648
    'mymodule_additional_setting' => 'default value',
1649
  );
1650
}
1651

    
1652
/**
1653
 * Reveal the internal details about the storage for a field.
1654
 *
1655
 * For example, an SQL storage module might return the Schema API structure for
1656
 * the table. A key/value storage module might return the server name,
1657
 * authentication credentials, and bin name.
1658
 *
1659
 * Field storage modules are not obligated to implement this hook. Modules
1660
 * that rely on these details must only use them for read operations.
1661
 *
1662
 * @param $field
1663
 *   A field structure.
1664
 *
1665
 * @return
1666
 *   An array of details.
1667
 *    - The first dimension is a store type (sql, solr, etc).
1668
 *    - The second dimension indicates the age of the values in the store
1669
 *      FIELD_LOAD_CURRENT or FIELD_LOAD_REVISION.
1670
 *    - Other dimensions are specific to the field storage module.
1671
 *
1672
 * @see hook_field_storage_details_alter()
1673
 */
1674
function hook_field_storage_details($field) {
1675
  $details = array();
1676

    
1677
  // Add field columns.
1678
  foreach ((array) $field['columns'] as $column_name => $attributes) {
1679
    $real_name = _field_sql_storage_columnname($field['field_name'], $column_name);
1680
    $columns[$column_name] = $real_name;
1681
  }
1682
  return array(
1683
    'sql' => array(
1684
      FIELD_LOAD_CURRENT => array(
1685
        _field_sql_storage_tablename($field) => $columns,
1686
      ),
1687
      FIELD_LOAD_REVISION => array(
1688
        _field_sql_storage_revision_tablename($field) => $columns,
1689
      ),
1690
    ),
1691
  );
1692
}
1693

    
1694
/**
1695
 * Perform alterations on Field API storage details.
1696
 *
1697
 * @param $details
1698
 *   An array of storage details for fields as exposed by
1699
 *   hook_field_storage_details() implementations.
1700
 * @param $field
1701
 *   A field structure.
1702
 *
1703
 * @see hook_field_storage_details()
1704
 */
1705
function hook_field_storage_details_alter(&$details, $field) {
1706
  if ($field['field_name'] == 'field_of_interest') {
1707
    $columns = array();
1708
    foreach ((array) $field['columns'] as $column_name => $attributes) {
1709
      $columns[$column_name] = $column_name;
1710
    }
1711
    $details['drupal_variables'] = array(
1712
      FIELD_LOAD_CURRENT => array(
1713
        'moon' => $columns,
1714
      ),
1715
      FIELD_LOAD_REVISION => array(
1716
        'mars' => $columns,
1717
      ),
1718
    );
1719
  }
1720
}
1721

    
1722
/**
1723
 * Load field data for a set of entities.
1724
 *
1725
 * This hook is invoked from field_attach_load() to ask the field storage
1726
 * module to load field data.
1727
 *
1728
 * Modules implementing this hook should load field values and add them to
1729
 * objects in $entities. Fields with no values should be added as empty
1730
 * arrays.
1731
 *
1732
 * @param $entity_type
1733
 *   The type of entity, such as 'node' or 'user'.
1734
 * @param $entities
1735
 *   The array of entity objects to add fields to, keyed by entity ID.
1736
 * @param $age
1737
 *   FIELD_LOAD_CURRENT to load the most recent revision for all fields, or
1738
 *   FIELD_LOAD_REVISION to load the version indicated by each entity.
1739
 * @param $fields
1740
 *   An array listing the fields to be loaded. The keys of the array are field
1741
 *   IDs, and the values of the array are the entity IDs (or revision IDs,
1742
 *   depending on the $age parameter) to add each field to.
1743
 * @param $options
1744
 *   An associative array of additional options, with the following keys:
1745
 *   - deleted: If TRUE, deleted fields should be loaded as well as
1746
 *     non-deleted fields. If unset or FALSE, only non-deleted fields should be
1747
 *     loaded.
1748
 */
1749
function hook_field_storage_load($entity_type, $entities, $age, $fields, $options) {
1750
  $load_current = $age == FIELD_LOAD_CURRENT;
1751

    
1752
  foreach ($fields as $field_id => $ids) {
1753
    // By the time this hook runs, the relevant field definitions have been
1754
    // populated and cached in FieldInfo, so calling field_info_field_by_id()
1755
    // on each field individually is more efficient than loading all fields in
1756
    // memory upfront with field_info_field_by_ids().
1757
    $field = field_info_field_by_id($field_id);
1758
    $field_name = $field['field_name'];
1759
    $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field);
1760

    
1761
    $query = db_select($table, 't')
1762
      ->fields('t')
1763
      ->condition('entity_type', $entity_type)
1764
      ->condition($load_current ? 'entity_id' : 'revision_id', $ids, 'IN')
1765
      ->condition('language', field_available_languages($entity_type, $field), 'IN')
1766
      ->orderBy('delta');
1767

    
1768
    if (empty($options['deleted'])) {
1769
      $query->condition('deleted', 0);
1770
    }
1771

    
1772
    $results = $query->execute();
1773

    
1774
    $delta_count = array();
1775
    foreach ($results as $row) {
1776
      if (!isset($delta_count[$row->entity_id][$row->language])) {
1777
        $delta_count[$row->entity_id][$row->language] = 0;
1778
      }
1779

    
1780
      if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta_count[$row->entity_id][$row->language] < $field['cardinality']) {
1781
        $item = array();
1782
        // For each column declared by the field, populate the item
1783
        // from the prefixed database column.
1784
        foreach ($field['columns'] as $column => $attributes) {
1785
          $column_name = _field_sql_storage_columnname($field_name, $column);
1786
          $item[$column] = $row->$column_name;
1787
        }
1788

    
1789
        // Add the item to the field values for the entity.
1790
        $entities[$row->entity_id]->{$field_name}[$row->language][] = $item;
1791
        $delta_count[$row->entity_id][$row->language]++;
1792
      }
1793
    }
1794
  }
1795
}
1796

    
1797
/**
1798
 * Write field data for an entity.
1799
 *
1800
 * This hook is invoked from field_attach_insert() and field_attach_update(),
1801
 * to ask the field storage module to save field data.
1802
 *
1803
 * @param $entity_type
1804
 *   The entity type of entity, such as 'node' or 'user'.
1805
 * @param $entity
1806
 *   The entity on which to operate.
1807
 * @param $op
1808
 *   FIELD_STORAGE_UPDATE when updating an existing entity,
1809
 *   FIELD_STORAGE_INSERT when inserting a new entity.
1810
 * @param $fields
1811
 *   An array listing the fields to be written. The keys and values of the
1812
 *   array are field IDs.
1813
 */
1814
function hook_field_storage_write($entity_type, $entity, $op, $fields) {
1815
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
1816
  if (!isset($vid)) {
1817
    $vid = $id;
1818
  }
1819

    
1820
  foreach ($fields as $field_id) {
1821
    $field = field_info_field_by_id($field_id);
1822
    $field_name = $field['field_name'];
1823
    $table_name = _field_sql_storage_tablename($field);
1824
    $revision_name = _field_sql_storage_revision_tablename($field);
1825

    
1826
    $all_languages = field_available_languages($entity_type, $field);
1827
    $field_languages = array_intersect($all_languages, array_keys((array) $entity->$field_name));
1828

    
1829
    // Delete and insert, rather than update, in case a value was added.
1830
    if ($op == FIELD_STORAGE_UPDATE) {
1831
      // Delete languages present in the incoming $entity->$field_name.
1832
      // Delete all languages if $entity->$field_name is empty.
1833
      $languages = !empty($entity->$field_name) ? $field_languages : $all_languages;
1834
      if ($languages) {
1835
        db_delete($table_name)
1836
          ->condition('entity_type', $entity_type)
1837
          ->condition('entity_id', $id)
1838
          ->condition('language', $languages, 'IN')
1839
          ->execute();
1840
        db_delete($revision_name)
1841
          ->condition('entity_type', $entity_type)
1842
          ->condition('entity_id', $id)
1843
          ->condition('revision_id', $vid)
1844
          ->condition('language', $languages, 'IN')
1845
          ->execute();
1846
      }
1847
    }
1848

    
1849
    // Prepare the multi-insert query.
1850
    $do_insert = FALSE;
1851
    $columns = array('entity_type', 'entity_id', 'revision_id', 'bundle', 'delta', 'language');
1852
    foreach ($field['columns'] as $column => $attributes) {
1853
      $columns[] = _field_sql_storage_columnname($field_name, $column);
1854
    }
1855
    $query = db_insert($table_name)->fields($columns);
1856
    $revision_query = db_insert($revision_name)->fields($columns);
1857

    
1858
    foreach ($field_languages as $langcode) {
1859
      $items = (array) $entity->{$field_name}[$langcode];
1860
      $delta_count = 0;
1861
      foreach ($items as $delta => $item) {
1862
        // We now know we have someting to insert.
1863
        $do_insert = TRUE;
1864
        $record = array(
1865
          'entity_type' => $entity_type,
1866
          'entity_id' => $id,
1867
          'revision_id' => $vid,
1868
          'bundle' => $bundle,
1869
          'delta' => $delta,
1870
          'language' => $langcode,
1871
        );
1872
        foreach ($field['columns'] as $column => $attributes) {
1873
          $record[_field_sql_storage_columnname($field_name, $column)] = isset($item[$column]) ? $item[$column] : NULL;
1874
        }
1875
        $query->values($record);
1876
        if (isset($vid)) {
1877
          $revision_query->values($record);
1878
        }
1879

    
1880
        if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && ++$delta_count == $field['cardinality']) {
1881
          break;
1882
        }
1883
      }
1884
    }
1885

    
1886
    // Execute the query if we have values to insert.
1887
    if ($do_insert) {
1888
      $query->execute();
1889
      $revision_query->execute();
1890
    }
1891
  }
1892
}
1893

    
1894
/**
1895
 * Delete all field data for an entity.
1896
 *
1897
 * This hook is invoked from field_attach_delete() to ask the field storage
1898
 * module to delete field data.
1899
 *
1900
 * @param $entity_type
1901
 *   The entity type of entity, such as 'node' or 'user'.
1902
 * @param $entity
1903
 *   The entity on which to operate.
1904
 * @param $fields
1905
 *   An array listing the fields to delete. The keys and values of the
1906
 *   array are field IDs.
1907
 */
1908
function hook_field_storage_delete($entity_type, $entity, $fields) {
1909
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
1910

    
1911
  foreach (field_info_instances($entity_type, $bundle) as $instance) {
1912
    if (isset($fields[$instance['field_id']])) {
1913
      $field = field_info_field_by_id($instance['field_id']);
1914
      field_sql_storage_field_storage_purge($entity_type, $entity, $field, $instance);
1915
    }
1916
  }
1917
}
1918

    
1919
/**
1920
 * Delete a single revision of field data for an entity.
1921
 *
1922
 * This hook is invoked from field_attach_delete_revision() to ask the field
1923
 * storage module to delete field revision data.
1924
 *
1925
 * Deleting the current (most recently written) revision is not
1926
 * allowed as has undefined results.
1927
 *
1928
 * @param $entity_type
1929
 *   The entity type of entity, such as 'node' or 'user'.
1930
 * @param $entity
1931
 *   The entity on which to operate. The revision to delete is
1932
 *   indicated by the entity's revision ID property, as identified by
1933
 *   hook_fieldable_info() for $entity_type.
1934
 * @param $fields
1935
 *   An array listing the fields to delete. The keys and values of the
1936
 *   array are field IDs.
1937
 */
1938
function hook_field_storage_delete_revision($entity_type, $entity, $fields) {
1939
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
1940

    
1941
  if (isset($vid)) {
1942
    foreach ($fields as $field_id) {
1943
      $field = field_info_field_by_id($field_id);
1944
      $revision_name = _field_sql_storage_revision_tablename($field);
1945
      db_delete($revision_name)
1946
        ->condition('entity_type', $entity_type)
1947
        ->condition('entity_id', $id)
1948
        ->condition('revision_id', $vid)
1949
        ->execute();
1950
    }
1951
  }
1952
}
1953

    
1954
/**
1955
 * Execute an EntityFieldQuery.
1956
 *
1957
 * This hook is called to find the entities having certain entity and field
1958
 * conditions and sort them in the given field order. If the field storage
1959
 * engine also handles property sorts and orders, it should unset those
1960
 * properties in the called object to signal that those have been handled.
1961
 *
1962
 * @param EntityFieldQuery $query
1963
 *   An EntityFieldQuery.
1964
 *
1965
 * @return
1966
 *   See EntityFieldQuery::execute() for the return values.
1967
 */
1968
function hook_field_storage_query($query) {
1969
  $groups = array();
1970
  if ($query->age == FIELD_LOAD_CURRENT) {
1971
    $tablename_function = '_field_sql_storage_tablename';
1972
    $id_key = 'entity_id';
1973
  }
1974
  else {
1975
    $tablename_function = '_field_sql_storage_revision_tablename';
1976
    $id_key = 'revision_id';
1977
  }
1978
  $table_aliases = array();
1979
  // Add tables for the fields used.
1980
  foreach ($query->fields as $key => $field) {
1981
    $tablename = $tablename_function($field);
1982
    // Every field needs a new table.
1983
    $table_alias = $tablename . $key;
1984
    $table_aliases[$key] = $table_alias;
1985
    if ($key) {
1986
      $select_query->join($tablename, $table_alias, "$table_alias.entity_type = $field_base_table.entity_type AND $table_alias.$id_key = $field_base_table.$id_key");
1987
    }
1988
    else {
1989
      $select_query = db_select($tablename, $table_alias);
1990
      $select_query->addTag('entity_field_access');
1991
      $select_query->addMetaData('base_table', $tablename);
1992
      $select_query->fields($table_alias, array('entity_type', 'entity_id', 'revision_id', 'bundle'));
1993
      $field_base_table = $table_alias;
1994
    }
1995
    if ($field['cardinality'] != 1) {
1996
      $select_query->distinct();
1997
    }
1998
  }
1999

    
2000
  // Add field conditions.
2001
  foreach ($query->fieldConditions as $key => $condition) {
2002
    $table_alias = $table_aliases[$key];
2003
    $field = $condition['field'];
2004
    // Add the specified condition.
2005
    $sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $condition['column']);
2006
    $query->addCondition($select_query, $sql_field, $condition);
2007
    // Add delta / language group conditions.
2008
    foreach (array('delta', 'language') as $column) {
2009
      if (isset($condition[$column . '_group'])) {
2010
        $group_name = $condition[$column . '_group'];
2011
        if (!isset($groups[$column][$group_name])) {
2012
          $groups[$column][$group_name] = $table_alias;
2013
        }
2014
        else {
2015
          $select_query->where("$table_alias.$column = " . $groups[$column][$group_name] . ".$column");
2016
        }
2017
      }
2018
    }
2019
  }
2020

    
2021
  if (isset($query->deleted)) {
2022
    $select_query->condition("$field_base_table.deleted", (int) $query->deleted);
2023
  }
2024

    
2025
  // Is there a need to sort the query by property?
2026
  $has_property_order = FALSE;
2027
  foreach ($query->order as $order) {
2028
    if ($order['type'] == 'property') {
2029
      $has_property_order = TRUE;
2030
    }
2031
  }
2032

    
2033
  if ($query->propertyConditions || $has_property_order) {
2034
    if (empty($query->entityConditions['entity_type']['value'])) {
2035
      throw new EntityFieldQueryException('Property conditions and orders must have an entity type defined.');
2036
    }
2037
    $entity_type = $query->entityConditions['entity_type']['value'];
2038
    $entity_base_table = _field_sql_storage_query_join_entity($select_query, $entity_type, $field_base_table);
2039
    $query->entityConditions['entity_type']['operator'] = '=';
2040
    foreach ($query->propertyConditions as $property_condition) {
2041
      $query->addCondition($select_query, "$entity_base_table." . $property_condition['column'], $property_condition);
2042
    }
2043
  }
2044
  foreach ($query->entityConditions as $key => $condition) {
2045
    $query->addCondition($select_query, "$field_base_table.$key", $condition);
2046
  }
2047

    
2048
  // Order the query.
2049
  foreach ($query->order as $order) {
2050
    if ($order['type'] == 'entity') {
2051
      $key = $order['specifier'];
2052
      $select_query->orderBy("$field_base_table.$key", $order['direction']);
2053
    }
2054
    elseif ($order['type'] == 'field') {
2055
      $specifier = $order['specifier'];
2056
      $field = $specifier['field'];
2057
      $table_alias = $table_aliases[$specifier['index']];
2058
      $sql_field = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $specifier['column']);
2059
      $select_query->orderBy($sql_field, $order['direction']);
2060
    }
2061
    elseif ($order['type'] == 'property') {
2062
      $select_query->orderBy("$entity_base_table." . $order['specifier'], $order['direction']);
2063
    }
2064
  }
2065

    
2066
  return $query->finishQuery($select_query, $id_key);
2067
}
2068

    
2069
/**
2070
 * Act on creation of a new field.
2071
 *
2072
 * This hook is invoked from field_create_field() to ask the field storage
2073
 * module to save field information and prepare for storing field instances.
2074
 * If there is a problem, the field storage module should throw an exception.
2075
 *
2076
 * @param $field
2077
 *   The field structure being created.
2078
 */
2079
function hook_field_storage_create_field($field) {
2080
  $schema = _field_sql_storage_schema($field);
2081
  foreach ($schema as $name => $table) {
2082
    db_create_table($name, $table);
2083
  }
2084
  drupal_get_schema(NULL, TRUE);
2085
}
2086

    
2087
/**
2088
 * Act on deletion of a field.
2089
 *
2090
 * This hook is invoked from field_delete_field() to ask the field storage
2091
 * module to mark all information stored in the field for deletion.
2092
 *
2093
 * @param $field
2094
 *   The field being deleted.
2095
 */
2096
function hook_field_storage_delete_field($field) {
2097
  // Mark all data associated with the field for deletion.
2098
  $field['deleted'] = 0;
2099
  $table = _field_sql_storage_tablename($field);
2100
  $revision_table = _field_sql_storage_revision_tablename($field);
2101
  db_update($table)
2102
    ->fields(array('deleted' => 1))
2103
    ->execute();
2104

    
2105
  // Move the table to a unique name while the table contents are being deleted.
2106
  $field['deleted'] = 1;
2107
  $new_table = _field_sql_storage_tablename($field);
2108
  $revision_new_table = _field_sql_storage_revision_tablename($field);
2109
  db_rename_table($table, $new_table);
2110
  db_rename_table($revision_table, $revision_new_table);
2111
  drupal_get_schema(NULL, TRUE);
2112
}
2113

    
2114
/**
2115
 * Act on deletion of a field instance.
2116
 *
2117
 * This hook is invoked from field_delete_instance() to ask the field storage
2118
 * module to mark all information stored for the field instance for deletion.
2119
 *
2120
 * @param $instance
2121
 *   The instance being deleted.
2122
 */
2123
function hook_field_storage_delete_instance($instance) {
2124
  $field = field_info_field($instance['field_name']);
2125
  $table_name = _field_sql_storage_tablename($field);
2126
  $revision_name = _field_sql_storage_revision_tablename($field);
2127
  db_update($table_name)
2128
    ->fields(array('deleted' => 1))
2129
    ->condition('entity_type', $instance['entity_type'])
2130
    ->condition('bundle', $instance['bundle'])
2131
    ->execute();
2132
  db_update($revision_name)
2133
    ->fields(array('deleted' => 1))
2134
    ->condition('entity_type', $instance['entity_type'])
2135
    ->condition('bundle', $instance['bundle'])
2136
    ->execute();
2137
}
2138

    
2139
/**
2140
 * Act before the storage backends load field data.
2141
 *
2142
 * This hook allows modules to load data before the Field Storage API,
2143
 * optionally preventing the field storage module from doing so.
2144
 *
2145
 * This lets 3rd party modules override, mirror, shard, or otherwise store a
2146
 * subset of fields in a different way than the current storage engine.
2147
 * Possible use cases include per-bundle storage, per-combo-field storage, etc.
2148
 *
2149
 * Modules implementing this hook should load field values and add them to
2150
 * objects in $entities. Fields with no values should be added as empty
2151
 * arrays. In addition, fields loaded should be added as keys to $skip_fields.
2152
 *
2153
 * @param $entity_type
2154
 *   The type of entity, such as 'node' or 'user'.
2155
 * @param $entities
2156
 *   The array of entity objects to add fields to, keyed by entity ID.
2157
 * @param $age
2158
 *   FIELD_LOAD_CURRENT to load the most recent revision for all fields, or
2159
 *   FIELD_LOAD_REVISION to load the version indicated by each entity.
2160
 * @param $skip_fields
2161
 *   An array keyed by field IDs whose data has already been loaded and
2162
 *   therefore should not be loaded again. Add a key to this array to indicate
2163
 *   that your module has already loaded a field.
2164
 * @param $options
2165
 *   An associative array of additional options, with the following keys:
2166
 *   - field_id: The field ID that should be loaded. If unset, all fields
2167
 *     should be loaded.
2168
 *   - deleted: If TRUE, deleted fields should be loaded as well as
2169
 *     non-deleted fields. If unset or FALSE, only non-deleted fields should be
2170
 *     loaded.
2171
 */
2172
function hook_field_storage_pre_load($entity_type, $entities, $age, &$skip_fields, $options) {
2173
  // @todo Needs function body.
2174
}
2175

    
2176
/**
2177
 * Act before the storage backends insert field data.
2178
 *
2179
 * This hook allows modules to store data before the Field Storage API,
2180
 * optionally preventing the field storage module from doing so.
2181
 *
2182
 * @param $entity_type
2183
 *   The type of $entity; for example, 'node' or 'user'.
2184
 * @param $entity
2185
 *   The entity with fields to save.
2186
 * @param $skip_fields
2187
 *   An array keyed by field IDs whose data has already been written and
2188
 *   therefore should not be written again. The values associated with these
2189
 *   keys are not specified.
2190
 * @return
2191
 *   Saved field IDs are set set as keys in $skip_fields.
2192
 */
2193
function hook_field_storage_pre_insert($entity_type, $entity, &$skip_fields) {
2194
  if ($entity_type == 'node' && $entity->status && _forum_node_check_node_type($entity)) {
2195
    $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
2196
    foreach ($entity->taxonomy_forums as $language) {
2197
      foreach ($language as $delta) {
2198
        $query->values(array(
2199
          'nid' => $entity->nid,
2200
          'title' => $entity->title,
2201
          'tid' => $delta['value'],
2202
          'sticky' => $entity->sticky,
2203
          'created' => $entity->created,
2204
          'comment_count' => 0,
2205
          'last_comment_timestamp' => $entity->created,
2206
        ));
2207
      }
2208
    }
2209
    $query->execute();
2210
  }
2211
}
2212

    
2213
/**
2214
 * Act before the storage backends update field data.
2215
 *
2216
 * This hook allows modules to store data before the Field Storage API,
2217
 * optionally preventing the field storage module from doing so.
2218
 *
2219
 * @param $entity_type
2220
 *   The type of $entity; for example, 'node' or 'user'.
2221
 * @param $entity
2222
 *   The entity with fields to save.
2223
 * @param $skip_fields
2224
 *   An array keyed by field IDs whose data has already been written and
2225
 *   therefore should not be written again. The values associated with these
2226
 *   keys are not specified.
2227
 * @return
2228
 *   Saved field IDs are set set as keys in $skip_fields.
2229
 */
2230
function hook_field_storage_pre_update($entity_type, $entity, &$skip_fields) {
2231
  $first_call = &drupal_static(__FUNCTION__, array());
2232

    
2233
  if ($entity_type == 'node' && $entity->status && _forum_node_check_node_type($entity)) {
2234
    // We don't maintain data for old revisions, so clear all previous values
2235
    // from the table. Since this hook runs once per field, per entity, make
2236
    // sure we only wipe values once.
2237
    if (!isset($first_call[$entity->nid])) {
2238
      $first_call[$entity->nid] = FALSE;
2239
      db_delete('forum_index')->condition('nid', $entity->nid)->execute();
2240
    }
2241
    // Only save data to the table if the node is published.
2242
    if ($entity->status) {
2243
      $query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
2244
      foreach ($entity->taxonomy_forums as $language) {
2245
        foreach ($language as $delta) {
2246
          $query->values(array(
2247
            'nid' => $entity->nid,
2248
            'title' => $entity->title,
2249
            'tid' => $delta['value'],
2250
            'sticky' => $entity->sticky,
2251
            'created' => $entity->created,
2252
            'comment_count' => 0,
2253
            'last_comment_timestamp' => $entity->created,
2254
          ));
2255
        }
2256
      }
2257
      $query->execute();
2258
      // The logic for determining last_comment_count is fairly complex, so
2259
      // call _forum_update_forum_index() too.
2260
      _forum_update_forum_index($entity->nid);
2261
    }
2262
  }
2263
}
2264

    
2265
/**
2266
 * Returns the maximum weight for the entity components handled by the module.
2267
 *
2268
 * Field API takes care of fields and 'extra_fields'. This hook is intended for
2269
 * third-party modules adding other entity components (e.g. field_group).
2270
 *
2271
 * @param $entity_type
2272
 *   The type of entity; e.g. 'node' or 'user'.
2273
 * @param $bundle
2274
 *   The bundle name.
2275
 * @param $context
2276
 *   The context for which the maximum weight is requested. Either 'form', or
2277
 *   the name of a view mode.
2278
 * @return
2279
 *   The maximum weight of the entity's components, or NULL if no components
2280
 *   were found.
2281
 */
2282
function hook_field_info_max_weight($entity_type, $bundle, $context) {
2283
  $weights = array();
2284

    
2285
  foreach (my_module_entity_additions($entity_type, $bundle, $context) as $addition) {
2286
    $weights[] = $addition['weight'];
2287
  }
2288

    
2289
  return $weights ? max($weights) : NULL;
2290
}
2291

    
2292
/**
2293
 * Alters the display settings of a field before it gets displayed.
2294
 *
2295
 * Note that instead of hook_field_display_alter(), which is called for all
2296
 * fields on all entity types, hook_field_display_ENTITY_TYPE_alter() may be
2297
 * used to alter display settings for fields on a specific entity type only.
2298
 *
2299
 * This hook is called once per field per displayed entity. If the result of the
2300
 * hook involves reading from the database, it is highly recommended to
2301
 * statically cache the information.
2302
 *
2303
 * @param $display
2304
 *   The display settings that will be used to display the field values, as
2305
 *   found in the 'display' key of $instance definitions.
2306
 * @param $context
2307
 *   An associative array containing:
2308
 *   - entity_type: The entity type; e.g., 'node' or 'user'.
2309
 *   - field: The field being rendered.
2310
 *   - instance: The instance being rendered.
2311
 *   - entity: The entity being rendered.
2312
 *   - view_mode: The view mode, e.g. 'full', 'teaser'...
2313
 *
2314
 * @see hook_field_display_ENTITY_TYPE_alter()
2315
 */
2316
function hook_field_display_alter(&$display, $context) {
2317
  // Leave field labels out of the search index.
2318
  // Note: The check against $context['entity_type'] == 'node' could be avoided
2319
  // by using hook_field_display_node_alter() instead of
2320
  // hook_field_display_alter(), resulting in less function calls when
2321
  // rendering non-node entities.
2322
  if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') {
2323
    $display['label'] = 'hidden';
2324
  }
2325
}
2326

    
2327
/**
2328
 * Alters the display settings of a field on a given entity type before it gets displayed.
2329
 *
2330
 * Modules can implement hook_field_display_ENTITY_TYPE_alter() to alter display
2331
 * settings for fields on a specific entity type, rather than implementing
2332
 * hook_field_display_alter().
2333
 *
2334
 * This hook is called once per field per displayed entity. If the result of the
2335
 * hook involves reading from the database, it is highly recommended to
2336
 * statically cache the information.
2337
 *
2338
 * @param $display
2339
 *   The display settings that will be used to display the field values, as
2340
 *   found in the 'display' key of $instance definitions.
2341
 * @param $context
2342
 *   An associative array containing:
2343
 *   - entity_type: The entity type; e.g., 'node' or 'user'.
2344
 *   - field: The field being rendered.
2345
 *   - instance: The instance being rendered.
2346
 *   - entity: The entity being rendered.
2347
 *   - view_mode: The view mode, e.g. 'full', 'teaser'...
2348
 *
2349
 * @see hook_field_display_alter()
2350
 */
2351
function hook_field_display_ENTITY_TYPE_alter(&$display, $context) {
2352
  // Leave field labels out of the search index.
2353
  if ($context['view_mode'] == 'search_index') {
2354
    $display['label'] = 'hidden';
2355
  }
2356
}
2357

    
2358
/**
2359
 * Alters the display settings of pseudo-fields before an entity is displayed.
2360
 *
2361
 * This hook is called once per displayed entity. If the result of the hook
2362
 * involves reading from the database, it is highly recommended to statically
2363
 * cache the information.
2364
 *
2365
 * @param $displays
2366
 *   An array of display settings for the pseudo-fields in the entity, keyed
2367
 *   by pseudo-field names.
2368
 * @param $context
2369
 *   An associative array containing:
2370
 *   - entity_type: The entity type; e.g., 'node' or 'user'.
2371
 *   - bundle: The bundle name.
2372
 *   - view_mode: The view mode, e.g. 'full', 'teaser'...
2373
 */
2374
function hook_field_extra_fields_display_alter(&$displays, $context) {
2375
  if ($context['entity_type'] == 'taxonomy_term' && $context['view_mode'] == 'full') {
2376
    $displays['description']['visible'] = FALSE;
2377
  }
2378
}
2379

    
2380
/**
2381
 * Alters the widget properties of a field instance on a given entity type
2382
 * before it gets displayed.
2383
 *
2384
 * Modules can implement hook_field_widget_properties_ENTITY_TYPE_alter() to
2385
 * alter the widget properties for fields on a specific entity type, rather than
2386
 * implementing hook_field_widget_properties_alter().
2387
 *
2388
 * This hook is called once per field per displayed widget entity. If the result
2389
 * of the hook involves reading from the database, it is highly recommended to
2390
 * statically cache the information.
2391
 *
2392
 * @param $widget
2393
 *   The instance's widget properties.
2394
 * @param $context
2395
 *   An associative array containing:
2396
 *   - entity_type: The entity type; e.g., 'node' or 'user'.
2397
 *   - entity: The entity object.
2398
 *   - field: The field that the widget belongs to.
2399
 *   - instance: The instance of the field.
2400
 *
2401
 * @see hook_field_widget_properties_alter()
2402
 */
2403
function hook_field_widget_properties_ENTITY_TYPE_alter(&$widget, $context) {
2404
  // Change a widget's type according to the time of day.
2405
  $field = $context['field'];
2406
  if ($field['field_name'] == 'field_foo') {
2407
    $time = date('H');
2408
    $widget['type'] = $time < 12 ? 'widget_am' : 'widget_pm';
2409
  }
2410
}
2411

    
2412
/**
2413
 * @} End of "addtogroup field_storage".
2414
 */
2415

    
2416
/**
2417
 * @addtogroup field_crud
2418
 * @{
2419
 */
2420

    
2421
/**
2422
 * Act on a field being created.
2423
 *
2424
 * This hook is invoked from field_create_field() after the field is created, to
2425
 * allow modules to act on field creation.
2426
 *
2427
 * @param $field
2428
 *   The field just created.
2429
 */
2430
function hook_field_create_field($field) {
2431
  // @todo Needs function body.
2432
}
2433

    
2434
/**
2435
 * Act on a field instance being created.
2436
 *
2437
 * This hook is invoked from field_create_instance() after the instance record
2438
 * is saved, so it cannot be used to modify the instance itself.
2439
 *
2440
 * @param $instance
2441
 *   The instance just created.
2442
 */
2443
function hook_field_create_instance($instance) {
2444
  // @todo Needs function body.
2445
}
2446

    
2447
/**
2448
 * Forbid a field update from occurring.
2449
 *
2450
 * Any module may forbid any update for any reason. For example, the
2451
 * field's storage module might forbid an update if it would change
2452
 * the storage schema while data for the field exists. A field type
2453
 * module might forbid an update if it would change existing data's
2454
 * semantics, or if there are external dependencies on field settings
2455
 * that cannot be updated.
2456
 *
2457
 * To forbid the update from occurring, throw a FieldUpdateForbiddenException.
2458
 *
2459
 * @param $field
2460
 *   The field as it will be post-update.
2461
 * @param $prior_field
2462
 *   The field as it is pre-update.
2463
 * @param $has_data
2464
 *   Whether any data already exists for this field.
2465
 */
2466
function hook_field_update_forbid($field, $prior_field, $has_data) {
2467
  // A 'list' field stores integer keys mapped to display values. If
2468
  // the new field will have fewer values, and any data exists for the
2469
  // abandoned keys, the field will have no way to display them. So,
2470
  // forbid such an update.
2471
  if ($has_data && count($field['settings']['allowed_values']) < count($prior_field['settings']['allowed_values'])) {
2472
    // Identify the keys that will be lost.
2473
    $lost_keys = array_diff(array_keys($field['settings']['allowed_values']), array_keys($prior_field['settings']['allowed_values']));
2474
    // If any data exist for those keys, forbid the update.
2475
    $query = new EntityFieldQuery();
2476
    $found = $query
2477
      ->fieldCondition($prior_field['field_name'], 'value', $lost_keys)
2478
      ->range(0, 1)
2479
      ->execute();
2480
    if ($found) {
2481
      throw new FieldUpdateForbiddenException("Cannot update a list field not to include keys with existing data");
2482
    }
2483
  }
2484
}
2485

    
2486
/**
2487
 * Act on a field being updated.
2488
 *
2489
 * This hook is invoked just after field is updated in field_update_field().
2490
 *
2491
 * @param $field
2492
 *   The field as it is post-update.
2493
 * @param $prior_field
2494
 *   The field as it was pre-update.
2495
 * @param $has_data
2496
 *   Whether any data already exists for this field.
2497
 */
2498
function hook_field_update_field($field, $prior_field, $has_data) {
2499
  // Reset the static value that keeps track of allowed values for list fields.
2500
  drupal_static_reset('list_allowed_values');
2501
}
2502

    
2503
/**
2504
 * Act on a field being deleted.
2505
 *
2506
 * This hook is invoked just after a field is deleted by field_delete_field().
2507
 *
2508
 * @param $field
2509
 *   The field just deleted.
2510
 */
2511
function hook_field_delete_field($field) {
2512
  // @todo Needs function body.
2513
}
2514

    
2515
/**
2516
 * Act on a field instance being updated.
2517
 *
2518
 * This hook is invoked from field_update_instance() after the instance record
2519
 * is saved, so it cannot be used by a module to modify the instance itself.
2520
 *
2521
 * @param $instance
2522
 *   The instance as it is post-update.
2523
 * @param $prior_instance
2524
 *   The instance as it was pre-update.
2525
 */
2526
function hook_field_update_instance($instance, $prior_instance) {
2527
  // @todo Needs function body.
2528
}
2529

    
2530
/**
2531
 * Act on a field instance being deleted.
2532
 *
2533
 * This hook is invoked from field_delete_instance() after the instance is
2534
 * deleted.
2535
 *
2536
 * @param $instance
2537
 *   The instance just deleted.
2538
 */
2539
function hook_field_delete_instance($instance) {
2540
  // @todo Needs function body.
2541
}
2542

    
2543
/**
2544
 * Act on field records being read from the database.
2545
 *
2546
 * This hook is invoked from field_read_fields() on each field being read.
2547
 *
2548
 * @param $field
2549
 *   The field record just read from the database.
2550
 */
2551
function hook_field_read_field($field) {
2552
  // @todo Needs function body.
2553
}
2554

    
2555
/**
2556
 * Act on a field record being read from the database.
2557
 *
2558
 * This hook is invoked from field_read_instances() on each instance being read.
2559
 *
2560
 * @param $instance
2561
 *   The instance record just read from the database.
2562
 */
2563
function hook_field_read_instance($instance) {
2564
  // @todo Needs function body.
2565
}
2566

    
2567
/**
2568
 * Acts when a field record is being purged.
2569
 *
2570
 * In field_purge_field(), after the field configuration has been
2571
 * removed from the database, the field storage module has had a chance to
2572
 * run its hook_field_storage_purge_field(), and the field info cache
2573
 * has been cleared, this hook is invoked on all modules to allow them to
2574
 * respond to the field being purged.
2575
 *
2576
 * @param $field
2577
 *   The field being purged.
2578
 */
2579
function hook_field_purge_field($field) {
2580
  db_delete('my_module_field_info')
2581
    ->condition('id', $field['id'])
2582
    ->execute();
2583
}
2584

    
2585
/**
2586
 * Acts when a field instance is being purged.
2587
 *
2588
 * In field_purge_instance(), after the field instance has been
2589
 * removed from the database, the field storage module has had a chance to
2590
 * run its hook_field_storage_purge_instance(), and the field info cache
2591
 * has been cleared, this hook is invoked on all modules to allow them to
2592
 * respond to the field instance being purged.
2593
 *
2594
 * @param $instance
2595
 *   The instance being purged.
2596
 */
2597
function hook_field_purge_instance($instance) {
2598
  db_delete('my_module_field_instance_info')
2599
    ->condition('id', $instance['id'])
2600
    ->execute();
2601
}
2602

    
2603
/**
2604
 * Remove field storage information when a field record is purged.
2605
 *
2606
 * Called from field_purge_field() to allow the field storage module
2607
 * to remove field information when a field is being purged.
2608
 *
2609
 * @param $field
2610
 *   The field being purged.
2611
 */
2612
function hook_field_storage_purge_field($field) {
2613
  $table_name = _field_sql_storage_tablename($field);
2614
  $revision_name = _field_sql_storage_revision_tablename($field);
2615
  db_drop_table($table_name);
2616
  db_drop_table($revision_name);
2617
}
2618

    
2619
/**
2620
 * Remove field storage information when a field instance is purged.
2621
 *
2622
 * Called from field_purge_instance() to allow the field storage module
2623
 * to remove field instance information when a field instance is being
2624
 * purged.
2625
 *
2626
 * @param $instance
2627
 *   The instance being purged.
2628
 */
2629
function hook_field_storage_purge_field_instance($instance) {
2630
  db_delete('my_module_field_instance_info')
2631
    ->condition('id', $instance['id'])
2632
    ->execute();
2633
}
2634

    
2635
/**
2636
 * Remove field storage information when field data is purged.
2637
 *
2638
 * Called from field_purge_data() to allow the field storage
2639
 * module to delete field data information.
2640
 *
2641
 * @param $entity_type
2642
 *   The type of $entity; for example, 'node' or 'user'.
2643
 * @param $entity
2644
 *   The pseudo-entity whose field data to delete.
2645
 * @param $field
2646
 *   The (possibly deleted) field whose data is being purged.
2647
 * @param $instance
2648
 *   The deleted field instance whose data is being purged.
2649
 */
2650
function hook_field_storage_purge($entity_type, $entity, $field, $instance) {
2651
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
2652

    
2653
  $table_name = _field_sql_storage_tablename($field);
2654
  $revision_name = _field_sql_storage_revision_tablename($field);
2655
  db_delete($table_name)
2656
    ->condition('entity_type', $entity_type)
2657
    ->condition('entity_id', $id)
2658
    ->execute();
2659
  db_delete($revision_name)
2660
    ->condition('entity_type', $entity_type)
2661
    ->condition('entity_id', $id)
2662
    ->execute();
2663
}
2664

    
2665
/**
2666
 * @} End of "addtogroup field_crud".
2667
 */
2668

    
2669
/**
2670
 * Determine whether the user has access to a given field.
2671
 *
2672
 * This hook is invoked from field_access() to let modules block access to
2673
 * operations on fields. If no module returns FALSE, the operation is allowed.
2674
 *
2675
 * @param $op
2676
 *   The operation to be performed. Possible values: 'edit', 'view'.
2677
 * @param $field
2678
 *   The field on which the operation is to be performed.
2679
 * @param $entity_type
2680
 *   The type of $entity; for example, 'node' or 'user'.
2681
 * @param $entity
2682
 *   (optional) The entity for the operation.
2683
 * @param $account
2684
 *   (optional) The account to check; if not given use currently logged in user.
2685
 *
2686
 * @return
2687
 *   TRUE if the operation is allowed, and FALSE if the operation is denied.
2688
 */
2689
function hook_field_access($op, $field, $entity_type, $entity, $account) {
2690
  if ($field['field_name'] == 'field_of_interest' && $op == 'edit') {
2691
    return user_access('edit field of interest', $account);
2692
  }
2693
  return TRUE;
2694
}
2695

    
2696
/**
2697
 * @} End of "addtogroup hooks".
2698
 */