field.attach.inc 50 KB
Newer Older
1
2
3
<?php
// $Id$

4
5
6
7
8
/**
 * @file
 * Field attach API, allowing objects (nodes, users, ...) to be 'fieldable'.
 */

9
/**
10
 * Exception thrown by field_attach_validate() on field validation errors.
11
12
13
14
15
16
17
18
19
20
21
 */
class FieldValidationException extends FieldException {
  var $errors;

 /**
  * Constructor for FieldValidationException.
  *
  * @param $errors
  *   An array of field validation errors, keyed by field name and
  *   delta that contains two keys:
  *   - 'error': A machine-readable error code string, prefixed by
22
  *     the field module name. A field widget may use this code to decide
23
24
25
26
27
28
29
30
31
32
  *     how to report the error.
  *   - 'message': A human-readable error message such as to be
  *     passed to form_error() for the appropriate form element.
  */
  function __construct($errors) {
    $this->errors = $errors;
    parent::__construct(t('Field validation errors'));
  }
}

33
34
35
36
37
38
39
40
41
/**
 * Exception thrown by field_attach_query() on unsupported query syntax.
 *
 * Some storage modules might not support the full range of the syntax for
 * conditions, and will raise a FieldQueryException when an usupported
 * condition was specified.
 */
class FieldQueryException extends FieldException {}

42
43
44
45
46
47
/**
 * @defgroup field_storage Field Storage API
 * @{
 * Implement a storage engine for Field API data.
 *
 * The Field Attach API uses the Field Storage API to perform all
48
49
 * "database access". Each Field Storage API hook function defines a
 * primitive database operation such as read, write, or delete. The
50
51
52
53
54
55
56
57
58
 * default field storage module, field_sql_storage.module, uses the
 * local SQL database to implement these operations, but alternative
 * field storage engines can choose to represent the data in SQL
 * differently or use a completely different storage mechanism such as
 * a cloud-based database.
 *
 * The Drupal system variable field_storage_module identifies the
 * field storage module to use.
 */
59
60

/**
61
62
 * Argument for an update operation.
 *
63
 * This is used in hook_field_storage_write when updating an
64
65
66
67
68
 * existing object.
 */
define('FIELD_STORAGE_UPDATE', 'update');

/**
69
70
 * Argument for an insert operation.
 *
71
72
73
74
 * This is used in hook_field_storage_write when inserting a new object.
 */
define('FIELD_STORAGE_INSERT', 'insert');

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
 * @} End of "defgroup field_storage"
 */

/**
 * @defgroup field_attach Field Attach API
 * @{
 * Operate on Field API data attached to Drupal objects.
 *
 * Field Attach API functions load, store, generate Form API
 * structures, display, and perform a vareity of other functions for
 * field data connected to individual objects.
 *
 * Field Attach API functions generally take $obj_type and $object
 * arguments along with additional function-specific arguments.
 * $obj_type is the type of the fieldable entity, such as 'node' or
91
 * 'user', and $object is the object itself. An individual object's
92
93
94
95
 * bundle, if any, is read from the object's bundle key property
 * identified by hook_fieldable_info() for $obj_type.
 *
 * Fieldable types call Field Attach API functions during their own
96
 * API calls; for example, node_load() calls field_attach_load(). A
97
 * fieldable type is not required to use all of the Field Attach
98
99
100
101
 * API functions.
 *
 * Most Field Attach API functions define a corresponding hook
 * function that allows any module to act on Field Attach operations
102
103
104
 * for any object after the operation is complete, and access or
 * modify all the field, form, or display data for that object and
 * operation. For example, field_attach_view() invokes
105
 * hook_field_attach_view_alter(). These all-module hooks are distinct from
106
107
108
109
110
 * those of the Field Types API, such as hook_field_load(), that are
 * only invoked for the module that defines a specific field type.
 *
 * field_attach_load(), field_attach_insert(), and
 * field_attach_update() also define pre-operation hooks,
111
 * e.g. hook_field_attach_pre_load(). These hooks run before the
112
113
114
 * corresponding Field Storage API and Field Type API operations.
 * They allow modules to define additional storage locations
 * (e.g. denormalizing, mirroring) for field data on a per-field
115
 * basis. They also allow modules to take over field storage
116
117
118
119
120
121
122
123
 * completely by instructing other implementations of the same hook
 * and the Field Storage API itself not to operate on specified
 * fields.
 *
 * The pre-operation hooks do not make the Field Storage API
 * irrelevant. The Field Storage API is essentially the "fallback
 * mechanism" for any fields that aren't being intercepted explicitly
 * by pre-operation hooks.
124
125
126
127
128
129
 */

