<?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; }