hook_field_presave

7 field.api.php hook_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items)
8 field.api.php hook_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items)

Define custom presave behavior for this module's field types.

Make changes or additions to field values by altering the $items parameter by reference. There is no return value.

Parameters

$entity_type: The type of $entity.

$entity: The entity for the operation.

$field: The field structure for the operation.

$instance: The instance structure for $field on $entity's bundle.

$langcode: The language associated with $items.

$items: $entity->{$field['field_name']}[$langcode], or an empty array if unset.

Related topics

4 functions implement hook_field_presave()

2 invocations of hook_field_presave()

File

modules/field/field.api.php, line 416

Code

function hook_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  if ($field['type'] == 'number_decimal') {
    // Let PHP round the value to ensure consistent behavior across storage
    // backends.
    foreach ($items as $delta => $item) {
      if (isset($item['value'])) {
        $items[$delta]['value'] = round($item['value'], $field['settings']['scale']);
      }
    }
  }
}

Comments

This hook deserves a

This hook deserves a disclaimer: because you're editing an $items array that has been passed in by-reference, any changes you make to prepare the data for saving will persist on these items through the remainder of the page request. If you're performing data transformation, this means your data may be incompatible with your API after you've performed a save in the middle of a page request.

As an example, in Drupal Commerce our Price field was storing prices as integers that got converted to decimals on load and changed back to integers on presave. Unfortunately, this meant that when we saved an order or line item in the middle of the page request, every other function that wanted to manipulate or display the price had an integer instead of the actual decimal value that should've been used.

As such, this hook should be used with extreme caution.

clone

I think, by using the clone keyword, one can work on a copy of the field item. Or am I missing something?

Also note that this hook is

Also note that this hook is only called on the module that defines the field. So you can't use it to hook into presave functionality of other modules' fields.

AFAICT, the best hook to use for that is hook_field_attach_presave(), though it a bit tough since the only parameters are $entity_type and $entity.

Login or register to post comments