/**
 * Invoke a field hook.
 *
 * @param $op
130
 *   Possible operations include:
131
132
133
134
135
136
137
138
139
140
141
 *   - form
 *   - validate
 *   - presave
 *   - insert
 *   - update
 *   - delete
 *   - delete revision
 *   - sanitize
 *   - view
 *   - prepare translation
 * @param $obj_type
142
 *   The type of $object; e.g. 'node' or 'user'.
143
 * @param $object
144
 *   The fully formed $obj_type object.
145
 * @param $a
146
 *   - The $form in the 'form' operation.
147
 *   - The value of $build_mode in the 'view' operation.
148
 *   - Otherwise NULL.
149
 * @param $b
150
151
 *   - The $form_state in the 'submit' operation.
 *   - Otherwise NULL.
152
153
 * @param $options
 *   An associative array of additional options, with the following keys:
154
155
156
157
 *  - 'field_name': The name of the field whose operation should be
 *    invoked. By default, the operation is invoked on all the fields
 *    in the object's bundle.  NOTE: This option is not compatible with
 *    the 'deleted' option; the 'field_id' option should be used
158
 *    instead.
159
160
 *  - 'field_id': The id of the field whose operation should be
 *    invoked. By default, the operation is invoked on all the fields
161
 *    in the objects' bundles.
162
163
 *  - 'default': A boolean value, specifying which implementation of
 *    the operation should be invoked.
164
165
166
167
168
169
 *    - if FALSE (default), the field types implementation of the operation
 *      will be invoked (hook_field_[op])
 *    - If TRUE, the default field implementation of the field operation
 *      will be invoked (field_default_[op])
 *    Internal use only. Do not explicitely set to TRUE, but use
 *    _field_invoke_default() instead.
170
171
172
 *  - 'deleted': If TRUE, the function will operate on deleted fields
 *    as well as non-deleted fields. If unset or FALSE, only
 *    non-deleted fields are operated on.
173
 */
174
175
176
177
function _field_invoke($op, $obj_type, $object, &$a = NULL, &$b = NULL, $options = array()) {
  // Merge default options.
  $default_options = array(
    'default' => FALSE,
178
    'deleted' => FALSE,
179
    'language' => NULL,
180
181
182
183
  );
  $options += $default_options;

  // Iterate through the object's field instances.
184
  $return = array();
185
  list(, , $bundle) = field_attach_extract_ids($obj_type, $object);
186
187
188
189
190
191
192
193
194

  if ($options['deleted']) {
    $instances = field_read_instances(array('bundle' => $bundle), array('include_deleted' => $options['deleted']));
  }
  else {
    $instances = field_info_instances($bundle);
  }

  foreach ($instances as $instance) {
195
196
    $field_name = $instance['field_name'];

197
    // When in 'single field' mode, only act on the specified field.
198
    if ((!isset($options['field_id']) || $options['field_id'] == $instance['field_id']) && (!isset($options['field_name']) || $options['field_name'] == $field_name)) {
199
      $field = field_info_field($field_name);
200
201
      $field_translations = array();
      $suggested_languages = empty($options['language']) ? NULL : array($options['language']);
202

203
204
205
206
      // Initialize field translations according to the available languages.
      foreach (field_multilingual_available_languages($obj_type, $field, $suggested_languages) as $langcode) {
        $field_translations[$langcode] = isset($object->{$field_name}[$langcode]) ? $object->{$field_name}[$langcode] : array();
      }
207
208
209
210

      // Invoke the field hook and collect results.
      $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
      if (drupal_function_exists($function)) {
211
212
213
214
215
216
217
218
219
220
221
222
        // Iterate over all the field translations.
        foreach ($field_translations as $langcode => $items) {
          $result = $function($obj_type, $object, $field, $instance, $langcode, $items, $a, $b);
          if (isset($result)) {
            // For hooks with array results, we merge results together.
            // For hooks with scalar results, we collect results in an array.
            if (is_array($result)) {
              $return = array_merge($return, $result);
            }
            else {
              $return[] = $result;
            }
223
          }
224
225
226
227
228

          // Populate $items back in the field values, but avoid replacing missing
          // fields with an empty array (those are not equivalent on update).
          if ($items !== array() || isset($object->{$field_name}[$langcode])) {
            $object->{$field_name}[$langcode] = $items;
229
230
          }
        }
231
232
233
234
235
236
237
      }
    }
  }

  return $return;
}

