Validating & Submitting Forms To Other Websites With Drupal

Photo of Greg Harvey
Wed, 2009-06-10 10:49By greg

So you've got a client who wants to have a Drupal form send something off to another website. In my case my client wanted to manage their newsletter from the SalesForce CRM (which they doubtless paid gazillions of dollars for, so they'd better bloody well use it, etc.) so newsletter sign-ups needed directing there.

No problem, I thought - build a Drupal form in the usual way and add the '#action' form attribute, setting it to the remote URL the form needs to be submitted to. Tried that, it worked. Happy days.

Now to add some validation... What the deuce?? My validation has no effect! Turns out this is by design. If you post your data off to another site, then that site has the task of validating. Except in my case it doesn't. Rats.

Now what? Well I found this post about using drupal_execute() for executing your form, but this is no good - it will never work, because drupal_execute() is for local use, assumes so and ignores '#action' in forms.

So it was longwave in #drupaluk IRC (again!) who suggested using drupal_http_request instead. This way I can leave my form alone, let it do the usual stuff in the usual Drupal way (present a form, validate the submission) and then post it off in the submit function for the form.

Thanks to this post on sending data using drupal_http_request (read the replies too!) I was able to write a submit function that looked something like this (obviously for the form with ID of my_module_newsletter_form):

function my_module_newsletter_form_submit($form, &$form_state) {
// remote URL we want to post to
$url = 'https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
// set our headers
$headers = array(
'Content-Type' => 'application/x-www-form-urlencoded',
);
// the actual sending of the data
$response = drupal_http_request($url, $headers, 'POST', http_build_query($form_state['values'], '', '&'));

// if we get a good response, thank user for submission
if ($response->code == 200) {
drupal_set_message(t('Thank you for subscribing to our newsletter.'));
// otherwise let them know something went wrong
} else {
drupal_set_message(t('There was a problem with your submission. Please try again later.'), 'error');
}
}
?>

And that's all there is to it. Once you have let Drupal handle building the form and managing all the validation you can *then* submit your data off to another site. I have tested this and the response data looks good. Only thing left to work out is why I'm not getting my debug email, as I am getting a positive response from the SalesForce script, but that's another story. Wish me luck! =(

Edit: Got my debug email in the end. Turned out I needed to set the Content-Type request header properly. Updated the above code snip to include the necessary change.