Form API Internal Workflow Illustration
Last modified: December 3, 2009 - 09:59
This workflow actually includes some of the nodeapi hooks as well as FAPI workflow to help illustrate the places where form elements can be manipulated.

This workflow actually includes some of the nodeapi hooks as well as FAPI workflow to help illustrate the places where form elements can be manipulated.

This workflow leaves off
This workflow leaves off what happens after Save. In the normal workflow, it does a drupal_goto (back to the page you're looking on).
-- Merlin
[Point the finger: Assign Blame!]
[Read my writing: ehalseymiles.com]
[Read my Coding blog: Angry Donuts]
Hi Merlin, Thanks for the
Hi Merlin,
Thanks for the feedback. Does the drupal_goto() call the same URL as was originally visited, by default? Is there any control over that with a FAPI property?
I'll check with KarenS what to do, as she has documentation-fu.
Cheers,
J-P
Yes, and there are ways to
Yes, and there are ways to control it:
The submit function can return the destination to go to
$form['#redirect'] -- set to the destination or to NULL to disable redirects
-- Merlin
[Read my writing: ehalseymiles.com]
[Read my Coding blog: Angry Donuts]
what about hook_prepare?
This seems great (just printed off a copy) but it seems to be missing hook_prepare, no?
Jake
---
School and university yearbooks
great chart. one note:
great chart. one note: drupal_retrieve_form($form_id) doesn't necessarily call hook_form(), but any form building function like $form_id. or, if that doesn't exist, a result of hook_forms():
<?phpfunction drupal_retrieve_form($form_id) {
// ...
// We first check to see if there's a function named after the $form_id.
// If there is, we simply pass the arguments on to it to get the form.
if (!function_exists($form_id)) {
// In cases where many form_ids need to share a central builder function,
// such as the node editing form, modules can implement hook_forms(). It
// maps one or more form_ids to the correct builder functions.
//
// We cache the results of that hook to save time, but that only works
// for modules that know all their form_ids in advance. (A module that
// adds a small 'rate this comment' form to each comment in a list
// would need a unique form_id for each one, for example.)
//
// So, we call the hook if $forms isn't yet populated, OR if it doesn't
// yet have an entry for the requested form_id.
if (!isset($forms) || !isset($forms[$form_id])) {
$forms = module_invoke_all('forms', $saved_args);
}
$form_definition = $forms[$form_id];
if (isset($form_definition['callback arguments'])) {
$args = array_merge($form_definition['callback arguments'], $args);
}
if (isset($form_definition['callback'])) {
$callback = $form_definition['callback'];
}
}
// If $callback was returned by a hook_forms() implementation, call it.
// Otherwise, call the function named after the form id.
$form = call_user_func_array(isset($callback) ? $callback : $form_id, $args);
// ...
}
?>
#after_build
In the workflow '#afterbuild' should be '#after_build' with an underscore.
Corrections and omissions
A correction on the diagram: "presave" is called just before saving the node, and once it's done, one of "update" (if the node has been edited), "insert" (if the node has just been created), or "delete" (if the node has just been deleted) is called. This diagram caused me some confusion when I expected form elements to be saved if I changed them in hook_nodeapi in "insert", since it shows that the node is only saved after the "insert", which it is not. The diagram also leaves out when "update", "load", "prepare", "view" and "alter" are called in hook_nodeapi (for a full list of possible actions implemented in hook_nodeapi, take a look at http://api.drupal.org/api/function/hook_nodeapi/6 )
A helpful description of which action runs when is found in hook_hook_info():
'presave' runs 'When either saving a new post or updating an existing post'
'insert' runs 'After saving a new post'
'update' runs 'After saving an updated post'
'delete' runs 'After deleting a post'
'view' runs 'When content is viewed by an authenticated user'