field.attach.inc 62.4 KB
Newer Older
1 2
<?php

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

8
use Drupal\field\FieldValidationException;
9
use Drupal\Core\Entity\EntityInterface;
10
use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
11

12 13 14
/**
 * @defgroup field_storage Field Storage API
 * @{
15
 * Implements a storage engine for Field API data.
16
 *
17 18 19 20 21 22 23
 * The Field Attach API uses the Field Storage API to perform all "database
 * access". Each Field Storage API hook function defines a primitive database
 * operation such as read, write, or delete. The default field storage module,
 * field_sql_storage.module, uses the local SQL database to implement these
 * operations, but alternative field storage backends can choose to represent
 * the data in SQL differently or use a completely different storage mechanism
 * such as a cloud-based database.
24
 *
25
 * Each field defines which storage backend it uses. The Drupal system variable
26
 * 'field_storage_default' identifies the storage backend used by default.
27
 *
28 29
 * See @link field Field API @endlink for information about the other parts of
 * the Field API.
30
 */
31 32

/**
33 34
 * Argument for an update operation.
 *
35
 * This is used in hook_field_storage_write when updating an existing entity.
36
 */
37
const FIELD_STORAGE_UPDATE = 'update';
38 39

/**
40 41
 * Argument for an insert operation.
 *
42
 * This is used in hook_field_storage_write when inserting a new entity.
43
 */
44
const FIELD_STORAGE_INSERT = 'insert';
45

46
/**
47
 * @} End of "defgroup field_storage".
48 49 50 51 52
 */

/**
 * @defgroup field_attach Field Attach API
 * @{
53
 * Operates on Field API data attached to Drupal entities.
54
 *
55
 * Field Attach API functions load, store, display, generate Field API
56 57 58 59 60 61 62 63
 * structures, and perform a variety of other functions for field data attached
 * to individual entities.
 *
 * Field Attach API functions generally take $entity_type and $entity arguments
 * along with additional function-specific arguments. $entity_type is the type
 * of the fieldable entity, such as 'node' or 'user', and $entity is the entity
 * itself.
 *
64
 * An entity plugin's annotation is how entity types define if and how
65 66
 * Field API should operate on their entity objects. Notably, the 'fieldable'
 * property needs to be set to TRUE.
67 68 69
 *
 * The Field Attach API uses the concept of bundles: the set of fields for a
 * given entity is defined on a per-bundle basis. The collection of bundles for
70 71 72 73 74 75 76 77 78 79 80
 * an entity type is added to the entity definition with
 * hook_entity_info_alter(). For instance, node_entity_info_alter() exposes
 * each node type as its own bundle. This means that the set of fields of a
 * node is determined by the node type.
 *
 * The Field API reads the bundle name for a given entity from a particular
 * property of the entity object, and hook_entity_info_alter() defines which
 * property to use. For instance, node_entity_info_alter() specifies:
 * @code
 *   $info['entity_keys']['bundle'] = 'type'
 * @endcode
81 82 83 84 85 86 87 88 89
 * This indicates that for a particular node object, the bundle name can be
 * found in $node->type. This property can be omitted if the entity type only
 * exposes a single bundle (all entities of this type have the same collection
 * of fields). This is the case for the 'user' entity type.
 *
 * Most Field Attach API functions define a corresponding hook function that
 * allows any module to act on Field Attach operations for any entity after the
 * operation is complete, and access or modify all the field, form, or display
 * data for that entity and operation. For example, field_attach_view() invokes
90
 * hook_field_attach_view_alter(). These all-module hooks are distinct from
91 92 93 94 95
 * 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, e.g. hook_field_attach_pre_load(). These hooks
96 97
 * run before the corresponding Field Storage API and Field Type API operations.
 * They allow modules to define additional storage locations (e.g.
98 99 100 101 102 103
 * denormalizing, mirroring) for field data on a per-field basis. They also
 * allow modules to take over field storage 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
104 105
 * Field Storage API is essentially the "fallback mechanism" for any fields that
 * aren't being intercepted explicitly by pre-operation hooks.
106
 *
107 108 109
 * @link field_language Field language API @endlink provides information about
 * the structure of field objects.
 *
110 111
 * See @link field Field API @endlink for information about the other parts of
 * the Field API.
112 113
 */

