Create a Ticketing System with Support and Webform
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.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion