1

Summary

I need to edit some data before it gets saved, and hook_field_presave() looks like exactly what I need, but it doesn't get called for some reason.

The Scenario

I'd like to edit data coming from changes to the location field (location module), so that I can look up latitude and longitude information when none is provided and make sure it gets saved.

The implementation

At the moment I'm just adding the hook to the location.module for testing purposes before moving them into a separate module. The code I'm using is this:

function location_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
  watchdog('location', 'testing location_field_presave', array(), WATCHDOG_NOTICE);
}

However, the dblog is never updated with my message; the code never runs.

3

If you are editing an enabled module, you need to first disable, and then re-enable it. Drupal saves in cache the list of hooks implemented by modules; the one I described is the way to force Drupal to update that cache.

hook_field_presave() is invoked for the module implementing the field; the other modules should implement hook_field_attach_presave(). If the Location module is not implementing the field, it should implement hook_field_attach_presave(), which is what your module should do too.

The documentation is not much clear about this; but looking at field_attach_presave() is a little more clear what happens.

function field_attach_presave($entity_type, $entity) {
  _field_invoke('presave', $entity_type, $entity);

  // Let other modules act on presaving the entity.
  module_invoke_all('field_attach_presave', $entity_type, $entity);
}

_field_invoke() invokes the hook for the module implementing the field; module_invoke_all() invokes the hook implemented by any module.

That is why the documentation for hook_field_presave() says, "Define custom presave behavior for this module's field types."

6
  • if other modules should be using hook_field_attach_presave(), then how would they go about changing data before saving it? I don't see any parameters passed by reference in the function definition. – JoBu1324 Dec 6 '12 at 21:56
  • They need to get the field data from the $entity object. – kiamlaluno Dec 6 '12 at 21:58
  • I see that the data is there, but how can I preserve my changes? Or am I expected to return the $entity object? – JoBu1324 Dec 6 '12 at 22:02
  • 2
    @JoBu1324 $entity is an object, and for the most part objects are passed by reference in PHP. Any changes you make to that object will persist outside the scope of your function – Clive Dec 6 '12 at 22:19
  • 1
    Just for reference, I found field_get_items() in the API, which helped me bypass an indepth examination of the $entity object. – JoBu1324 Dec 6 '12 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.