114
/**
115
 * Invokes a method on all the fields of a given entity.
116 117 118 119 120 121
 *
 * @todo Remove _field_invoke() and friends when field types and formatters are
 * turned into plugins.
 *
 * @param string $method
 *   The name of the method to invoke.
122 123
 * @param callable $target_function
 *   A function that receives an $instance object and returns the object on
124 125 126 127
 *   which the method should be invoked.
 * @param Drupal\Core\Entity\EntityInterface $entity
 *   The fully formed $entity_type entity.
 * @param mixed $a
128
 *   (optional) A parameter for the invoked method. Defaults to NULL.
129
 * @param mixed $b
130
 *   (optional) A parameter for the invoked method. Defaults to NULL.
131
 * @param array $options
132 133
 *   (optional) An associative array of additional options, with the following
 *   keys:
134 135 136 137 138 139 140 141 142 143 144 145 146
 *   - field_name: The name of the field whose operation should be invoked. By
 *     default, the operation is invoked on all the fields in the entity'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 entity's'
 *     bundles.
 *   - 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.
 *   - langcode: A language code or an array of language codes keyed by field
 *     name. It will be used to narrow down to a single value the available
 *     languages to act on.
147 148 149
 *
 * @return array
 *   An array of returned values.
150
 */
151
function field_invoke_method($method, $target_function, EntityInterface $entity, &$a = NULL, &$b = NULL, array $options = array()) {
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
  // Merge default options.
  $default_options = array(
    'deleted' => FALSE,
    'langcode' => NULL,
  );
  $options += $default_options;

  $entity_type = $entity->entityType();
  // Determine the list of instances to iterate on.
  $instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);

  // Iterate through the instances and collect results.
  $return = array();
  foreach ($instances as $instance) {

167
    // Let the function determine the target object on which the method should be
168
    // called.
169
    $target = call_user_func($target_function, $instance);
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

    if (method_exists($target, $method)) {
      $field = field_info_field_by_id($instance['field_id']);
      $field_name = $field['field_name'];

      // Determine the list of languages to iterate on.
      $available_langcodes = field_available_languages($entity_type, $field);
      $langcodes = _field_language_suggestion($available_langcodes, $options['langcode'], $field_name);

      foreach ($langcodes as $langcode) {
        $items = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();

        $result = $target->$method($entity, $langcode, $items, $a, $b);

        if (isset($result)) {
          // For methods with array results, we merge results together.
          // For methods with scalar results, we collect results in an array.
          if (is_array($result)) {
            $return = array_merge($return, $result);
          }
          else {
            $return[] = $result;
          }
        }

        // 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($entity->{$field_name}[$langcode])) {
          $entity->{$field_name}[$langcode] = $items;
        }
      }
    }
  }

  return $return;
}

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
/**
 * Invokes a method across fields on multiple entities.
 *
 * @param string $method
 *   The name of the method to invoke.
 * @param callable $target_function
 *   A function that receives an $instance object and returns the object on
 *   which the method should be invoked.
 * @param array $entities
 *   An array of entities, keyed by entity ID.
 * @param mixed $a
 *   (optional) A parameter for the invoked method. Defaults to NULL.
 * @param mixed $b
 *   (optional) A parameter for the invoked method. Defaults to NULL.
 * @param $options
 *   (optional) An associative array of additional options, with the following
 *   keys:
 *   - field_name: The name of the field whose operation should be invoked. By
 *     default, the operation is invoked on all the fields in the entity'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 entity's'
 *     bundles.
 *   - 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.
 *   - langcode: A language code or an array of language codes keyed by field
 *     name. It will be used to narrow down to a single value the available
 *     languages to act on.
 *
 * @return array
 *   An array of returned values keyed by entity ID.
 *
 * @see field_invoke_method()
 */
