Last updated 18 December 2016. Created on 10 August 2011.
Edited by ninisama, jrockowitz, ronliskey, daveparrish. Log in to edit this page.

In 3.x and newer versions of Webform, the use of PHP validation and processing is deprecated because it's unsafe, but you can do whatever you need to within a custom module. Here are the most important parts you'll need for your module to communicate with your webform and validate or process the data available to the webform.

In this example, I have a webform that allows visitors to register for an event. After the user submits the form, they receive a confirmation page that uses some of the submitted data. It prints an ID and sends an email with the same information. I'll be using the 7.x version for this example but if you know how to code, you'll have no problems downgrading to 6.x-3.x

The first step is to create a hook_menu with the callback to hold the confirmation page:

function reg_menu() {
  	$items['register/confirmation/%/%'] = array(
		'page callback' => 'reg_confirmation_page',
		'page arguments' => array(2, 3),
		'access arguments' => array("access content"),
		'type' => MENU_CALLBACK,
		'title' => 'Confirmation',

        return $items;


This is pretty straight forward, all you need to do now is go to your webform configuration form and set that you want to redirect the user to a new page after form submission. The page you'll need to enter is: register/confirmation/%nid/%sid

The nid and sid values will be replaced by webform and our module will recognize them.

Now create the page callback 'reg_confirmation_page'.

// The $nid is not actually used here, but I'm adding it in case you need to get some data from the webform node.
function reg_confirmation_page($nid, $sid) {
        // Get the submission array
	$submission = webform_menu_submission_load($sid, $nid);
	// Process the submission
	$data = reg_confirmation_process_submission($submission);
	// I'm adding some CSS to theme the confirmation page.
	drupal_add_css(drupal_get_path("module", "reg") . "/reg.css", array('media' => 'screen'));
	drupal_add_css(drupal_get_path("module", "reg") . "/reg-print.css", array('media' => 'print'));
	// Process the data throught the theme layer
	$output = theme("confirmation_page", array('data' => $data));
	// Send the mail
	reg_send_email("confirmation", $data);
	return $output;

As you can see, after I get the $submission from the 'sid', I send the data through another function to process the data. What does it mean? It means that webform presents the data array in a not very friendly way, so we need to simplify this for the rest of our module.

function reg_confirmation_process_submission(&$submission) {
	if($submission) {
		$data = array(
			'sid' => $submission->sid,
			'last_name' => $submission->data[1]['value'][0],
			'name' => $submission->data[3]['value'][0],
			'email' => $submission->data[4]['value'][0],
		return $data;

We just create a $data array using the information of the $submission object. Remember that this object will be built when you add fields to your form, but in a general way, you'll have something like this:


$submission is the object
->data is the array of arrays that holds the data provided by the user
[foo] this is a number that webform assigns when you add this field to the form. This number is not affected if you arrange the order of the fields at your form.
['value'][bar] if you use multiple values, you'll end up with an array that you'll have to process in some way. All my values are single so I'll always have ['value'][0]

One last thing. The reg_send_mail() function is a function I'm using to send an email. I won't explain it here, the only thing I need to mention is that you can send an email and because I'm passing the $data array to this function also, I can use all the information in the array when I send the email.

Looking for support? Visit the forums, or join #drupal-support in IRC.


papagenic’s picture


I tried to reproduce this. It almost works, but there is still a problem with the retrieval of the nid and sid values:
In the form settings, I use a custom confirmation url as explained: register/confirmation/%nid/%sid

With these settings, the confirmation url opened in the browser is then : register/confirmation/%25nid/%25sid&sid=154 and this cause the reg_confirmation_page to be passed the values "%nid" and %sid" for $nid and $sid, preventing the retrieval of the form data.
Can anybody tell me what i am doing wrong?


lelizondo’s picture

I really don't know what to tell you. Whey you go to your form (node/nid/webform/configure) do you see the Token fieldset? Those are the values that you should enter in the custom URL.

I'm using this solution with D7, I don't know if you're using D6 and this could be the problem.


capellic’s picture

Is there no better way to reference the submission data? The idea of referring to specific fields with incremental indexing scares me:


What happens if I add a new field to the form resulting in the value in the array above not being what I assumed it to be? Is there a way to pull the data in an associative array with the component's machine name?

lelizondo’s picture

Yes, there is a better way to do it. I haven't tried but I guess you could load all the fields and then create an administration page where you can just select what fields you want.

I will soon be working on a project that requires to recycle this process in multiple sites and with different fields so what I've just described I'll just be doing it in the next few weeks. Once I have a solution, I'll post it here.


lelizondo’s picture

I've just found this that explains how to do exactly what you're asking.


RAWDESK’s picture

Yes there is a better way dealing with this data array.
Simply explained : You can match the array keys with the component id's from the webform.

Try to execute this piece of code in devel and you'll see what i mean :

$node = node_load($my_webform_nid);
$nodes = array($node->nid => $node);
dpm($components = $nodes[$node->nid]->webform['components']);
dpm($data = webform_menu_submission_load($my_sid,$my_webform_nid)->data);

Both arrays now have the same key so by simply matching both keys and refer to $components[$cid]['form_key'] to identify your required field, you can avoid mismatching symptoms when webform is altered.
Hence, it's even possible to replace your $data key with form_key before actually starting to evaluate your data...

joelrosen’s picture

I made a submodule that allows use of tokens in webform's confirmation messages. So this way you can use tokens like [webform:webform-val-your_field_here] in your confirmation message, editable in webform's online admin interface. See the sandbox project here:

It's working great for me, but I'd like to hear what other people think of this approach, and if there are any security issues, before I apply for full project status. It works by storing the ID of the user's submission in $_SESSION and checking that this key is set before allowing access to confirmation pages.