This handbook page is not recommended by the Webform module maintainers. Any use of custom PHP code through the Webform PHP module is discouraged.

Support and Webform are two modules that serve different purposes but they are limited in functionality. Both modules can compliment each other to create a great ticketing system.

Compatibility

All of this should work with any version of Webform. However, since 6.x-3.x, the 'Additional processing' textarea was remove so you'll need to install Webform PHP.

What we'll do

We're going to create two sites, one 'frontend' and one 'backend'. The frontend site will have installed Webform and the 'backend' will have installed Support. One a visitor goes to the frontend, he/she can submit a webform and the results will be saved in the 'backend' site as Support nodes. Your support team, can then login into the "backend" site and answer the tickets.

What we'll need

  • Two databases, 'frontend' and 'backend'
  • Two drupal sites 'frontend' and 'backend'
  • No prefix in the databases tables

Installing

We'll have to install two sites as usual. The tricky part here is that we have to configure the 'frontend' site to be able to connect to the 'backend' site.

Once you install the two sites, edit the settings.php of the 'frontend' site. Go to the section where you have the DB settings (around line 92) and see that you have something like this:

$db_url['default'] = 'mysqli://username:password@localhost/frontend';
$db_url['backend'] = 'mysqli://username:password@localhost/backend';
$db_prefix = '';

The first line will be the 'default' DB connection Drupal will use. The second one, is the connection to the backend site. More on this latter.

Installing the Modules

Install this modules on the 'frontend' site:

  • Webform
  • Support
  • CCK (optional)
  • If using Webform 3.x you'll also need Webform PHP

Now, install this modules on the 'backend' site:

  • Support
  • CCK (optional)
  • Views (optional)
  • Chart (optional)

Prepare the sites

In the 'Support Ticket' content type on both sites, you can create a new field to hold the email, If you do this, you have to create the fields in both sites and both fields should be the same. This is totally optional, you can omit this if you want, just remove the line:

$node->field_email[0]['value'] = $email;

from the custom module.

Create your webform

Now, create a webform in the 'frontend' site. I'll make it very simple, I'll create only two components. Email and Message. Create it as you would usually do, we'll come back latter to the form to add some magic to it. I made both email and message fields mandatory. You could change this but the email has to be mandatory, we'll use it latter.

See the next images for an example of my form and my components page.
Form
Components

Create a custom module

On the 'frontend' site, you'll have to create a custom module. This module will be the one to connect the two sites and create nodes on the 'backend' with the information provided by your form.

I'll call my module 'swcon'. This module has three functions, I'll try to explain line by line what it does:

<?php
function swcon_new_node(&$form_state, $webform) { 
  // This is more practical.
  $values = $form_state['values']['submitted_tree'];
  // Connect to the database 'backend', this is not the name of the database, but the 'name' defined in the array for that database in settings.php
  db_set_active('backend');
  
  // Get the email value and 
  $email = $values['email'];

  // We validate the email
  if(user_load(array('mail' => $email))) {
    // User exists, use the data available.
  }
  else {
    // User doesn't exist, create a new user

    // Create a new password
    $pass = user_password(5);

    // THIS IS BAD! but for some reason, Drupal is not sending the $account->password, so I temporary save the new password in a variable and then I delete the variable after the mail was sent.
    variable_set('temp_pass_'.$email, $pass);
    // build the new user object
    $newuser = array(
      'mail' => $email,
      'name' => $email,
      'pass' => $pass,
      'access' => 0,
      'status' => 1,
    );
    // save the new user
    $account = user_save(NULL, $newuser, NULL);
    
    // notify the user of the new account
    swcon_notify($account);
  }
  
    // We can use this function for several webforms, if every webform is different, we have to apply conditionals.
    if($webform == 'contact') {      
      // Map the first 80 characters of the message to the title variable.
      $title = check_plain(truncate_utf8($values['message'], 80, TRUE, TRUE));;   
      // Map the Message to the Body variable
      $body = $values['message'];

      // Create a new object
      $node = new stdClass();
      // Our node will be of type 'support_ticket'
      $node->type = 'support_ticket';
      // Search for the user by email
      $user = user_load(array('mail' => $email));
      // If the author of the node is the same one as the user, then support will notify automatically about new comments and changes.
      $node->uid = $user->uid;
      // Enable comments
      $node->comment = 2;
      // Map the Title and Body
      $node->title = $title;
      $node->body = $body; 
      // Map the cck field
      $node->field_email[0]['value'] = $email;
      // Support fields 
      // 1 means new by default
      $node->state = 1;
      // 2 means normal by default
      $node->priority = 2;
      // you can find out the client id with a query to the DB
      $node->client = 1;
    
      // Save the node
      node_save($node);
    }
  // Must return to our default database
  db_set_active('default');
}

