Use Contact Form 7 and Pardot together

Written in

by

An ask for a contact form that sends data to pardot turned out to be a fun little plug-in.

Code first;

<?php
/**
* custom CF7 to Pardot Form Handler
*
* @package custom-cf7-pardot-form-handler
* @copyright 2023 Derak Kilgo
* @license GPL v2 or later
*
* Plugin Name: custom CF7 to Pardot Form Handler
* Description: Relay form data from a Contact Form 7 form to a Pardot Custom Form Handler endpoint.
* Version: 0.0.1
* Author: Derak Kilgo
* Requires PHP: 5.6
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
if (!defined('ABSPATH')) {
exit;
}
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'custom_cf7pfh_add_action_links' );
function custom_cf7pfh_add_action_links ( $actions ) {
$mylinks = array(
'<a href="https://gist.github.com/derak-kilgo/d561ca19764058a9d40a9dd9b11ed817">Docs</a>',
);
$actions = array_merge( $actions, $mylinks );
return $actions;
}
add_action('wpcf7_submit','custom_cf7pfh_send',10,2);
/**
* Action to hook into when contact 7 forms are submitted. Form must include a "custom_pardot_form_action_url" arg.
* Example $result - {"contact_form_id":9999,"status":"mail_sent","message":"Thank you for your message. It has been sent.","posted_data_hash":"a685e3d41dxxxxxxxxxxxxxxxxx"}
*
* @param WPCF7_ContactForm $contact_form
* @param array $result The result of submitting the form along with status and result messaging.
* @return void
*/
function custom_cf7pfh_send($contact_form,$result){
//based on flamingo.php by Takayuki Miyoshi
$submission = WPCF7_Submission::get_instance();
if ( ! $submission or ! $posted_data = $submission->get_posted_data() ) {
//do nothing. No submission obj means we can't get posted data.
return;
}
$tmpSettings = $contact_form->additional_setting('custom_pardot_form_action_url',1);
if(empty($tmpSettings[0])){
//do nothing. We don't have an action to take.
return;
}
$pardot_action_url = (string) $tmpSettings[0];
unset($tmpSettings);
//Send data to the form endpoint.
//@see https://help.salesforce.com/s/articleView?id=000383081&type=1
// $wp_remote_post_result = wp_remote_post($pardot_action_url,array(
// 'method' => 'POST',
// 'headers' => array('Content-Type' => 'application/x-www-form-urlencoded'),
// 'body' => $posted_data
// ));
$wp_remote_post_result = custom_post_to_url($pardot_action_url,$posted_data);
if(defined('WP_DEBUG') && WP_DEBUG === true) {
$data = [
'timestamp' => microtime(true),
'posted_data' => $posted_data,
'pardot_action_url' => $pardot_action_url,
'remote_post_result' => $wp_remote_post_result
];
$json = print_r($data, true);
file_put_contents(__DIR__ . '/output.log', $json . "\n\n\n", FILE_APPEND);
/* end debugging */
}
}
/**
* Send POST form data to pardot.
* WordPress wp_remote_post() doesn't seem to work with pardot.
*
* @param $target_url
* @param $post_data
* @return array
*/
function custom_post_to_url ($target_url,$post_data){
//This works around some gotchas with pardot form handlers.
//pardot does not support multi-part form.
//@see https://help.salesforce.com/s/articleView?id=000383081&type=1
//@see http://php.net/manual/en/function.curl-setopt.php CURLOPT_POSTFIELDS
//Portions of this code generated by insomnia/2023.5.8
$curl = curl_init();
$post_string = http_build_query($post_data);
curl_setopt_array($curl, [
CURLOPT_URL => $target_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLINFO_HEADER_OUT=>true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $post_string,
CURLOPT_HTTPHEADER => [
"Content-Type: application/x-www-form-urlencoded",
"User-Agent: customPardotFormRelay/0.0.1"
],
]);
//Capture response headers safely. See RFC822 RFC2616 RFC7230
//@see https://stackoverflow.com/a/41135574
$response_headers = [];
// this function is called by curl for each header received
curl_setopt($curl, CURLOPT_HEADERFUNCTION,
function($curl, $header) use (&$response_headers)
{
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) < 2) // ignore invalid headers
return $len;
$response_headers[strtolower(trim($header[0]))][] = trim($header[1]);
return $len;
}
);
//Make request
$response = curl_exec($curl);
$err = curl_error($curl);
//Collect output
$out = array();
$out['response_body'] = curl_exec($curl);
//NOTE: this may need to be updated in the future to use CURLINFO_RESPONSE_CODE instead.
$out['response_code'] = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$out['response_headers'] = $response_headers;
$out['error'] = curl_error($curl);
$out['request_headers'] = curl_getinfo($curl,CURLINFO_HEADER_OUT);
curl_close($curl);
return $out;
}

Plug-in hooks into the ‘wpcf7_submit’ action which occurs after a form is submitted successfully and makes a secondary request to a pardot form handler endpoint.

Config is done in contact form 7 using “additional settings”.

Usage:

  1. Install this plugin and contact form 7.
  2. Make a new contact form.
  3. Make sure the input ‘name’ attributes match your pardot field handles.
  4. On the forms’ Additional Settings page, add the handler url from pardot.
    Example: custom_pardot_form_action_url: "https://example.com/l/999/99-99-99/abcd"
  5. Save your form.

Note: If WP_DEBUG is enabled; the plug-in will attempt to write to plugins/output.log
This is useful when trying to debug issues with the form handler.

Note: “custom_pardot_form_action_url” must be present for data to be sent to pardot.
Plug-in ignores any forms which don’t have this.

So what was fun about this?

I was aware of another project by the same author called “Flamingo”. It directs the form data to a database. I enjoyed picking that plug-in apart. There were hints there that are not in the ContactForm7 docs. I guess I was surprised there wasn’t something that already did this and amused that it wasn’t that hard to piece together.

Enjoy.

Verified by MonsterInsights