During development of the pgbar module I often ran into Notices for something in
$items. This time I said to myself: Let's get this straight once and for all. So I've inserted some debug code into my module to track which field related hook can manipulate data and in which order they are called. You can see the result in the dot-graph at the bottom.
The nodes are places where we can access the data. That's either the browser (
instance_settings_form), the database (
field_storage) or some hooks. The edges indicate how data travels through these nodes. The black lines indicate routes that are always taken (if applicable) the coloured routes are only taken for certain actions:
- light green: for previewing the field (ie. hitting preview in the node form)
- green: for viewing a field (ie. node/nid)
- yellow: loading the field form with and without default values already defined (ie. loading the field settings form, adding new items in a node form)
- orange: editing already existing field (ie. loading the node form)
- pink: hitting save on the field settings form
- red: saving (ie. hitting save on the node form)
For those of you that plan to implement a new field type this picture holds quite some complications:
hook_field_widget_form()has to deal with nearly all kind of data: none at all, data from the field_storage (via
hook_field_load), default values from the instance settings and data from a previous form submission.
hook_field_loadis called during preview so it has to not only handle data from the database but also data from the form.
hook_field_validateis (together with
hook_field_is_empty) the only hook that's called for all form submissions. But it can't manipulate the data at all. So there is no way to transform the data sent by the browser prior to the other hooks. My workaround is to use an
hook_field_prepare_viewand it's companion
hook_field_formatter_prepare_viewalso manipulate the data sent to
hook_field_widget_formwhen previewing a node.
Due to the non-uniform way data is handled for fields during the workflow manipulating field data in this hooks is quite tedious. Most modules seem to deal with this by simply storing data in the same data structure as the form. But how to deal with changes in the form? Different widgets for the same type?
How do you deal with this?