function swcon_notify($account, $language = NULL) {
  // Get the language
  $language = $language ? $language : user_preferred_language($account);
  // Call swcon_mail with 'notify' as the $key
  $mail = drupal_mail('swcon', 'notify', $account->mail, $language, $account);
  
  return empty($mail) ? NULL : $mail['result'];
}

function swcon_mail($key, &$message, $account) {
  $language = $message['language'];
  // We get the password from the variable
  $pass = variable_get('temp_pass_'.$account->mail, '');
  switch($key) {
    case 'notify':
      // The subject, change this.
      $message['subject'] = t('A new account has been created for you in our Site', $language->language);
      // The mail body, change this.
      $message['body'][] = t("Hi!\n\n We've detected you submitted a new ticket, we have created a new account for you, you can login with it and follow the status of your ticket. Use the following to login: \n\nUsername: !username\nPassword: !password", array('!username' => $account->name, '!password' => $pass), $language->language);
      // delete the variable
      variable_del('temp_pass_'.$account->mail);
      break;
  }
}
?>

Edit your webform

Now that you have your own module, go back to the webform and edit it. Open the Webform advanced settings fieldset and you'll see two textarea fields, add the following to the 'Additional Processing' field.

<?php
// Tell swcon_new_node what $webform tu use. In this case we use contact.
swcon_new_node($form_state, 'contact'); 
?>

Test

Test the form and go the Backend where you'll see the new ticket node.

Comments

Peter Bowey’s picture

Why is this marked as "Page status: Deprecated"?

And then we read:

"The contents of this handbook page are not recommended by the Webform module maintainers. Any use of custom PHP code through the Webform PHP module is discouraged."

.

I assume that is meant to be a warning, but explain for what please!
This handbook page covers a area where little progress has been made to harness a effective "ticket-support system".

lelizondo’s picture

Because the maintainers of Webform, have always considered that using PHP to validate or do some extra form processing is dangerous. I'm not familiar with the details.

Luis

Peter Bowey’s picture

Thanks Luis,

Well that leaves 'Javascript' as to validation of forms?? So what does the 'webform' module use => PHP, and there is one file called select-admin.js (see below).

Typically, client-side validation (using javascript) is used to ensure that all fields are filled in, email addresses are valid, etc. This provides instant feedback and eases the burden on servers or the user's internet connection.

We validate server-side (using PHP) for security. We can control everything on the server and nothing on the client machine. It's here that we ensure that all entered data is non-malicious and correct. Maybe that is the real 'Deprecated' status point raised here => secure PHP Form input checking. I thought that was normal PHP practice = filtering input on all forms?

If we are only going to go with one type of validation, server-side validation is more secure. We should never rely on client-side code for any kind of security.

I have spent 'many days' seeking a ready made and effective Drupal Ticket Support system. The 'idea' presented here on this Drupal Node is one of the few that made good sense!

Peter Bowey

lelizondo’s picture

You don't even need Support, you could do this just with CCK and Services, if you want to get more sophisticated. I even created a module to integrate Services and Subscriptions. But, in the end, some extra processing with PHP must be involved, unless we could find another way to do it. For me is very simple, PHP might be risky, but without PHP processing and validating, Webform is just a fancy clone of the Contact Form module.

PHP will open way to many possibilities, one of them is this Support Ticket case. I'm willing to take the risk of doing it with PHP, because otherwise, it would require way to many code to write just to achieve the same functionality.

Luis

mahyag’s picture

hi
when I fill the fields of the form, I recieve the following error:

Fatal error: Call to undefined function swcon_new_node() in C:\wamp\www\sites\all\modules\webform_php\webform_php.module(81) : eval()'d code on line 3

I think that I placed swcon.module in a wrong path.
so help me that where should I place swcon.module?

thanks

lelizondo’s picture

you should place the module where you place all your modules.

Luis