I implement corporate marketing websites, which often have contact forms. I've implemented four since March, am currently working on a fifth, and all of them had conditional routing: They went to one or more selected people, based on characteristics of the form.

For example:

  • if the person filling the form self-identifies as a "member of the media", the form is routed to the PR person.
  • if the person checks a box to request a sales visit, the form goes to the sales manager

... and so on.

Webform has everything I need except this.

My experience leads me to believe this would be a pretty common need. The Feedback form can do single-person routing, but it can't easily be expanded to include extra fields. (That's a requirement. Clients always want way more information on their feedback forms than is there in the Drupal feedback form. Not directly relevant, here, since webform addresses that, but that's why I can't use feedback.)

I found a patch to implement something that looks like this in the 4.6 version of webform, and I've looked at the patch code to see if I could adapt it. But:

  1. I've got no experience with the Drupal API
  2. My php skills are not at the level that allows me to grok this stuff quickly and easily.
  3. That said, looking at the patch code leads me to think the 4.6 and 4.7 versions of webform are pretty seriously different, and I'm having a hard time figuring out where the 4.6 patch relates to the 4.7 code.

So, I'm posting this as a feature request for 4.7, even though there is a 4.6 patch.

Comments

quicksketch’s picture

Hi there escoles, I know it's been a while since you posted this request (we've had it before, without much progress), but I'm posting because a recent addition to webform CVS version might be able to help your cause. I added in two additional fields in the "Advanced Settings" of webform for 'additional validation' and 'additional processing'. This basically allows you to perform additional verification on fields (like phone numbers or URLs, etc) and also perform additional tasks after the form is submitted (like sending out extra emails).

The learning curve is pretty steep, and it basically requires some knowledge of Drupal and PHP. Since I just put this to use, I'm posting my code as an example.

I put together an advanced submission form for inviting new users to a site. It asks for email addresses of a users friends, then checks if they are currently a user of the site. If a user is registered, it throws an error. If none of the new email addresses are registered users, then an email is sent out to all users 'inviting' them to join the site. Here's the code to get started:

The validation code:

foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webformcomponents[$field_id];
  if (strpos($component['name'],"Friend Email") !== FALSE && valid_email_address($value)) {
    if ($validUser = user_load(array('mail'=>$value))) {
      form_set_error($field_id,t('The email "%email" is already in use by user "%name"!',array('%email' => $value,'%name' => $validUser->name))); 
    }
  }
}

And the additional processing code:

$friendEmails = array();
foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webformcomponents[$field_id];
  if (strpos($component['name'],"Friend Email") !== FALSE && valid_email_address($value)) {
    $friendEmails[] = $value;
  }
  if ($component['name'] == "Your Email" && valid_email_address($value)) {
    $fromEmail = $value;
  }
  if ($component['name'] == "Your Name") {
    $fromName = $value;
  }
}
    
$message = "

Your message here.

Signup now for our website at http://www.example.com!

";

$header = "From: ".$fromName." <".$fromEmail.">";
$subject = "You're invited to MTV Flux!";

user_mail(implode(', ',$friendEmails), $subject, $message, $header);

I hope this helps.

escoles’s picture

When I've got breathing room after the current project, I'll check it out.

quicksketch’s picture

Title: Conditional Recipient Based On Select » Additional Validation and Submission Fields
Version: 4.7.x-1.x-dev » 5.x-1.x-dev

I've linked to this page from the webform project page to help others get started with validation/submission code.

BioALIEN’s picture

Just what I was looking for. Cheers quicksketch :)

nshreders’s picture

I previously wrote a patch for webform 4.7 to prepend text in the subject line. 5.x allows for additional processing but I'm not able to get it to work. I tried:

<?php $email_subject = "dummy_text: " .  $email_subject; ?>

So the email sent out will have the subject of "dummy_text: ". It's just showing the I have set for the subject. Does anyone have any suggestions? I'm doing this so recipients can setup filters in their email clients.

Marc Bijl’s picture

Hi,

I stumbled upon this page looking for a way to send a confirmation e-mail to an (anonymous) user after submitting a webform. The code here seems to be what I was looking for, so that's the good news. The bad news however: it gave me an error.

I'm not a programmer, but I think the function user_mail needs to be replaced by drupal_mail:
- http://drupal.org/node/64279#drupal-mail

This seems to work :)