function field_invoke_method_multiple($method, $target_function, array $entities, &$a = NULL, &$b = NULL, array $options = array()) {
  // Merge default options.
  $default_options = array(
    'deleted' => FALSE,
    'langcode' => NULL,
  );
  $options += $default_options;

  $instances = array();
  $grouped_entities = array();
  $grouped_items = array();
  $grouped_targets = array();
  $return = array();

  // Go through the entities and collect the instances on which the method
  // should be called.
  foreach ($entities as $entity) {
    $id = $entity->id();
    $entity_type = $entity->entityType();

    // Determine the list of instances to iterate on.
    $entity_instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);

    foreach ($entity_instances as $instance) {
      $instance_id = $instance['id'];
      $field_name = $instance['field_name'];

      // Let the closure determine the target object on which the method should
      // be called.
      if (empty($grouped_targets[$instance_id])) {
        $grouped_targets[$instance_id] = call_user_func($target_function, $instance);
      }

      if (method_exists($grouped_targets[$instance_id], $method)) {
        // Add the instance to the list of instances to invoke the hook on.
        if (!isset($instances[$instance_id])) {
          $instances[$instance_id] = $instance;
        }

        // Unless a language code suggestion is provided we iterate on all the
        // available language codes.
        $field = field_info_field_by_id($instance['field_id']);
        $available_langcodes = field_available_languages($entity_type, $field);
        $langcode = !empty($options['langcode'][$id]) ? $options['langcode'][$id] : $options['langcode'];
        $langcodes = _field_language_suggestion($available_langcodes, $langcode, $field_name);
        foreach ($langcodes as $langcode) {
          // Group the entities and items corresponding to the current field.
          $grouped_entities[$instance_id][$langcode][$id] = $entities[$id];
          $grouped_items[$instance_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
        }
      }
    }
    // Initialize the return value for each entity.
    $return[$id] = array();
  }

  // For each instance, invoke the method and collect results.
  foreach ($instances as $instance_id => $instance) {
    $field_name = $instance['field_name'];

    // Iterate over all the field translations.
    foreach ($grouped_items[$instance_id] as $langcode => &$items) {
      $entities = $grouped_entities[$instance_id][$langcode];
      $results = $grouped_targets[$instance_id]->$method($entities, $langcode, $items, $a, $b);

      if (isset($results)) {
        // Collect results by entity.
        // 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;
          }
        }
      }
    }

    // Populate field values back in the entities, but avoid replacing missing
    // fields with an empty array (those are not equivalent on update).
    foreach ($grouped_entities[$instance_id] as $langcode => $entities) {
      foreach ($entities as $id => $entity) {
        if ($grouped_items[$instance_id][$langcode][$id] !== array() || isset($entity->{$field_name}[$langcode])) {
          $entity->{$field_name}[$langcode] = $grouped_items[$instance_id][$langcode][$id];
        }
      }
    }
  }

  return $return;
}

337 338 339 340
/**
 * Invoke a field hook.
 *
 * @param $op
341
 *   Possible operations include:
342 343 344 345 346 347 348 349 350
 *   - form
 *   - validate
 *   - presave
 *   - insert
 *   - update
 *   - delete
 *   - delete revision
 *   - view
 *   - prepare translation
351 352
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity object.
353
 * @param $a
354
 *   - The $form in the 'form' operation.
355
 *   - The value of $view_mode in the 'view' operation.
356
 *   - Otherwise NULL.
357
 * @param $b
358 359
 *   - The $form_state in the 'submit' operation.
 *   - Otherwise NULL.
360 361
 * @param $options
 *   An associative array of additional options, with the following keys:
362 363
 *  - 'field_name': The name of the field whose operation should be
 *    invoked. By default, the operation is invoked on all the fields
364
 *    in the entity's bundle. NOTE: This option is not compatible with
365
 *    the 'deleted' option; the 'field_id' option should be used
366
 *    instead.
367 368
 *  - 'field_id': The id of the field whose operation should be
 *    invoked. By default, the operation is invoked on all the fields
369
 *    in the entity's' bundles.
370 371
 *  - 'default': A boolean value, specifying which implementation of
 *    the operation should be invoked.
372 373 374 375 376 377
 *    - 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.
378 379 380
 *  - '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.
381
 *  - 'langcode': A language code or an array of language codes keyed by field
382 383
 *    name. It will be used to narrow down to a single value the available
 *    languages to act on.
384
 */
385
function _field_invoke($op, EntityInterface $entity, &$a = NULL, &$b = NULL, $options = array()) {
386 387 388
  // Merge default options.
  $default_options = array(
    'default' => FALSE,
389
    'deleted' => FALSE,
390
    'langcode' => NULL,
391 392 393
  );
  $options += $default_options;

394
  // Determine the list of instances to iterate on.
395
  $instances = _field_invoke_get_instances($entity->entityType(), $entity->bundle(), $options);
396

397 398
  // Iterate through the instances and collect results.
  $return = array();
399
  foreach ($instances as $instance) {
400 401 402 403
    // field_info_field() is not available for deleted fields, so use
    // field_info_field_by_id().
    $field = field_info_field_by_id($instance['field_id']);
    $field_name = $field['field_name'];
404 405 406
    $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
    if (function_exists($function)) {
      // Determine the list of languages to iterate on.
407
      $available_langcodes = field_available_languages($entity->entityType(), $field);
408
      $langcodes = _field_language_suggestion($available_langcodes, $options['langcode'], $field_name);
409

410
      foreach ($langcodes as $langcode) {
411
        $items = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
412
        $result = $function($entity, $field, $instance, $langcode, $items, $a, $b);
413 414 415 416 417
        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);
418
          }
419 420
          else {
            $return[] = $result;
421 422
          }
        }
423 424 425 426 427 428

        // 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($entity->{$field_name}[$langcode])) {
          $entity->{$field_name}[$langcode] = $items;
        }
429 430 431 432 433 434 435
      }
    }
  }

  return $return;
}

436
/**
437
 * Invokes a field hook across fields on multiple entities.
438 439 440 441
 *
 * @param $op
 *   Possible operations include:
 *   - load
442
 *   - prepare_view
443 444
 *   For all other operations, use _field_invoke() / field_invoke_default()
 *   instead.
445
 * @param $entity_type
446
 *   The type of entities in $entities; e.g. 'node' or 'user'.
447
 * @param $entities
448
 *   An array of entities, keyed by entity ID.
449 450 451 452 453
 * @param $a
 *   - The $age parameter in the 'load' operation.
 *   - Otherwise NULL.
 * @param $b
 *   Currently always NULL.
454 455
 * @param $options
 *   An associative array of additional options, with the following keys:
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
 *   - field_name: The name of the field whose operation should be invoked. By
 *     default, the operation is invoked on all the fields in the entity'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 entity's
 *     bundles.
 *   - default: A boolean value, specifying which implementation of the
 *     operation should be invoked.
 *     - 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.
 *   - 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.
 *   - langcode: A language code or an array of arrays of language codes keyed
 *     by entity ID and field name. It will be used to narrow down to a single
 *     value the available languages to act on.
477
 *
478
 * @return
479
 *   An array of returned values keyed by entity ID.
480
 */
481
function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b = NULL, $options = array()) {
482 483 484
  // Merge default options.
  $default_options = array(
    'default' => FALSE,
485
    'deleted' => FALSE,
486
    'langcode' => NULL,
487 488 489
  );
  $options += $default_options;

490 491
  $fields = array();
  $grouped_instances = array();
492
  $grouped_entities = array();
493 494 495
  $grouped_items = array();
  $return = array();

496
  // Go through the entities and collect the fields on which the hook should be
497
  // invoked.
498
  //
499
  // We group fields by ID, not by name, because this function can operate on
500
  // deleted fields which may have non-unique names. However, entities can only
501 502
  // contain data for a single field for each name, even if that field
  // is deleted, so we reference field data via the
503 504
  // $entity->$field_name property.
  foreach ($entities as $entity) {
505
    // Determine the list of instances to iterate on.
506 507
    $instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);
    $id = $entity->id();
508 509 510

    foreach ($instances as $instance) {
      $field_id = $instance['field_id'];
511
      $field_name = $instance['field_name'];
512
      $field = field_info_field_by_id($field_id);
513 514
      $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
      if (function_exists($function)) {
515
        // Add the field to the list of fields to invoke the hook on.
516
        if (!isset($fields[$field_id])) {
517
          $fields[$field_id] = $field;
518 519 520
        }
        // Extract the field values into a separate variable, easily accessed
        // by hook implementations.
521 522 523 524 525 526
        // Unless a language code suggestion is provided we iterate on all the
        // available language codes.
        $available_langcodes = field_available_languages($entity_type, $field);
        $langcode = !empty($options['langcode'][$id]) ? $options['langcode'][$id] : $options['langcode'];
        $langcodes = _field_language_suggestion($available_langcodes, $langcode, $field_name);
        foreach ($langcodes as $langcode) {
527
          $grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
528 529 530 531
          // Group the instances and entities corresponding to the current
          // field.
          $grouped_instances[$field_id][$langcode][$id] = $instance;
          $grouped_entities[$field_id][$langcode][$id] = $entities[$id];
532
        }
533 534
      }
    }
535
    // Initialize the return value for each entity.
536 537 538
    $return[$id] = array();
  }

539
  // For each field, invoke the field hook and collect results.
540 541
  foreach ($fields as $field_id => $field) {
    $field_name = $field['field_name'];
542
    $function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
543
    // Iterate over all the field translations.
544 545 546 547
    foreach ($grouped_items[$field_id] as $langcode => &$items) {
      $entities = $grouped_entities[$field_id][$langcode];
      $instances = $grouped_instances[$field_id][$langcode];
      $results = $function($entity_type, $entities, $field, $instances, $langcode, $items, $a, $b);
548 549 550 551 552 553 554 555 556 557
      if (isset($results)) {
        // Collect results by entity.
        // 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;
558 559 560 561 562
          }
        }
      }
    }

563
    // Populate field values back in the entities, but avoid replacing missing
564
    // fields with an empty array (those are not equivalent on update).
565 566 567
    foreach ($grouped_entities[$field_id] as $langcode => $entities) {
      foreach ($entities as $id => $entity) {
        if ($grouped_items[$field_id][$langcode][$id] !== array() || isset($entity->{$field_name}[$langcode])) {
568
          $entity->{$field_name}[$langcode] = $grouped_items[$field_id][$langcode][$id];
569
        }
570 571 572 573 574 575 576
      }
    }
  }

  return $return;
}