238
/**
239
 * Invoke a field hook across fields on multiple objects.
240
241
242
243
 *
 * @param $op
 *   Possible operations include:
 *   - load
244
245
 *   For all other operations, use _field_invoke() / field_invoke_default()
 *   instead.
246
247
248
249
250
251
252
253
254
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $objects
 *   An array of objects, keyed by object id.
 * @param $a
 *   - The $age parameter in the 'load' operation.
 *   - Otherwise NULL.
 * @param $b
 *   Currently always NULL.
255
256
 * @param $options
 *   An associative array of additional options, with the following keys:
257
258
259
260
261
262
263
264
265
 *  - 'field_name': The name of the field whose operation should be
 *    invoked. By default, the operation is invoked on all the fields
 *    in the object's bundle. NOTE: This option is not compatible with
 *    the 'deleted' option; the 'field_id' option should be used instead.
 *  - 'field_id': The id of the field whose operation should be
 *    invoked. By default, the operation is invoked on all the fields
 *    in the objects' bundles.
 *  - 'default': A boolean value, specifying which implementation of
 *    the operation should be invoked.
266
267
268
269
270
271
 *    - if FALSE (default), the field types implementation of the operation
 *      will be invoked (hook_field_[op])
 *    - If TRUE, the default field implementation of the field operation
 *      will be invoked (field_default_[op])
 *    Internal use only. Do not explicitely set to TRUE, but use
 *    _field_invoke_multiple_default() instead.
272
273
274
 *  - 'deleted': If TRUE, the function will operate on deleted fields
 *    as well as non-deleted fields. If unset or FALSE, only
 *    non-deleted fields are operated on.
275
276
277
 * @return
 *   An array of returned values keyed by object id.
 */
278
279
280
281
function _field_invoke_multiple($op, $obj_type, $objects, &$a = NULL, &$b = NULL, $options = array()) {
  // Merge default options.
  $default_options = array(
    'default' => FALSE,
282
    'deleted' => FALSE,
283
    'language' => NULL,
284
285
286
  );
  $options += $default_options;

287
288
289
290
291
292
  $fields = array();
  $grouped_instances = array();
  $grouped_objects = array();
  $grouped_items = array();
  $return = array();

293
294
  // Go through the objects and collect the fields on which the hook should be
  // invoked.
295
296
297
298
299
300
  //
  // We group fields by id, not by name, because this function can operate on
  // deleted fields which may have non-unique names. However, objects can only
  // contain data for a single field for each name, even if that field
  // is deleted, so we reference field data via the
  // $object->$field_name property.
301
302
  foreach ($objects as $object) {
    list($id, $vid, $bundle) = field_attach_extract_ids($obj_type, $object);
303
304
305
306
307
308
309
310
311
312

    if ($options['deleted']) {
      $instances = field_read_field(array('bundle' => $bundle, array('include_deleted' => $options['deleted'])));
    }
    else {
      $instances = field_info_instances($bundle);
    }

    foreach ($instances as $instance) {
      $field_id = $instance['field_id'];
313
      $field_name = $instance['field_name'];
314
      // When in 'single field' mode, only act on the specified field.
315
      if ((empty($options['field_id']) || $options['field_id'] == $field_id) && (empty($options['field_name']) || $options['field_name'] == $field_name)) {
316
        // Add the field to the list of fields to invoke the hook on.
317
318
        if (!isset($fields[$field_id])) {
          $fields[$field_id] = field_info_field_by_id($field_id);
319
320
        }
        // Group the corresponding instances and objects.
321
322
        $grouped_instances[$field_id][$id] = $instance;
        $grouped_objects[$field_id][$id] = $objects[$id];
323
324
        // Extract the field values into a separate variable, easily accessed
        // by hook implementations.
325
326
327
328
        $suggested_languages = empty($options['language']) ? NULL : array($options['language']);
        foreach (field_multilingual_available_languages($obj_type, $fields[$field_id], $suggested_languages) as $langcode) {
          $grouped_items[$field_id][$langcode][$id] = isset($object->{$field_name}[$langcode]) ? $object->{$field_name}[$langcode] : array();
        }
329
330
      }
    }
331
    // Initialize the return value for each object.
332
333
334
    $return[$id] = array();
  }

335
  // For each field, invoke the field hook and collect results.
336
337
  foreach ($fields as $field_id => $field) {
    $field_name = $field['field_name'];
338
339
    $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
    if (drupal_function_exists($function)) {
340
341
342
343
344
345
346
347
348
349
350
351
352
353
      // Iterate over all the field translations.
      foreach ($grouped_items[$field_id] as $langcode => $items) {
        $results = $function($obj_type, $grouped_objects[$field_id], $field, $grouped_instances[$field_id], $langcode, $grouped_items[$field_id][$langcode], $options, $a, $b);
        if (isset($results)) {
          // Collect results by object.
          // For hooks with array results, we merge results together.
          // For hooks with scalar results, we collect results in an array.
          foreach ($results as $id => $result) {
            if (is_array($result)) {
              $return[$id] = array_merge($return[$id], $result);
            }
            else {
              $return[$id][] = $result;
            }
354
355
356
357
358
359
360
          }
        }
      }
    }

    // Populate field values back in the objects, but avoid replacing missing
    // fields with an empty array (those are not equivalent on update).
361
    foreach ($grouped_objects[$field_id] as $id => $object) {
362
363
364
365
      foreach ($grouped_items[$field_id] as $langcode => $items) {
        if ($grouped_items[$field_id][$langcode][$id] !== array() || isset($object->{$field_name}[$langcode])) {
          $object->{$field_name}[$langcode] = $grouped_items[$field_id][$langcode][$id];
        }
366
367
368
369
370
371
372
      }
    }
  }

  return $return;
}

373
374
/**
 * Invoke field.module's version of a field hook.
375
376
377
378
379
380
 *
 * This function invokes the field_default_[op]() function.
 * Use _field_invoke() to invoke the field type implementation,
 * hook_field_[op]().
 *
 * @see _field_invoke().
381
 */
382
383
384
function _field_invoke_default($op, $obj_type, $object, &$a = NULL, &$b = NULL, $options = array()) {
  $options['default'] = TRUE;
  return _field_invoke($op, $obj_type, $object, $a, $b, $options);
385
386
}

387
388
/**
 * Invoke field.module's version of a field hook on multiple objects.
389
390
391
392
393
394
 *
 * This function invokes the field_default_[op]() function.
 * Use _field_invoke_multiple() to invoke the field type implementation,
 * hook_field_[op]().
 *
 * @see _field_invoke_multiple().
395
 */
396
397
398
function _field_invoke_multiple_default($op, $obj_type, $objects, &$a = NULL, &$b = NULL, $options = array()) {
  $options['default'] = TRUE;
  return _field_invoke_multiple($op, $obj_type, $objects, $a, $b, $options);
399
400
}

401
402
403
404
405
406
407
408
409
410
411
412
/**
 * Add form elements for all fields for an object to a form structure.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object for which to load form elements, used to initialize
 *   default form values.
 * @param $form
 *   The form structure to fill in.
 * @param $form_state
 *   An associative array containing the current state of the form.
413
414
415
 * @param $langcode
 *   The language the field values are going to be entered, if no language
 *   is provided the default site language will be used.
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
 * @return
 *   The form elements are added by reference at the top level of the $form
 *   parameter. Sample structure:
 *   @code
 *   array(
 *     '#fields' => array(
 *       // One sub-array per field appearing in the form, keyed by field name.
 *       'field_foo' => array (
 *         'field' => the field definition structure,
 *         'instance' => the field instance definition structure,
 *         'form_path' => an array of keys indicating the path to the field
 *           element within the full $form structure, used by the 'add more
 *           values' AHAH button. Any 3rd party module using form_alter() to
 *           modify the structure of the form should update this entry as well.
 *       ),
 *     ),
 *
 *     // One sub-array per field appearing in the form, keyed by field name.
 *     // The structure of the array differs slightly depending on whether the
 *     // widget is 'single-value' (provides the input for one field value,
 *     // most common case), and will therefore be repeated as many times as
 *     // needed, or 'multiple-values' (one single widget allows the input of
 *     // several values, e.g checkboxes, select box...).
439
440
441
442
443
 *     // The sub-array is nested into a $langcode key where $langcode has the
 *     // same value of the $langcode parameter above. This allow us to match
 *     // the field data structure ($field_name[$langcode][$delta][$column]).
 *     // The '#language' key holds the same value of $langcode and it is used
 *     // to access the field sub-array when $langcode is unknown.
444
445
 *     'field_foo' => array(
 *       '#tree' => TRUE,
446
447
 *       '#language' => $langcode,
 *       $langcode => array(
448
 *         '#field_name' => the name of the field,
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
 *         '#tree' => TRUE,
 *         '#required' => whether or not the field is required,
 *         '#title' => the label of the field instance,
 *         '#description' => the description text for the field instance,
 *
 *         // Only for 'single' widgets:
 *         '#theme' => 'field_multiple_value_form',
 *         '#multiple' => the field cardinality,
 *         // One sub-array per copy of the widget, keyed by delta.
 *         0 => array(
 *           '#title' => the title to be displayed by the widget,
 *           '#default_value' => the field value for delta 0,
 *           '#required' => whether the widget should be marked required,
 *           '#delta' => 0,
 *           '#field_name' => the name of the field,
 *           '#bundle' => the name of the bundle,
 *           '#columns' => the array of field columns,
 *           // The remaining elements in the sub-array depend on the widget.
 *           '#type' => the type of the widget,
 *           ...
 *         ),
 *         1 => array(
 *           ...
 *         ),
 *
 *         // Only for multiple widgets:
 *         '#bundle' => $instance['bundle'],
 *         '#columns'  => array_keys($field['columns']),
477
478
479
480
481
482
483
484
 *         // The remaining elements in the sub-array depend on the widget.
 *         '#type' => the type of the widget,
 *         ...
 *       ),
 *       ...
 *     ),
 *   )
 *   @endcode
485
 */
486
487
488
489
function field_attach_form($obj_type, $object, &$form, &$form_state, $langcode = NULL) {
  // If no language is provided use the default site language.
  $options = array('language' => field_multilingual_valid_language($langcode));
  $form += (array) _field_invoke_default('form', $obj_type, $object, $form, $form_state, $options);
490

491
492
493
494
495
  // Add custom weight handling.
  list($id, $vid, $bundle) = field_attach_extract_ids($obj_type, $object);
  $form['#pre_render'][] = '_field_extra_weights_pre_render';
  $form['#extra_fields'] = field_extra_fields($bundle);

496
497
498
499
500
501
502
503
504
505
506
507
  // Let other modules make changes to the form.
  foreach (module_implements('field_attach_form') as $module) {
    $function = $module . '_field_attach_form';
    $function($obj_type, $object, $form, $form_state);
  }
}

/**
 * Load all fields for the most current version of each of a set of
 * objects of a single object type.
 *
 * @param $obj_type
508
 *   The type of $object; e.g. 'node' or 'user'.
509
 * @param $objects
510
 *   An array of objects for which to load fields, keyed by object id.
511
512
 *   Each object needs to have its 'bundle', 'id' and (if applicable)
 *   'revision' keys filled.
513
514
515
 * @param $age
 *   FIELD_LOAD_CURRENT to load the most recent revision for all
 *   fields, or FIELD_LOAD_REVISION to load the version indicated by
516
 *   each object. Defaults to FIELD_LOAD_CURRENT; use
517
 *   field_attach_load_revision() instead of passing FIELD_LOAD_REVISION.
518
519
 * @param $options
 *   An associative array of additional options, with the following keys:
520
521
522
 *  - 'field_id': The field id that should be loaded, instead of
 *    loading all fields, for each object. Note that returned objects
 *    may contain data for other fields, for example if they are read
523
 *    from a cache.
524
525
 *  - 'deleted': If TRUE, the function will operate on deleted fields
 *    as well as non-deleted fields. If unset or FALSE, only
526
 *    non-deleted fields are operated on.
527
 * @returns
528
529
 *   Loaded field values are added to $objects. Fields with no values should be
 *   set as an empty array.
530
 */
531
function field_attach_load($obj_type, $objects, $age = FIELD_LOAD_CURRENT, $options = array()) {
532
  $load_current = $age == FIELD_LOAD_CURRENT;
533

534
535
536
537
538
539
  // Merge default options.
  $default_options = array(
    'deleted' => FALSE,
  );
  $options += $default_options;

540
  $info = field_info_fieldable_types($obj_type);
541
542
543
  // Only the most current revision of non-deleted fields for
  // cacheable fieldable types can be cached.
  $cache_read = $load_current && $info['cacheable'] && empty($options['deleted']);
544
  // In addition, do not write to the cache when loading a single field.
545
  $cache_write = $cache_read && !isset($options['field_id']);
546

547
548
549
550
551
552
553
  if (empty($objects)) {
    return;
  }

  // Assume all objects will need to be queried. Objects found in the cache
  // will be removed from the list.
  $queried_objects = $objects;
554

555
  // Fetch available objects from cache, if applicable.
556
  if ($cache_read) {
557
558
559
560
561
562
563
564
    // Build the list of cache entries to retrieve.
    $cids = array();
    foreach ($objects as $id => $object) {
      $cids[] = "field:$obj_type:$id";
    }
    $cache = cache_get_multiple($cids, 'cache_field');
    // Put the cached field values back into the objects and remove them from
    // the list of objects to query.
565
566
    foreach ($objects as $id => $object) {
      $cid = "field:$obj_type:$id";
567
568
569
570
      if (isset($cache[$cid])) {
        unset($queried_objects[$id]);
        foreach ($cache[$cid]->data as $field_name => $values) {
          $object->$field_name = $values;
571
572
        }
      }
573
    }
574
575
  }

576
  // Fetch other objects from their storage location.
577
  if ($queried_objects) {
578
    // The invoke order is:
579
580
    // - hook_field_attach_pre_load()
    // - storage engine's hook_field_storage_load()
581
    // - field-type module's hook_field_load()
582
583
    // - hook_field_attach_load()

584
    // Invoke hook_field_attach_pre_load(): let any module load field
585
586
587
588
    // data before the storage engine, accumulating along the way.
    $skip_fields = array();
    foreach (module_implements('field_attach_pre_load') as $module) {
      $function = $module . '_field_attach_pre_load';
589
      $function($obj_type, $queried_objects, $age, $skip_fields, $options);
590
591
592
593
    }

    // Invoke the storage engine's hook_field_storage_load(): the field storage
    // engine loads the rest.
594
    module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_load', $obj_type, $queried_objects, $age, $skip_fields, $options);
595

596
    // Invoke field-type module's hook_field_load().
597
    _field_invoke_multiple('load', $obj_type, $queried_objects, $age, $options);
598
599
600
601
602

    // Invoke hook_field_attach_load(): let other modules act on loading the
    // object.
    foreach (module_implements('field_attach_load') as $module) {
      $function = $module . '_field_attach_load';
603
      $function($obj_type, $queried_objects, $age, $options);
604
    }
605

606
    // Build cache data.
607
    if ($cache_write) {
608
609
610
611
612
613
      foreach ($queried_objects as $id => $object) {
        $data = array();
        list($id, $vid, $bundle) = field_attach_extract_ids($obj_type, $object);
        $instances = field_info_instances($bundle);
        foreach ($instances as $instance) {
          $data[$instance['field_name']] = $queried_objects[$id]->{$instance['field_name']};
614
        }
615
        $cid = "field:$obj_type:$id";
616
617
618
619
620
621
622
623
624
625
        cache_set($cid, $data, 'cache_field');
      }
    }
  }
}

