The additional processing field adds the ability to do additional post processing with PHP. While this is generally a nice feature, it is handicapped for one particular use - redirecting the user to another url. I say it is handicapped because the additional processing occurs before the submission is logged or an email is sent. That makes sense for additional processing of the form fields - any processing that changes the submitted values should occur before those values are recorded in the DB. However, this makes the additional processing field less than ideal for redirecting to custom or dynamic urls.

A solution I've implemented and am testing now is to create a webform submission hook. It will be called just before the natural redirection would occur, which is well after the email submission and databased logging. This is a more flexible solution, though it is a bit more complicated. Not very complicated, you just need to create a mini module to house the function hook_webform_submission.

Does anyone have any suggestions or requests while I'm working on it?

CommentFileSizeAuthor
#1 webform_patch_1.txt1.07 KBscafmac

Comments

scafmac’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new1.07 KB

Patch attached. Pretty simple...

To use the hook, you will need to create an instance of hook_webform_submission where hook is replaced with the name of your module. So for example in my testing I used a module named test that consisted of two files living in a folder named test in the modules directory. Those files were:

test/test.info

name = test
description = "Module for testing webform hook"
package = Administration

test/test.module

<?php
  function test_webform_submission( $submission ) {
    $url = "https://www.example.com/public/register";
    $query = "s=stlawevr&NAME_FIRST=${submission['firstname']}";
    drupal_goto($url, $query);
  }

That's it. Once the module is enabled on the admin pages, all submissions will run this function after emails are sent and submission is logged. Clearly this is a proof of concept - real hook might want to do a conditional redirect. Note that I use drupal_goto instead of php's header function call to do the redirection. Check out the api reference - it handles some niceties so you don't have to.

In theory you could create the hook function within the webform module, but I wouldn't recommend it just to simplify upgrading in the future.

From my perspective hooks are a better way to implement the post processing options - perhaps even for the additional processing functionality that currently exists. To my way of thinking, exposing a field that will except and process php code to site maintainers or the public is pretty risky. By using hooks you can relegate the functionality to the site developers.

Hope it's in the next release... Thanks for the module.

quicksketch’s picture

If a developer is going to go through the work of implementing a hook, why wouldn't they just use hook_form_alter to add an extra submission handler to webforms?

function mymodule_form_alter($form_id, &$form) {
  if ($form_id == 'webform_client_form') {
    $form['#submit']['mymodule_webform_submit'] = array();
  }
}

function mymodule_webform_submit($form_values) {
  drupal_set_message("Do extra stuff to submitted form here");
}

scafmac’s picture

That's a good question & I hadn't considered it. Offhand I would say the patch I wrote makes more sense, since it is not the form that I want to mess with per se or the values, I only want to do a redirect after your great module is finished with it. I believe it requires a bit of hacking the Drupal DB in order to alter the order that module hooks are called, but it is possible. And it would be important to ensure your module has sent any emails and recorded the submission in the DB before any redirect occurs, so the order would be important.

It doesn't seem unusual to me to have a module create it's own hooks & it is only one additional line of code. Many of the bug requests I've seen skirt around this issue of how to extend the functionality of the webform without breaking the email or db logging, so I think it will be used. I agree that if it was general processing of the form values, or something that didn't involve the functioning of the webform module, it would make more sense to use the core hooks. But since I want to only alter the lest step of your process, this seems like the simplest way to do it.

That's my 2 cents - thanks again.

yched’s picture

I'd tend to agree with quicksketch : no need to add another hook to do something that is exactly in the scope of FAPI / hook_form_alter...

scafmac’s picture

Great - could you explain how you would do it?

scafmac’s picture

Status: Needs review » Closed (fixed)

So after some more investigation I've figured it out & indeed the patch is unneeded. It's simpler than I thought to just use the hook_form_alter as quicksketch had recommended, though there are some differences from his example in #2. For one thing, I didn't want to do anything complicated, just to redirect the form once the webform was finished.

As before you need to add this to a module or create a new module. This is only the code from the mymodule.module file - use the example above for the .info file if needed.

  function mymodule_form_alter($form_id, &$form) {
    if ($form['#base'] == 'webform_client_form' && $form['#post']['op'] == 'Submit') {
      $url = "https://www.example.com/public/register";
      if ($form['#post']['submitted']['email'] ) {
        $query = "EMAIL=". $form['#post']['submitted']['email'] ;
      }
      if ($form['#post']['submitted']['firstName'] ) {
        $query .= "&NAME_FIRST=". $form['#post']['submitted']['firstName'] ;
      }
      if ($form['#post']['submitted']['lastName'] ) {
        $query .= "&NAME_LAST=". $form['#post']['submitted']['lastName'] ;
      }
      $form['#redirect'] = "$url?$query";
    }
  }

Some things to notice...

  • unless you only want to apply this to a specific form, you need to check $form['#base'] == 'webform_client_form' not $form_id since it contains the id # appended to the end of 'webform_client_form'
  • I opted to access the fields & values via the $form['#post'] array because it is the simplest to extract field names & values from
  • To do the redirect, just set $form['#redirect'] to the new url, get query included (if applicable)

That's all.

thomas.remington’s picture

scafmac,

Hey Iʻm a bit new to all this, could you help explain this a bit more? I just want to be able to control the redirect url, based on a field in the webform, it seems you have the answer. I tried creating this module, mymodule.module, as well as the mymodule.info... but then drupal just blanks at the module confirm page, when I try to enable it, I guess Iʻm just a bit lost. could you point me in the right direction?

thanks

thomas.remington’s picture

Hey sorry,

everything ended up working ok, I just had a a closing php thingy at the end of the code "?>" this is the first module Iʻve made and so I was just unsure of things.

thanks