577 578
/**
 * Invoke field.module's version of a field hook.
579 580 581 582 583
 *
 * This function invokes the field_default_[op]() function.
 * Use _field_invoke() to invoke the field type implementation,
 * hook_field_[op]().
 *
584
 * @see _field_invoke()
585
 */
586
function _field_invoke_default($op, EntityInterface $entity, &$a = NULL, &$b = NULL, $options = array()) {
587
  $options['default'] = TRUE;
588
  return _field_invoke($op, $entity, $a, $b, $options);
589 590
}

591
/**
592
 * Invoke field.module's version of a field hook on multiple entities.
593 594 595 596 597
 *
 * This function invokes the field_default_[op]() function.
 * Use _field_invoke_multiple() to invoke the field type implementation,
 * hook_field_[op]().
 *
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
 * @param $op
 *   Possible operations include:
 *   - load
 *   - prepare_view
 *   For all other operations, use _field_invoke() / field_invoke_default()
 *   instead.
 * @param $entity_type
 *   The type of entities in $entities; e.g. 'node' or 'user'.
 * @param $entities
 *   An array of entities, keyed by entity ID.
 * @param $a
 *   - The $age parameter in the 'load' operation.
 *   - Otherwise NULL.
 * @param $b
 *   Currently always NULL.
 * @param $options
 *   An associative array of additional options, with the following keys:
 *   - field_name: The name of the field whose operation should be invoked. By
 *     default, the operation is invoked on all the fields in the entity'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 entity's
 *     bundles.
 *   - default': A boolean value, specifying which implementation of the
 *     operation should be invoked.
 *     - 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.
 *   - 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.
 *   - language: A language code or an array of arrays of language codes keyed
 *     by entity ID and field name. It will be used to narrow down to a single
 *     value the available languages to act on.
 *
 * @return
 *   An array of returned values keyed by entity ID.
 *
640
 * @see _field_invoke_multiple()
641
 */
642
function _field_invoke_multiple_default($op, $entity_type, $entities, &$a = NULL, &$b = NULL, $options = array()) {
643
  $options['default'] = TRUE;
644
  return _field_invoke_multiple($op, $entity_type, $entities, $a, $b, $options);
645 646
}

647
/**
648 649 650
 * Retrieves a list of instances to operate on.
 *
 * Helper for _field_invoke().
651 652 653 654 655 656 657
 *
 * @param $entity_type
 *   The entity type.
 * @param $bundle
 *   The bundle name.
 * @param $options
 *   An associative array of options, as provided to _field_invoke(). Only the
658
 *   following keys are considered:
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
 *   - deleted
 *   - field_name
 *   - field_id
 *   See _field_invoke() for details.
 *
 * @return
 *   The array of selected instance definitions.
 */
function _field_invoke_get_instances($entity_type, $bundle, $options) {
  if ($options['deleted']) {
    // Deleted fields are not included in field_info_instances(), and need to
    // be fetched from the database with field_read_instances().
    $params = array('entity_type' => $entity_type, 'bundle' => $bundle);
    if (isset($options['field_id'])) {
      // Single-field mode by field id: field_read_instances() does the filtering.
      // Single-field mode by field name is not compatible with the 'deleted'
      // option.
      $params['field_id'] = $options['field_id'];
    }
    $instances = field_read_instances($params, array('include_deleted' => TRUE));
  }
  elseif (isset($options['field_name'])) {
    // Single-field mode by field name: field_info_instance() does the
    // filtering.
    $instances = array(field_info_instance($entity_type, $options['field_name'], $bundle));
  }
  else {
    $instances = field_info_instances($entity_type, $bundle);
    if (isset($options['field_id'])) {
      // Single-field mode by field id: we need to loop on each instance to
      // find the right one.
      foreach ($instances as $instance) {
        if ($instance['field_id'] == $options['field_id']) {
          $instances = array($instance);
          break;
        }
      }
    }
  }

  return $instances;
}

702
/**
703
 * Defines a 'target function' for field_invoke_method().
704 705 706
 *
 * Used to invoke methods on an instance's widget.
 *
707 708
 * @return callable $target_function
 *   A 'target function' for field_invoke_method().
709 710 711 712 713 714 715
 */
function _field_invoke_widget_target() {
  return function ($instance) {
    return $instance->getWidget();
  };
}

