0

What I'm trying to achieve

I am successfully using the Form API in Drupal 7 to dynamically alter Webforms to redirect to an off-site URL on submit.

What I need is twofold; I need (a) for the client to visit the offsite URL so the site can store a lead via query string parameters, as well as (b) for the same information to be documented in my local Drupal database.

Every lead must be documented, so I have tentatively ruled out JavaScript/AJAX as an option.

How I tried it

I thought the best way to do this was to set up a module with $form_state['redirect']:

/**
 * Implement hook_form_alter to change the form's submit action
 */
function myform_form_alter(&$form, &$form_state, $form_id) {
    $form['actions']['submit']['#submit'][]='myform_submit';
}

/**
 * Callback as specified above
 */
function myform_submit($form, &$form_state) {
    // Values for the query string
    $vals = array('mykey' => 'myval');

    // Redirect appropriately
    $form_state['redirect'] = array(
        // $path
        'http://www.anotherwebsite.com/',
        // $options
        array('query' => $vals),
        // $http_response_code
        302,
    );
}

I did that, and as expected, the user is redirected immediately after form submission. However, the Form API does not submit to my database before redirecting the user.

I read the FAPI documentation for Drupal 7. I sought using #action, although it apparently reports only accepting internal values and my users must visit an offsite URL. I wound up using redirect in the meantime, which was no longer documented but was suggested in the comments.

Where do I go from here?

EDIT: tenken's response works, but I have another problem!

My callback now uses array_unshift($form['#submit'],'my_callback') and via drupal_http_request, is submitting to both websites. However, my webform is still not saving submissions locally, and instead on submit, redirects to self (even with no hook_form_alter).

  • 1
    By "does not submit to my database" do you mean the Webform module doesn't save it's data to the db? – Clive Mar 29 '12 at 17:31
2

EDIT: added option (1) after thinking about this more, haha. It's a much simpler solution.

(1)

If the below is to complex you (and you actually want to POST something) you could form_alter the form and append your own additional FAPI #submit function which uses drupal_http_request() to POST/GET the url with all the submitted form params.

(2)

I think you want to set the destination value from within the #action of the form to be wherever the default webform submit path is and tag on a destination querystring parameter to the action which drupal will then goto after the form has been validated/submitted.

I know you said you tried using #action but I'm talking about the action being the drupal action and destination being a remote url (url-escaped).

Eg, I have customized a login form to use various login backend logic depending on the url of the login: /user/login, /student/login, /staff/login ... etc. I then make the destination of a succcessful login goto a specific drupal page. destination is used by drupal_goto() to redirect the user anywhere -- even an external url.

Here is a small example from code I have in D7:

/**
 * The following 2 functions allow our form overrides to occur.
 */
function MYMODULE_form_user_login_block_alter(&$form, &$form_state) {
  if (_MYMODULE_auth_is_student_login_page_url()) {
    $form = $form + array('#auth-destination' => 'student');
    _MYMODULE_auth_user_login_form_alter($form, $form_state);
  }
  if (_MYMODULE_auth_is_staff_login_page_url()) {
    $form = $form + array('#auth-destination' => 'staff');
    _MYMODULE_auth_user_login_form_alter($form, $form_state);
  }
}

function MYMODULE_form_user_login_alter(&$form, &$form_state) {
  if (_MYMODULE_auth_is_student_login_page_url()) {
    $form = $form + array('#auth-destination' => 'student');
    _MYMODULE_auth_user_login_form_alter($form, $form_state);
  }
  if (_MYMODULE_auth_is_id_login_page_url()) {
    $form = $form + array('#auth-destination' => 'staff');
    _MYMODULE_auth_user_login_form_alter($form, $form_state);
  }
}

function _MYMODULE_auth_user_login_form_alter(&$form, &$form_state) {
  global $conf;
  $saveForm = $form;
  $form = array();
  # overrides the default validator.
  foreach ($saveForm as $key => $value) {
    if ($key == '#validate') {
      $form[$key] = array();
      foreach ($value as $validator) {
        if ($validator == 'user_login_authenticate_validate') {
          // If we progressed down to this level of nested Alters, we have
          // #auth-destination.
          $type_of_login = $saveForm['#auth-destination'];
          switch($type_of_login) {
            case 'staff':
              // These functions are custom validate functions whose logic is
              // copied/altered from the default
              // 'user_login_authenticate_validate' implementation.
              $validator = 'MYMODULE_auth_staff_authenticate_validate';
              // the form posts back to itself and supplies a unique destintation.
              $form['#action'] = '/?q=staff/login&destination=%3Cfront%3E';
              break;
            case 'student':
              $validator = 'MYMODULE_auth_student_authenticate_validate';
              // the form posts back to itself and supplies a unique destintation.
              $form['#action'] = '/?q=student/login&destination=student/my-surveys';
              break;
            default:
              break;
          }
        }
        $form[$key][] = $validator;
      }
    }
    else {
      $form[$key] = $value;
    }
  }
  $form['name']['#title'] = ($type_of_login == 'Staff') ? 'Staff Username' : 'StudentCampusID';
  unset($form['links']);
}
  • Hi @tenken, thanks! I've tried both methods, but I like that #1 keeps the user on the page. The form now (a) submits to the foreign website, and (b) returns to the "action" attribute after submitting. However, I still get "There are no submissions for this form" when viewing the results tab. Am I appending the additional #submit correctly? (pastebin.com/bhnQZiSH) Reading the documentation, it looks like it uses an array() to specify the #submit callback, but that throws me a server error. – Morgan Delaney Apr 4 '12 at 22:52
  • Just a note, I've decided to go the route of array_unshift($form['#submit'],'my_custom_callback');, which seems to work (to some extent). However, I've completely disabled my module, and it looks like I'm having further problems with the Webform module itself just not submitting anything. – Morgan Delaney Apr 5 '12 at 20:52
  • Are you using D7 webforms? or a FAPI custom built form. Webform may be processing its forms in another manner (that you should be able to hook into I believe). So, you should be able to track down the issue similar to this thread: drupal.stackexchange.com/questions/9436/… – tenken Apr 6 '12 at 3:33
  • @tenken I'm using D7 Webforms. Your solution answered my original question, and that article is something I've tried and makes sense (thank you). but even with zero altering, my Webform submit handlers aren't saving...a whole other issue altogether! (I've opened a separate Drupal Question.) – Morgan Delaney Apr 7 '12 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.