But, a $mailkey is needed. Can anyone please explain (idiot proof) what this is and which value(s) I can use?

Cheers,
Marc

BTW
I like to include an order number or something in the confirmation e-mail, e.g. the value of the submitted field in the submissions table. Does anyone know how to achieve this? Many thanks in advance!

quicksketch’s picture

@New Oceans, good question. The code posted above was for a 4.7 site, which used user_mail(). The function has now be renamed to drupal_mail() and has new super powers. :)

The $mailkey parameter you mention can be anything you like. I recommend something like "webform_anonymous" or "webform_nid_x", so that it correlates to your particular use-case. This "mailkey" is used by hook_mail_alter(), so any module may modify the mail as necessary (like creating an html mail which automatically adds links for http addresses).

So, just make it whatever you like. You'll probably never need to reference it, but follow good practice and make it something unique and relevant.

neurojavi’s picture

Hi:

This is what I was looking for!
But I'm unable to find those 2 options for additional validation and processing it in the 5.x version of this module?
Is there a patch or have I to use the HEAD version?

Many thanks.-

neurojavi’s picture

ops! Please forget my message above. I've found those options! It was a problem of mine.
Sorry for the noise.

ellen.davis’s picture

I am having the same issue as the original author of this thread. I need to route the email by Topic. I created a webform with a drop down list of Topics. Can the additional processing change where the email is sent to depending on the Topic?

rick hood’s picture

Your comment is old, but I had to do the same thing so am posting what I did here.

I followed the basic method that quicksketch outlined.

First, I wanted to put all my form processing code in another separate file, so I could just work on that file, so in the 'Additional Processing:' field on the web form, I put this:

require_once './process/inquiry_process.php';

…so now I am just working on the 'inquiry_process.php' file and I stuck in the folder called 'process'. You don’t have to do it that way, you can just stick the code below in the 'Additional Processing:' field.

Here is the code:


/*first need to get the value that was chosen from the Topic drop down */

foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webformcomponents[$field_id];
  if ($component['name'] == "Topic") {
    $Topic = $value;
  }

/*
and I will grab the value of one other form field for this example: Comment 
which will end up being the body of my email
 */
 
 if ($component['name'] == "Comment") {
    $Comment = $value;
  }


/*
now determine routing based on value of Topic
the variable $to will be the email address that the form will submit to
*/

$to = "default@example.com";

if ($Topic == "Politics") {
$to = "politics@example.com ";
}
if ($Topic == "Religion") {
$to = "religion@example.com";
}
if ($Topic == "Science") {
$to = "science@example.com";
}

/*
so now you have where the email is going to in the variable $to
now build and send the email by defining: 
$body
$mailkey
$subject
$from
I forget exactly what $mailkey does, but you can look it up
*/

$body = $Comment;
$mailkey = "inquirywebform";
$subject = "Put subject here";
$from = "from@example.com";

/*
the following Drupal function sends the email.
*/

drupal_mail($mailkey, $to, $subject, $body, $from, $headers = array())

tsernobyl_good_times’s picture

For me this script doesn't seem to work. I tried recreating the example - I made components 'Topic' (with same options, Religion, Politics and so on) and a textfield 'Comment'. When I try to send a form, all I get is a following error message:

Parse error: syntax error, unexpected $end in /home/www/sites/all/modules/webform/webform.module(1337) : eval()'d code on line 58

I parsed the script line by line and it seems that the error is in following part:

foreach ($form_values['submitted'] as $field_id => $value) {
$component = $node->webformcomponents[$field_id];
if ($component['name'] == "Topic") {
$Topic = $value;
}

rick hood’s picture

After my above post I found I was having trouble with drop down choices that were multiple choice.

This does not work for 'multiple-choice-allowed' drop downs:

if ($component['name'] == "Topic") {
$Topic = $value;
}

But this does:

if ($component['name'] == " Topic") {
        foreach ($value as $key => $choice) {
		if ($choice != "") {
      	$Topic .= $choice ." ";
		}
    }
  }
CMatters’s picture

Ok.. this is probably going to come very close to going in the stupid question category. I have found this thread very useful and has resolved a major issue.

However, I have one concern... When using $component['name'], the code will look for the "human readable" field name for a form. I'd rather use the machine readable name assigned to the field. I see it shows up in the rendered HTML source of the form. Is there a way to do that?

For example, right now I am using

$component['name'] == "Daytime Phone Number"

When I'd rather be using

$component['xxxx'] == "daytime_phone"
// where xxxx is the proper label for machine readable field name.

Thanks!

rick hood’s picture

I believe you use this instead:

$component['form_key'] == "daytime_phone"

I found that by looking in the database table called 'webform_component'.

ThadC’s picture

Anyone know how to make the FCKeditor module play nice with webform? When submitting a webform I get an error which reads:

warning: mysql_real_escape_string() expects parameter 1 to be string, array given in blahblah/Drupal/includes/database.mysql.inc on line 400. 
warning: Illegal offset type in blahblah/Drupal/modules/webform/components/select.inc on line 273. 

Any ideas?
TJ

ellen.davis’s picture

Here is what I came up with. I do not use drupal_mail to send the email. Rather, this script sets $node->email and lets webform send the email.


<?php

$subject_prefix = "MYWEBSITE: ";

/* default TO email,  should not really be used, set here just in case */
$node->email = "someone@email.com";

/* this corresponds to Topic drop down list when submitting email form */
$ToEmail = array();
$ToEmail['Accounting'] = "accounting@email.com";
$ToEmail['Administration'] = "admin@emai.com";
$ToEmail['General'] = "general@email.com";
$ToEmail['Other'] = "other@email.com";


foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webformcomponents[$field_id];

  /* set To email based on Topic */
  if ($component['name'] == "Topic") {
     if (isset($ToEmail[$value])) {
        $node->email = $ToEmail[$value];
        }
    }

  /* append prefix to Subject */
   if ($component['name'] == "Subject") {
      $form_values['submitted'][$field_id] = $subject_prefix . $value;
   }

  }
?>

archetwist’s picture

What about the 2.x version of the module? I've tried to modify the code but with no success. Could someone post an updated snippet?

abraxsus’s picture

Category: feature » support

I've just started with Drupal - and think it's great - and Webform. Today I made my first form with a datefield, but it doesn't automaticly check the input (year field) if it's a correct date. Also the year range has to be between 1920 to 1991. I've been strugeling to find a solution, but my knowledge of PHP and the Api is minimal. Is there anybody who can help me out?

quicksketch’s picture

Status: Active » Closed (fixed)

I've started a series of handbook pages on using the additional validation and submission fields under the main webform handbook page. Please post any new snippets there: http://drupal.org/node/197550

Or if you have a request for a new snippet create an issue.

nina_bee’s picture