716
/**
717
 * Adds form elements for all fields for an entity to a form structure.
718
 *
719 720 721 722 723 724 725 726 727 728 729
 * The form elements for the entity's fields are added by reference as direct
 * children in the $form parameter. This parameter can be a full form structure
 * (most common case for entity edit forms), or a sub-element of a larger form.
 *
 * By default, submitted field values appear at the top-level of
 * $form_state['values']. A different location within $form_state['values'] can
 * be specified by setting the '#parents' property on the incoming $form
 * parameter. Because of name clashes, two instances of the same field cannot
 * appear within the same $form element, or within the same '#parents' space.
 *
 * For each call to field_attach_form(), field values are processed by calling
730 731
 * field_attach_form_validate() and field_attach_extract_form_values() on the
 * same $form element.
732 733
 *
 * Sample resulting structure in $form:
734
 * @code
735 736 737 738
 *   '#parents' => The location of field values in $form_state['values'],
 *   '#entity_type' => The name of the entity type,
 *   '#bundle' => The name of the bundle,
 *   // One sub-array per field appearing in the entity, keyed by field name.
739 740 741 742 743 744 745 746 747 748 749
 *   // 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...).
 *   // The sub-array is nested into a $langcode key where $langcode has the
 *   // same value of the $langcode parameter above.
 *   // The '#language' key holds the same value of $langcode and it is used
 *   // to access the field sub-array when $langcode is unknown.
 *   'field_foo' => array(
 *     '#tree' => TRUE,
750
 *     '#field_name' => The name of the field,
751 752
 *     '#language' => $langcode,
 *     $langcode => array(
753 754 755 756 757 758 759 760
 *       '#field_name' => The name of the field,
 *       '#language' => $langcode,
 *       '#field_parents' => The 'parents' space for the field in the form,
 *          equal to the #parents property of the $form parameter received by
 *          field_attach_form(),
 *       '#required' => Whether or not the field is required,
 *       '#title' => The label of the field instance,
 *       '#description' => The description text for the field instance,
761 762 763
 *
 *       // Only for 'single' widgets:
 *       '#theme' => 'field_multiple_value_form',
764
 *       '#cardinality' => The field cardinality,
765 766
 *       // One sub-array per copy of the widget, keyed by delta.
 *       0 => array(
767 768 769 770 771 772 773 774 775
 *         '#entity_type' => The name of the entity type,
 *         '#bundle' => The name of the bundle,
 *         '#field_name' => The name of the field,
 *         '#field_parents' => The 'parents' space for the field in the form,
 *            equal to the #parents property of the $form parameter received by
 *            field_attach_form(),
 *         '#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,
776
 *         '#delta' => 0,
777
 *         '#columns' => The array of field columns,
778
 *         // The remaining elements in the sub-array depend on the widget.
779
 *         '#type' => The type of the widget,
780 781 782 783 784 785 786
 *         ...
 *       ),
 *       1 => array(
 *         ...
 *       ),
 *
 *       // Only for multiple widgets:
787
 *       '#entity_type' => The name of the entity type,
788 789 790
 *       '#bundle' => $instance['bundle'],
 *       '#columns'  => array_keys($field['columns']),
 *       // The remaining elements in the sub-array depend on the widget.
791
 *       '#type' => The type of the widget,
792 793 794 795 796 797 798
 *       ...
 *     ),
 *     ...
 *   ),
 * )
 * @endcode
 *
799 800
 * Additionally, some processing data is placed in $form_state, and can be
 * accessed by field_form_get_state() and field_form_set_state().
801
 *
802
 * @param \Drupal\Core\Entity\EntityInterface $entity
803
 *   The entity for which to load form elements, used to initialize
804 805
 *   default form values.
 * @param $form
806 807 808 809 810
 *   The form structure to fill in. This can be a full form structure, or a
 *   sub-element of a larger form. The #parents property can be set to control
 *   the location of submitted field values within $form_state['values']. If
 *   not specified, $form['#parents'] is set to an empty array, placing field
 *   values at the top-level of $form_state['values'].
811 812
 * @param $form_state
 *   An associative array containing the current state of the form.
813 814 815
 * @param $langcode
 *   The language the field values are going to be entered, if no language
 *   is provided the default site language will be used.
816 817 818
 * @param array $options
 *   An associative array of additional options. See field_invoke_method() for
 *   details.
819 820 821
 *
 * @see field_form_get_state()
 * @see field_form_set_state()
822
 */