/**
 * Load all fields for a previous version of each of a set of
 * objects of a single object type.
 *
626
627
628
 * Loading different versions of the same objects is not supported,
 * and should be done by separate calls to the function.
 *
629
 * @param $obj_type
630
 *   The type of $object; e.g. 'node' or 'user'.
631
 * @param $objects
632
 *   An array of objects for which to load fields, keyed by object id.
633
634
 *   Each object needs to have its 'bundle', 'id' and (if applicable)
 *   'revision' keys filled.
635
636
 * @param $options
 *   An associative array of additional options, with the following keys:
637
638
639
 *   - 'field_name':  The field name that should be loaded, instead of
 *     loading all fields, for each object. Note that returned objects
 *     may contain data for other fields, for example if they are read
640
 *     from a cache.
641
642
643
644
 * @returns
 *   On return, the objects in $objects are modified by having the
 *   appropriate set of fields added.
 */
645
646
function field_attach_load_revision($obj_type, $objects, $options = array()) {
  return field_attach_load($obj_type, $objects, FIELD_LOAD_REVISION, $options);
647
648
649
650
651
}

/**
 * Perform field validation against the field data in an object.
 *
652
653
654
655
 * This function does not perform field widget validation on form
 * submissions. It is intended to be called during API save
 * operations. Use field_attach_form_validate() to validate form
 * submissions.
656
657
658
659
660
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object with fields to validate.
661
662
 * @return
 *   Throws a FieldValidationException if validation errors are found.
663
 */
664
function field_attach_validate($obj_type, $object) {
665
666
  $errors = array();
  _field_invoke('validate', $obj_type, $object, $errors);
667
668
669
670

  // Let other modules validate the object.
  foreach (module_implements('field_attach_validate') as $module) {
    $function = $module . '_field_attach_validate';
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
    $function($obj_type, $object, $errors);
  }

  if ($errors) {
    throw new FieldValidationException($errors);
  }
}

/**
 * Perform field validation against form-submitted field values.
 *
 * There are two levels of validation for fields in forms: widget
 * validation, and field validation.
 * - Widget validation steps are specific to a given widget's own form
 * structure and UI metaphors. They are executed through FAPI's
 * #element_validate property during normal form validation.
 * - Field validation steps are common to a given field type, independently of
 * the specific widget being used in a given form. They are defined in the
 * field type's implementation of hook_field_validate().
 *
 * This function performs field validation in the context of a form
 * submission. It converts field validation errors into form errors
 * on the correct form elements. Fieldable object types should call
 * this function during their own form validation function.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
699
700
 *   The object being submitted. The 'bundle', 'id' and (if applicable)
 *   'revision' keys should be present. The actual field values will be read
701
702
703
704
705
706
 *   from $form_state['values'].
 * @param $form
 *   The form structure.
 * @param $form_state
 *   An associative array containing the current state of the form.
 */
707
function field_attach_form_validate($obj_type, $object, $form, &$form_state) {
708
709
710
711
712
713
714
715
716
717
718
  // Extract field values from submitted values.
  _field_invoke_default('extract_form_values', $obj_type, $object, $form, $form_state);

  // Perform field_level validation.
  try {
    field_attach_validate($obj_type, $object);
  }
  catch (FieldValidationException $e) {
    // Pass field-level validation errors back to widgets for accurate error
    // flagging.
    _field_invoke_default('form_errors', $obj_type, $object, $form, $e->errors);
719
720
721
722
723
724
725
726
727
728
729
730
  }
}

/**
 * Perform necessary operations on field data submitted by a form.
 *
 * Currently, this accounts for drag-and-drop reordering of
 * field values, and filtering of empty values.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
731
732
 *   The object being submitted. The 'bundle', 'id' and (if applicable)
 *   'revision' keys should be present. The actual field values will be read
733
734
735
736
737
738
 *   from $form_state['values'].
 * @param $form
 *   The form structure to fill in.
 * @param $form_state
 *   An associative array containing the current state of the form.
 */
739
function field_attach_submit($obj_type, $object, $form, &$form_state) {
740
741
742
  // Extract field values from submitted values.
  _field_invoke_default('extract_form_values', $obj_type, $object, $form, $form_state);

743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  _field_invoke_default('submit', $obj_type, $object, $form, $form_state);

  // Let other modules act on submitting the object.
  foreach (module_implements('field_attach_submit') as $module) {
    $function = $module . '_field_attach_submit';
    $function($obj_type, $object, $form, $form_state);
  }
}