Hi,
I also try to add aditionnal processing to my form. I have a form that non-autentified and autentified users can access to order. I need to check the email adress. If the email adress is unknown, then the user us automatically regisered with is first name as a login and his email adress as a password. Then he recives a mail with his infos. If the user is already regisered then nothing else happens.
This is the code (based on quicksketch's code above) :

Additional Validation

<?php
foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webformcomponents[$field_id];
  if (strpos($component['name'],"E-mail") !== FALSE && valid_email_address($value)) {
    if ($validUser = user_load(array('mail'=>$value))) {
      form_set_error($field_id,t('L'adresse mail "%email" est déja utilisée paru "%name"!',array('%email' => $value,'%name' => $validUser->name))); 
    }
  }
}
?>
Additional processing
<?php
$Emails = array();
foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webformcomponents[$field_id];
  if (strpos($component['name'],"E-mail") !== FALSE && valid_email_address($value)) {
    $Emails[] = $value;
  }
    if ($component['name'] == "Prénom") {
      $prenom = $value;
    }
    if ($component['name'] == "E-mail"&&valid_email_address($value)) {
      $mail = $value;
      $pass = $value;
    }
    db_query(INSERT INTO {users} (name, pass, mail, init) VALUES ('$prenom', '$pass', '$mail', '$mail');
    echo $mail;  
    $fromEmail = 'info@site.com';
    $fromName = 'Site';
  
}
    
$message = "

Your message here.

Signup now for our website at http://www.example.com!

";

$header = "From: ".$fromName." <".$fromEmail.">";
$subject = "You're invited to MTV Flux!";

user_mail(implode(', ',$Emails), $subject, $message, $header);
?>

This send me an error :

Parse error: syntax error, unexpected T_STRING in /homepages/14/d239557980/htdocs/drupal/modules/webform/webform.module(1458) : eval()'d code on line 6

Parse error: syntax error, unexpected T_STRING in /homepages/14/d239557980/htdocs/drupal/modules/webform/webform.module(1504) : eval()'d code on line 15

Do you have an idea?
Thanks

isaac77’s picture

davis4104: thank you for that code snippet, it was very helpful.

archetwist: The code in the example provided by davis4104 needs to be modified for use with webform 5.x-2.* I'm not an expert with this module, but here's what worked for me:

$node->email = $ToEmail[$value];
needs to be changed to
$node->webform['email'] = $ToEmail[$value];

also, in webform 5.x-2, you can set "additional" emails like this:

$node->webform['additional_emails']['sales'] = "email address (or variable containing address) here";
$node->webform['additional_emails']['press'] = "email address (or variable containing address) here";

Of course you do not have to use advanced -> additional processing to set those "additional emails" in all situations... In some cases, it is easier to set those values in the e-mail address and 'conditional e-mail recipients' fields.

j2g2’s picture

Hi, where do you place the php code? In what file?

Thank you for your help.

ericcorriel’s picture

Version: 5.x-1.x-dev » 6.x-2.4

For anyone using Webform 6.x-2.4 you may want to use the following code as the code above (which makes reference to $node->webformcomponents) is, I believe, no longer valid in 6.x.-2.4. I use the following to check for a valid email address:

foreach ($form_values['submitted'] as $field_id => $value) {
  $component = $node->webform["components"][$field_id];
  if ($component['name']=="email" && !valid_email_address($form_values['submitted'][$field_id])) {
      form_set_error($field_id,t('The email "%email" is not valid.',array('%email' => $form_values['submitted'][$field_id],'%name' => $validUser->name)));     
  }
}
m.e.’s picture

Title: Additional Validation and Submission Fields » Help with, and documentation of, proper syntax
Status: Closed (fixed) » Active

I've been through several of these posts and tried various validation snippets without success. Is there some clear documentation that I've missed? How do we know what will work in which version of Webform?

My site has 6.x-2.4 installed. Code like what was posted above by noblends doesn't break my page, but it also fails to identify invalid submissions.

Can someone who has successfully appeased the 6.x-2.4 Webform gods please provide a very basic primer that clearly shows which elements in the code snippet are standard to Webform and which are just examples of variables in her/his page? (For example: is 'submitted' common to all Webform code? is 'name'? is $component?)

quicksketch’s picture

Title: Help with, and documentation of, proper syntax » Additional Validation and Submission Fields

Check out the webform documentation at
http://drupal.org/handbook/modules/webform/submission-code and
http://drupal.org/handbook/modules/webform/validation-code

for some more examples. All snippets should work in any version of Webform 2.x. The only variables that are available are $node and $form_values, everything else comes out of those two variables.

m.e.’s picture

Thanks - I actually read the validation-code page, couldn't get anything to work, and posted a comment there that no one has answered. (My code has changed twice since I posted that comment - still no luck.)

I have a grid with dollar amounts (labels like "$100" "$25" ... "Other"). Database name for this choice is 'set_amount.' Below the grid is a textfield keyed as 'typed_amount.' If "Other" is selected in the grid, I want to require a numeric value in the textfield.

I'm pretty sure I'm just not getting how to properly reference the selections in my IF statements. It might help if the snippets included examples of labels, keys, etc. for the Webform components being validated.

jamescross’s picture

Hi, I have created a food order form and I need users to submit the date and time they wish to collect their food. However, after 10:30am I do not want the date field to display today's date as an available collection date. Do you know if I can achieve this using the additional validation section.

Thank you

quicksketch’s picture

Status: Active » Closed (fixed)

Per the submission guidelines, help with custom coding including theming, custom validation, or form_alter() is not provided in the Webform issue queue. I'd suggest referencing the handbook pages as noted in #28.

sdmaxey’s picture

Is it possible to use the Additional Submission to send the field values off to an external SOAP server so that our email provider can do double-opt-in validation. I was able to build a simple php form outside of Drupal that worked, but of course didn't have the validation and security within Drupal and webform.

There are hints here that suggest a possible path for what we want to do, but others that make me think its not possible. I've already read the documentation.

#11 suggests a way forward, but I seem to be missing the point where I can send the data using the nuSOAP client to the SOAP server instead of the webform data table.

Can someone point me in the right direction?