823
function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langcode = NULL, array $options = array()) {
824 825 826
  // Set #parents to 'top-level' by default.
  $form += array('#parents' => array());

827
  // If no language is provided use the default site language.
828
  $options['langcode'] = field_valid_language($langcode);
829
  $form += (array) field_invoke_method('form', _field_invoke_widget_target(), $entity, $form, $form_state, $options);
830

831
  // Add custom weight handling.
832
  $form['#pre_render'][] = '_field_extra_fields_pre_render';
833
  $form['#entity_type'] = $entity->entityType();
834
  $form['#bundle'] = $entity->bundle();
835

836
  // Let other modules make changes to the form.
837
  // Avoid module_invoke_all() to let parameters be taken by reference.
838 839
  foreach (module_implements('field_attach_form') as $module) {
    $function = $module . '_field_attach_form';
840
    $function($entity, $form, $form_state, $langcode);
841 842 843 844
  }
}

/**
845 846 847 848
 * Loads fields for the current revisions of a group of entities.
 *
 * Loads all fields for each entity object in a group of a single entity type.
 * The loaded field values are added directly to the entity objects.
849
 *
850 851 852 853
 * field_attach_load() is automatically called by the default entity controller
 * class, and thus, in most cases, doesn't need to be explicitly called by the
 * entity type module.
 *
854
 * @param $entity_type
855
 *   The type of entities in $entities; e.g., 'node' or 'user'.
856
 * @param $entities
857 858 859 860
 *   An array of entities for which to load fields, keyed by entity ID. Each
 *   entity needs to have its 'bundle', 'id' and (if applicable) 'revision' keys
 *   filled in. The function adds the loaded field data directly in the entity
 *   objects of the $entities array.
861
 * @param $age
862 863 864 865
 *   FIELD_LOAD_CURRENT to load the most recent revision for all fields, or
 *   FIELD_LOAD_REVISION to load the version indicated by each entity. Defaults
 *   to FIELD_LOAD_CURRENT; use field_attach_load_revision() instead of passing
 *   FIELD_LOAD_REVISION.
866 867
 * @param $options
 *   An associative array of additional options, with the following keys:
868 869 870 871 872 873
 *   - field_id: The field ID that should be loaded, instead of loading all
 *     fields, for each entity. Note that returned entities may contain data for
 *     other fields, for example if they are read from a cache.
 *   - 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.
874
 */
875
function field_attach_load($entity_type, $entities, $age = FIELD_LOAD_CURRENT, $options = array()) {
876
  $load_current = $age == FIELD_LOAD_CURRENT;
877

878 879 880 881 882 883
  // Merge default options.
  $default_options = array(
    'deleted' => FALSE,
  );
  $options += $default_options;

884
  $info = entity_get_info($entity_type);
885 886
  // Only the most current revision of non-deleted fields for cacheable entity
  // types can be cached.
887
  $cache_read = $load_current && $info['field_cache'] && empty($options['deleted']);
888
  // In addition, do not write to the cache when loading a single field.
889
  $cache_write = $cache_read && !isset($options['field_id']);
890

891
  if (empty($entities)) {
892 893 894
    return;
  }

895
  // Assume all entities will need to be queried. Entities found in the cache
896
  // will be removed from the list.
897
  $queried_entities = $entities;
898

899
  // Fetch available entities from cache, if applicable.
900
  if ($cache_read) {
901 902
    // Build the list of cache entries to retrieve.
    $cids = array();
903 904
    foreach ($entities as $id => $entity) {
      $cids[] = "field:$entity_type:$id";
905
    }
906
    $cache = cache('field')->getMultiple($cids);
907 908
    // Put the cached field values back into the entities and remove them from
    // the list of entities to query.
909 910
    foreach ($entities as $id => $entity) {
      $cid = "field:$entity_type:$id";
911
      if (isset($cache[$cid])) {
912
        unset($queried_entities[$id]);
913
        foreach ($cache[$cid]->data as $field_name => $values) {
914
          $entity->$field_name = $values;
915 916
        }
      }
917
    }
918 919
  }

920 921
  // Fetch other entities from their storage location.
  if ($queried_entities) {
922
    // The invoke order is:
923
    // - hook_field_storage_pre_load()
924
    // - storage backend's hook_field_storage_load()
925
    // - field-type module's hook_field_load()
926 927
    // - hook_field_attach_load()

928
    // Invoke hook_field_storage_pre_load(): let any module load field
929 930
    // data before the storage engine, accumulating along the way.
    $skip_fields = array();
931 932
    foreach (module_implements('field_storage_pre_load') as $module) {
      $function = $module . '_field_storage_pre_load';
933
      $function($entity_type, $queried_entities, $age, $skip_fields, $options);
934 935
    }

936 937
    $instances = array();

938
    // Collect the storage backends used by the remaining fields in the entities.
939
    $storages = array();
940
    foreach ($queried_entities as $entity) {
941 942 943
      $instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);
      $id = $entity->id();
      $vid = $entity->getRevisionId();
944
      foreach ($instances as $instance) {
945 946 947 948 949 950 951 952
        $field_name = $instance['field_name'];
        $field_id = $instance['field_id'];
        // Make sure all fields are present at least as empty arrays.
        if (!isset($queried_entities[$id]->{$field_name})) {
          $queried_entities[$id]->{$field_name} = array();
        }
        // Collect the storage backend if the field has not been loaded yet.
        if (!isset($skip_fields[$field_id])) {
953
          $field = field_info_field_by_id($field_id);
954
          $storages[$field['storage']['type']][$field_id][] = $load_current ? $id : $vid;
955 956 957 958 959 960 961
        }
      }
    }

    // Invoke hook_field_storage_load() on the relevant storage backends.
    foreach ($storages as $storage => $fields) {
      $storage_info = field_info_storage_types($storage);
962
      module_invoke($storage_info['module'], 'field_storage_load', $entity_type, $queried_entities, $age, $fields, $options);
963
    }
964

965
    // Invoke field-type module's hook_field_load().
966 967
    $null = NULL;
    _field_invoke_multiple('load', $entity_type, $queried_entities, $age, $null, $options);
968 969

    // Invoke hook_field_attach_load(): let other modules act on loading the
970
    // entity.
971
    module_invoke_all('field_attach_load', $entity_type, $queried_entities, $age, $options);
972

973
    // Build cache data.
974
    if ($cache_write) {
975
      foreach ($queried_entities as $id => $entity) {
976
        $data = array();
977
        $instances = field_info_instances($entity_type, $entity->bundle());
978
        foreach ($instances as $instance) {
979
          $data[$instance['field_name']] = $queried_entities[$id]->{$instance['field_name']};
980
        }
981
        $cid = "field:$entity_type:$id";
982
        cache('field')->set($cid, $data);
983 984 985 986 987 988
      }
    }
  }
}