/**
 * Perform necessary operations just before fields data get saved.
 *
 * We take no specific action here, we just give other
 * modules the opportunity to act.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object with fields to process.
 */
763
function field_attach_presave($obj_type, $object) {
764
765
766
767
768
769
770
771
772
773
  _field_invoke('presave', $obj_type, $object);

  // Let other modules act on presaving the object.
  foreach (module_implements('field_attach_presave') as $module) {
    $function = $module . '_field_attach_presave';
    $function($obj_type, $object);
  }
}

/**
774
775
776
777
778
779
 * Save field data for a new object.
 *
 * The passed in object must already contain its id and (if applicable)
 * revision id attributes.
 * Default values (if any) will be saved for fields not present in the
 * $object.
780
781
782
783
784
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object with fields to save.
785
786
787
 * @return
 *   Default values (if any) will be added to the $object parameter for fields
 *   it leaves unspecified.
788
 */
789
function field_attach_insert($obj_type, $object) {
790
  _field_invoke_default('insert', $obj_type, $object);
791
792
793
794
  _field_invoke('insert', $obj_type, $object);

  // Let other modules act on inserting the object, accumulating saved
  // fields along the way.
795
  $skip_fields = array();
796
797
  foreach (module_implements('field_attach_pre_insert') as $module) {
    $function = $module . '_field_attach_pre_insert';
798
    $function($obj_type, $object, $skip_fields);
799
800
  }

801
  // Field storage module saves any remaining unsaved fields.
802
  module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_write', $obj_type, $object, FIELD_STORAGE_INSERT, $skip_fields);
803
804
805

  list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
  if ($cacheable) {
806
    cache_clear_all("field:$obj_type:$id", 'cache_field');
807
808
809
810
811
812
813
814
815
816
817
  }
}

/**
 * Save field data for an existing object.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object with fields to save.
 */
818
function field_attach_update($obj_type, $object) {
819
820
821
822
  _field_invoke('update', $obj_type, $object);

  // Let other modules act on updating the object, accumulating saved
  // fields along the way.
823
  $skip_fields = array();
824
825
  foreach (module_implements('field_attach_pre_update') as $module) {
    $function = $module . '_field_attach_pre_update';
826
    $function($obj_type, $object, $skip_fields);
827
828
  }

829
  // Field storage module saves any remaining unsaved fields.
830
  module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_write', $obj_type, $object, FIELD_STORAGE_UPDATE, $skip_fields);
831
832
833

  list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
  if ($cacheable) {
834
    cache_clear_all("field:$obj_type:$id", 'cache_field');
835
836
837
838
  }
}

/**
839
 * Delete field data for an existing object. This deletes all
840
841
842
843
844
845
846
 * revisions of field data for the object.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object whose field data to delete.
 */
847
function field_attach_delete($obj_type, $object) {
848
849
850
851
852
853
854
855
856
857
858
  _field_invoke('delete', $obj_type, $object);
  module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_delete', $obj_type, $object);

  // Let other modules act on deleting the object.
  foreach (module_implements('field_attach_delete') as $module) {
    $function = $module . '_field_attach_delete';
    $function($obj_type, $object);
  }

  list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
  if ($cacheable) {
859
    cache_clear_all("field:$obj_type:$id", 'cache_field');
860
861
862
863
  }
}

/**
864
 * Delete field data for a single revision of an existing object. The
865
866
867
868
869
870
871
 * passed object must have a revision id attribute.
 *
 * @param $obj_type
 *   The type of $object; e.g. 'node' or 'user'.
 * @param $object
 *   The object with fields to save.
 */
872
function field_attach_delete_revision($obj_type, $object) {
873
  _field_invoke('delete_revision', $obj_type, $object);
874
875
876
877
878
879
880
881
882
  module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_delete_revision', $obj_type, $object);

  // Let other modules act on deleting the revision.
  foreach (module_implements('field_attach_delete_revision') as $module) {
    $function = $module . '_field_attach_delete_revision';
    $function($obj_type, $object);
  }
}

