Discover how to seamlessly integrate Fluent Forms with osTicket without using a resource intensive plugin.
By using osTicket’s (OST) standard api template, I was able to create a connector that integrates with a Fluent Forms (FF) that my users can use to create support tickets. Before going further, I should mention that you need Fluent Forms Pro in order to use the Image Upload or File Upload fields in your form.
osTicket API
One of the first things you should do is generate an API key. Log into your OST backend, make sure you are in the Admin Panel, click the Manage tab, and then click on API.
Once you open the page, you will need to enter the IP address of the server that is sending info to your API even if its the same server where OST is installed. Also, make sure to check the box next to Can Create Tickets (XML/JSON/EMAIL)
.
Now that you’ve created your API key, the two config options will need to be updated in the code before adding it to your theme’s functions.php
file.
- url: Add the url of your OST installation appended with
/api/tickets.json
. - key: This is where you add the API that you generated in OST.
One thing I should mention is $formData['osticket_form']
. This is a hidden form field that I created as a another check with the value being 1
.
Fluent Forms Action Hook
The action hook that I used from the plugin is fluentform/submission_inserted
. It was best to use this hook because of the data you can capture after submission including the url of the uploaded files.
Fluent Forms Data
When creating the form, I changed the name of the field attributes. This isn’t necessary, but I wanted to make them unique to the form.
$formData['osticket_form']
: hidden field with a default value$formData['osticket_fullname']
: full name of the submitter$formData['osticket_email']
: email of the submitter$formData['osticket_subject']
: also known as the issue summary$formData['osticket_message']
: the issue being reported$formData['osticket_topic']
: topic of the ticket which also sets the priority$formData['osticket_attach']
: file attachments
Multiple Files
It was easy to come up with code that support the upload of one file, but it took some time to figure out how to upload multiple files as well as the proper format. This little piece of magic was the key:
$raw_files_array = $formData['osticket_attach'];
$desired_output = [];
array_walk(
$raw_files_array,
function(&$val, $key) use (&$desired_output)
{
$parsed_url = parse_url( $val );
# Concat the path with the relative url to the file.
$file_path = ABSPATH . ltrim( $parsed_url['path'], '/');
# Get the mime type of the uploaded file.
$mime_type = mime_content_type($file_path);
# Get the basename of the file.
$base_name = wp_basename($file_path);
$desired_output[$base_name] = "data:$mime_type;base64," . base64_encode(file_get_contents($file_path));
}
);
# Loop through the attachments and push them to the attachments array.
# Each attachment must be in its own array.
foreach($desired_output as $filename => $encoded_file) {
$rawData['attachments'][] = [$filename => $encoded_file];
}
“What does it do,” you ask? First, the attached files ($formData['osticket_attach']
) are assigned to a variable. The files array is an associative array with numeric indexes [0 => $filename]
. We need to change that and make it an associative array with named indexes ['newname' => $filename]
. That’s where the array_walk
function comes in. In short, we parse the url so that we can extract the relative path and prepend it with the absolute path of our WordPress install, retrieve the mime type of the file, as well as the filename which we use as as the new index for the file that we can use in our new associative array.
Once that is done, we do an iteration creating a new array with a set of associative arrays and array push them to $rawData['attachments']
. The rest of the code does some checking and if all is ok, the data is handle by curl
and the ticket gets created. The last line of code $ticket_id = (string) sanitize_text_field($result);
is for checking that the ticket was successfully created. It is not needed and can be removed or commented out.
Well that’s it for explaining the different parts of the code. If you plan to use this, don’t forget a few housekeeping things to do:
- Change the
$config['url']
to your installation of osTicket - Add your api key to
$config['key']
- When creating your form fields, either change the field attributes to match the ones in the code or if you use your own naming convention, change the code to reflect the attributes in your form.
Hopefully you are using a child theme that has a functions.php
file where you can add code. If you are using a child theme and the file doesn’t exist, create it in the child theme folder. Then add the following code to that file, make any needed changes, and then save it. Make sure to test it out to make sure it is working.
If you have any issues or you are not using a child theme, you can ask for help in the forum for an alternative solution.
<?php
/**
* Submits inserted form data to osTicket's api for ticket creation.
*/
add_action('fluentform/submission_inserted', 'osticket_capture_submitted_fluentform_data', 10, 3);
function osticket_capture_submitted_fluentform_data($entryId, $formData, $form)
{
# osticket_form is a hidden form field with the value of 1
if($form->id != 2 && $formData['osticket_form'] != 1) {
return;
}
$config = [
'url' => 'https://yoursupportdeskurl.com/api/tickets.json',
'key' => 'your generated api'
];
# Fill in the data for the new ticket, this will likely come from $_POST.
$rawData = [
'name' => $formData['osticket_fullname'],
'email' => $formData['osticket_email'],
'subject' => $formData['osticket_subject'],
'message' => $formData['osticket_message'],
'topicId' => $formData['osticket_topic'],
'ip' => $_SERVER['REMOTE_ADDR'],
'attachments' => [],
];
$raw_files_array = $formData['osticket_attach'];
$desired_output = [];
array_walk(
$raw_files_array,
function(&$val, $key) use (&$desired_output)
{
$parsed_url = parse_url( $val );
# Concat the path with the relative url to the file.
$file_path = ABSPATH . ltrim( $parsed_url['path'], '/');
# Get the mime type of the uploaded file.
$mime_type = mime_content_type($file_path);
# Get the basename of the file.
$base_name = wp_basename($file_path);
$desired_output[$base_name] = "data:$mime_type;base64," . base64_encode(file_get_contents($file_path));
}
);
# Loop through the attachments and push them to the attachments array.
# Each attachment must be in its own array.
foreach($desired_output as $filename => $encoded_file) {
$rawData['attachments'][] = [$filename => $encoded_file];
}
# pre-checks
if(!function_exists('curl_version')) {
return;
}
if(!function_exists('json_encode')) {
return;
}
# set timeout
set_time_limit(30);
# curl post
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $config['url']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($rawData));
curl_setopt($ch, CURLOPT_USERAGENT, 'osTicket API Client v1.8');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Expect:', 'X-API-Key: ' . $config['key'] ]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result =curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code != 201) {
wp_die('Unable to create ticket: ' . $result);
}
# not used but here for checking.
$ticket_id = (string) sanitize_text_field($result);
}