/**
989
 * Loads all fields for previous versions of a group of entities.
990
 *
991 992
 * Loading different versions of the same entities is not supported, and should
 * be done by separate calls to the function.
993
 *
994 995 996 997
 * field_attach_load_revision() is automatically called by the default entity
 * controller class, and thus, in most cases, doesn't need to be explicitly
 * called by the entity type module.
 *
998
 * @param $entity_type
999
 *   The type of entities in $entities; e.g. 'node' or 'user'.
1000
 * @param $entities
1001
 *   An array of entities for which to load fields, keyed by entity ID. Each
1002 1003 1004
 *   entity needs to have its 'bundle', 'id' and (if applicable) 'revision' keys
 *   filled. The function adds the loaded field data directly in the entity
 *   objects of the $entities array.
1005
 * @param $options
1006 1007
 *   An associative array of additional options. See field_attach_load() for
 *   details.
1008
 */
1009 1010
function field_attach_load_revision($entity_type, $entities, $options = array()) {
  return field_attach_load($entity_type, $entities, FIELD_LOAD_REVISION, $options);
1011 1012 1013
}

/**
1014
 * Performs field validation against the field data in an entity.
1015
 *
1016 1017 1018
 * 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.
1019
 *
1020
 * @param \Drupal\Core\Entity\EntityInterface $entity
1021
 *   The entity with fields to validate.
1022
 * @throws Drupal\field\FieldValidationException
1023 1024 1025
 *   If validation errors are found, a FieldValidationException is thrown. The
 *   'errors' property contains the array of errors, keyed by field name,
 *   language and delta.
1026 1027 1028
 * @param array $options
 *   An associative array of additional options. See field_invoke_method() for
 *   details.
1029
 */
1030
function field_attach_validate(EntityInterface $entity, array $options = array()) {
1031
  $errors = array();
1032
  // Check generic, field-type-agnostic errors first.
1033
  $null = NULL;
1034
  _field_invoke_default('validate', $entity, $errors, $null, $options);
1035
  // Check field-type specific errors.
1036
  _field_invoke('validate', $entity, $errors, $null, $options);
1037

1038
  // Let other modules validate the entity.
1039
  // Avoid module_invoke_all() to let $errors be taken by reference.
1040 1041
  foreach (module_implements('field_attach_validate') as $module) {
    $function = $module . '_field_attach_validate';
1042
    $function($entity, $errors);
1043 1044 1045 1046 1047 1048 1049 1050
  }

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

/**
1051
 * Performs field validation against form-submitted field values.
1052
 *
1053 1054 1055 1056 1057
 * There are two levels of validation for fields in forms: widget validation and
 * 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.
1058
 * - Field validation steps are common to a given field type, independently of
1059 1060
 *   the specific widget being used in a given form. They are defined in the
 *   field type's implementation of hook_field_validate().
1061
 *