Why is my custom webform submit handler not submitting? I've looked at a number of posts, but none of them have quite the same issue as I am. I've added two custom submit buttons to a webform (in addition to the default one created by the admin page.) My custom validate function and submit function are being called, but the default submit function is not - i.e. the error logging I've put in my custom function gets printed, but the form is NOT actually submitted. Any ideas?

function create_vector_user_form_alter(&amp;$form, &amp;$form_state, $form_id) {
  switch ($form_id) {
  case 'webform_client_form_24': // free trial webform
    $form['submit']['64_bit_btn'] = array(
      '#name' =&gt; 'op',
      //'#button_type' =&gt; 'submit',
      '#type'   =&gt; 'submit',
      '#value' =&gt; t('DOWNLOAD 64-BIT TRIAL'),
      '#executes_submit_callback' =&gt; TRUE,
    );

    $form['#validate'][] = 'create_vector_user_free_trial_form_validate';
    $form['#submit'][] = 'create_vector_user_free_trial_form_submit';
    $form['actions']['submit']['#submit'][] = 'create_vector_user_free_trial_form_submit';
    break;
  }
}

function create_vector_user_free_trial_form_validate($form, &amp;$form_state) {
// this function runs correctly

}

    function create_vector_user_free_trial_form_submit($form_id, &amp;$form_state) {
    error_log("submit!");
    if (strtoupper($form_state['clicked_button']['#value']) == 'DOWNLOAD 64-BIT TRIAL') {
        error_log("submitted 64");
    }
    else if(strtoupper($form_state['clicked_button']['#value']) == 'EMAIL ME A LINK') {
        error_log("submitted email");
      $to = $form_state['values']['submitted']['email']; 
      $params = array();
      $params['version'] = $form_state['values']['submitted']['download_type'];
      $key = 'homepage';

      drupal_mail('create_vector_user', $key, $to, language_default(), $params);
    }

    else {
        error_log("submitted default 32");
    }

  error_log("test end");

}


ETA: I've also tried this in my form_alter function based on this article about custom validation:

$form['#validate'][] = 'create_vector_user_free_trial_form_validate';
// $form['#submit'][] = 'create_vector_user_free_trial_form_submit';
$first = array_shift($form['#submit']);
array_unshift($form['#submit'], $first,'create_vector_user_free_trial_form_submit');


//$form['actions']['submit']['#submit'][] = 'create_vector_user_free_trial_form_submit';
I found the problem. 

One of the features of webform is the ability of have multi-page forms, and the way how webform determine if it is in the "final" page is checking if the submit button has the value "Submit" and if that is not the case then it thinks to there is another page to evaluate before to submit the last function.

You can see this in the file webform.module in the line 3174:

 // Check for a multi-page form that is not yet complete.
 $submit_op = !empty($form['actions']['submit']['#value']) ? 
 $form['actions']['submit']['#value'] : t('Submit');
 $draft_op = !empty($form['actions']['draft']['#value']) ? 
 $form['actions']['draft']['#value'] : t('Save Draft');
if (!in_array($form_state['values']['op'], array($submit_op,   
$draft_op, '__AUTOSAVE__'))) {


In the case of your example $form_state['values']['op'] doesn't exists and even if it exists it wouldn't has the value 'Submit'  so it  will try to handle your form as a multipage form and It will not execute the last part of the function. 

What I did to make your example work was only add the this in your submit function $form_state['values']['op'] = 'Submit'; and that's it. 

It feels like a hack but that is the way how webform work :(

Below the example if you want to compare it with your code:

&lt;?php

/**
 * Implements hook_form_alter().
 */
function test1_form_alter(&amp;$form, &amp;$form_state, $form_id)
{
    switch ($form_id) {
        case 'webform_client_form_5':
            $form['64_bit_btn'] = array(
                '#name' =&gt; 'op',
                '#type' =&gt; 'submit',
                '#value' =&gt; t('DOWNLOAD 64-BIT TRIAL'),
            );
            $form['#validate'][] = 'create_vector_user_free_trial_form_validate';
            array_unshift($form['#submit'], 'create_vector_user_free_trial_form_submit');
            break;
    }
}

function create_vector_user_free_trial_form_validate($form, &amp;$form_state) {
    // this function runs correctly
}

function create_vector_user_free_trial_form_submit($form_id, &amp;$form_state) {
     // add your code here
    $form_state['values']['op'] = 'Submit';
}


(please note to my module is called test1 you need change this with the name of your module)