Adding your own extra _submit or function using hook_form_alter
When using Forms API to alter an existing form, if you add your own items you need a way to get the data back. When doing this to the node or user form, this is easy, but not so easy when modifying some of the more obscure forms.
Drupal 5
In this case, you need to add your own hook into the _submit chain. To be able to identify the form from within your submit handler, you need the form id ($form_id) submit data, you need the form values ($form_values). Both are automatically passed to your submit handler by the Forms API.
In your hook_form_alter():
<?php
$form['#submit']['my_very_own_submit'] = array();
?>And your submit function prototype:
<?php
function my_very_own_submit($form_id, $form_values)
?>Additional parameters
You can, if desired, pass additional parameters to your submit function. Your hook_form_alter() would then be like this:
<?php
$form['#submit']['my_very_own_submit'] = array($parameter_three, $parameter_four);
?>And your submit function prototype:
<?php
function my_very_own_submit($form_id, $form_values, $parameter_three, $parameter_four)
?>Getting your submit function called first
If you'd like to alter user input before it gets saved to the database, you'll want to force your submit function to the top of the $form['#submit'] array like so:
<?php
$form['#submit']['my_very_own_submit'] = array();
$form['#submit'] = array_reverse($form['#submit']);
?>Drupal 4.7
In this case, you need to add your own hook into the _submit chain, but how to do this isn't entirely straightforward, because you have to provide the hook with the arguments; one of these arguments needs to be a reference to $form_values, which you don't have yet. Or do you?
Turns out, forms API actually does provide the reference for you -- on the existing submit hook. All you have to do is clone it:
In your hook_form_alter:
<?php
$form['#submit']['my_very_own_form_submit'] = current($form['#submit']);
?>Just put your function name as the key to the array. If you like, add additional arguments using array_merge. ...= array_merge(current($form['#submit']), array($arg1, $arg2, $arg3);
This same approach will also work with #validate, #process, or #after_build callbacks.

Thanks to some help on IRC,
Thanks to some help on IRC, I found
<?php$form['#submit'] = array('my_very_own_form_submit' =>
array()) + (array)$form['#submit'];
?>
Works
I had some problems when $form['#submit'] didn't exist and current() broke it.
Another thing to bear in mind...
... is that the order that the submit functions get called is the same order that they're in that array - so in Sym's example above, 'my_very_own_form_submit' will get executed BEFORE the origional form's submit hook.
This is often not desirable as you wont know the ID of the submit until you've actually submit and created a node/term/whatever.
I guess you can replace the
I guess you can replace the submit function as well in this method no? by deleting the values in $form['#submit']?
If the form already has more
If the form already has more than one submission function, add your own with:
<?php$form['#submit'] = array_merge(array('my_very_own_submit' => array($additional_parameter)), $form['#submit']);
?>
Custom handler removes default handler?
I found when adding an extra submit handler to a system_settings_form() form, the default handler was not called afterwards.
<?php/**
* Admin settings form callback.
*/
function sitesynch_admin_settings() {
$form = array();
$form['myvariable'] = array(
'#type' => 'text',
'#default_value' => variable_get('myvariable),
);
$form['mybutton'] = array(
'#type' => 'submit',
'#value' => 'Do Action',
);
$form['#submit']['sitesynch_admin_settings_submit'] = array();
return system_settings_form($form);
}
?>
This caught my button for my custom action OK ... but stopped saving the rest of my settings as usual,
I had to then replace the normal form handler myself.
<?php// Adding my own extra handler makes it forget the default one?
// That shouldn't happen. Put it back.'
$form['#submit']['system_settings_form_submit'] = array();
?>
... I'm aware that current practice is to return just the $form and call system_settings_form at a higher level - this was originally 4.7 code now in 5.3. I dunno if that will make a difference.
.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/
updated example for Drupal 6
http://drupal.org/node/222158
If you are going to chain more than one handler...
If you are going to chain more than one handler, do not use array_reverse as is shown in the example. Calling array_reverse multiple times (as in different hook_form_alter instances) will flip flop the array and the handlers may not get invoked in the order in which you expect. If the original handler called drupal_goto(), then your handler may never get invoked. Instead, to be sure that your handler gets invoked before the original handler in any case, do something like:
$form['#submit'] = array_merge(array('my_very_own_submit' => array()), $form['#submit']);
(D5 example)
in D6, node/add, I
in D6, node/add, I have:
array_unshift ($form['#submit'], 'my_function_submit');