883
884
885
886
887
888
889
890
891
892
/**
 * Retrieve objects matching a given set of conditions.
 *
 * Note that the query 'conditions' only apply to the stored values.
 * In a regular field_attach_load() call, field values additionally go through
 * hook_field_load() and hook_field_attach_load() invocations, which can add
 * to or affect the raw stored values. The results of field_attach_query()
 * might therefore differ from what could be expected by looking at a regular,
 * fully loaded object.
 *
893
894
 * @param $field_id
 *   The id of the field to query.
895
896
897
898
899
900
901
902
903
904
905
906
 * @param $conditions
 *   An array of query conditions. Each condition is a numerically indexed
 *   array, in the form: array(column, value, operator).
 *   Not all storage engines are required to support queries on all column, or
 *   with all operators below. A FieldQueryException will be raised if an
 *   unsupported condition is specified.
 *   Supported columns:
 *     - any of the columns for $field_name's field type: condition on field
 *       value,
 *     - 'type': condition on object type (e.g. 'node', 'user'...),
 *     - 'bundle': condition on object bundle (e.g. node type),
 *     - 'entity_id': condition on object id (e.g node nid, user uid...),
907
908
 *     - 'deleted': condition on whether the field's data is
 *        marked deleted for the object (defaults to FALSE if not specified)
909
910
911
912
913
914
 *     The field_attach_query_revisions() function additionally supports:
 *     - 'revision_id': condition on object revision id (e.g node vid).
 *   Supported operators:
 *     - '=', '!=', '>', '>=', '<', '<=', 'STARTS_WITH', 'ENDS_WITH',
 *       'CONTAINS': these operators expect the value as a literal of the same
 *       type as the column,
915
916
 *     - 'IN', 'NOT IN': this operator expects the value as an array of
 *       literals of the same type as the column.
917
918
919
920
921
922
923
924
925
926
927
928
929
930
 *     - 'BETWEEN': this operator expects the value as an array of two literals
 *       of the same type as the column.
 *     The operator can be ommitted, and will default to 'IN' if the value is
 *     an array, or to '=' otherwise.
 *   Example values for $conditions:
 *   @code
 *   array(
 *     array('type', 'node'),
 *   );
 *   array(
 *     array('bundle', array('article', 'page')),
 *     array('value', 12, '>'),
 *   );
 *   @endcode
931
932
933
934
935
936
937
938
939
940
 * @param $count
 *   The number of results that is requested. This is only a
 *   hint to the storage engine(s); callers should be prepared to
 *   handle fewer or more results. Specify FIELD_QUERY_NO_LIMIT to retrieve
 *   all available objects. This parameter has no default value so
 *   callers must make an explicit choice to potentially retrieve an
 *   enormous result set.
 * @param &$cursor
 *   An opaque cursor that allows a caller to iterate through multiple
 *   result sets. On the first call, pass 0; the correct value to pass
941
942
943
 *   on the next call will be written into $cursor on return. When
 *   there is no more query data available, $cursor will be filled in
 *   with FIELD_QUERY_COMPLETE. If $cursor is passed as NULL,
944
 *   the first result set is returned and no next cursor is returned.
945
946
947
948
949
950
951
952
953
 * @param $age
 *   Internal use only. Use field_attach_query_revisions() instead of passing
 *   FIELD_LOAD_REVISION.
 *   - FIELD_LOAD_CURRENT (default): query the most recent revisions for all
 *     objects. The results will be keyed by object type and object id.
 *   - FIELD_LOAD_REVISION: query all revisions. The results will be keyed by
 *     object type and object revision id.
 * @return
 *   An array keyed by object type (e.g. 'node', 'user'...), then by object id
954
955
956
957
 *   or revision id (depending of the value of the $age parameter).
 *   The values are pseudo-objects with the bundle, id, and revision
 *   id fields filled in.
 *
958
959
960
 *   Throws a FieldQueryException if the field's storage doesn't support the
 *   specified conditions.
 */
961
function field_attach_query($field_id, $conditions, $count, &$cursor = NULL, $age = FIELD_LOAD_CURRENT) {
962
963
964
965
  if (!isset($cursor)) {
    $cursor = 0;
  }

966
967
968
969
970
  // Give a chance to 3rd party modules that bypass the storage engine to
  // handle the query.
  $skip_field = FALSE;
  foreach (module_implements('field_attach_pre_query') as $module) {
    $function = $module . '_field_attach_pre_query';
971
    $results = $function($field_id, $conditions, $count, $cursor, $age, $skip_field);
972
973
974
975
976
977
978
    // Stop as soon as a module claims it handled the query.
    if ($skip_field) {
      break;
    }
  }
  // If the request hasn't been handled, let the storage engine handle it.
  if (!$skip_field) {
979
    $function = variable_get('field_storage_module', 'field_sql_storage') . '_field_storage_query';
980
    $results = $function($field_id, $conditions, $count, $cursor, $age);
981
982
983
984
985
986
987
988
989
990
  }

  return $results;
}

/**
 * Retrieve object revisions matching a given set of conditions.
 *
 * See field_attach_query() for more informations.
 *
991
992
 * @param $field_id
 *   The id of the field to query.
993
994
 * @param $conditions
 *   See field_attach_query().
995
996
997
998
999
1000
 * @param $count
 *   The number of results that is requested. This is only a
 *   hint to the storage engine(s); callers should be prepared to
 *   handle fewer or more results. Specify FIELD_QUERY_NO_LIMIT to retrieve
 *   all available objects. This parameter has no default value so
 *   callers must make an explicit choice to potentially retrieve an
For faster browsing, not all history is shown. View entire blame