~ 2 min read

Maintaining states between form submit and node hooks in Drupal 6

share this story on
Insights about Drupal's use of node_save() functions and how the hook_nodeapi() uses a different context than the form submit handler

With Drupal, it is many times the case where you’d find yourself working with custom forms or alter existing forms through the Form API and end up modifying the submit handler so that you are essentially triggering node_save() yourself.

If you find yourself in such scenario where you are also having conditional actions in an implementation of hook_nodeapi() then you’ll soon enough realize that there is complete isolation between the $form array (or $form_state for that matter), which is available through the various form hooks, to the node handling hooks.

To give a practical example, imagine a case where upon a field property in the form you would like to handle the node saving that you implement in your custom hook_nodeapi() differently. The problem is right there – in your implementation of hook_nodeapi() you don’t get the $form nor any access to it, nor is it possible to pass it in any way.

I guess one way to attack the problem would be to glance into $_POST and take it from there. Now breadth slowly and forget this was ever an option since we are supposed to do things the ‘right way’ and not the ‘easy way’. Leave your quick-and-dirty work to quick-and-dirty situations (and production environment is not one of them).

Solving the issue though isn’t that hard as it looks – we’ll use the $node object as our temporary storage and simply apply attributes to the object. Because the object is passed by reference to node_save() the attribute being used will be available in any of the hook_nodeapi() implementations. You also don’t have to worry about the attribute is it’s not going to be persisted to the database.

Taking a practical example at it, assuming you are modifying an existing node, the code may look something like:

 function mymodule_node_edit_form_submit($form_id, $form_values) {
 $node = node_load(arg(1));
 $node->title = $form_state['values']['title'];
 // ... rest of your code
 // use an attribute to define some state (or actually pass anything from $form if required)
 $node->is_using_x = TRUE

Later on in any implementation of hook_nodeapi() the $node object, passed as reference, will maintain $node->is_using_x attribute with whatever payload you’ve set it to.