Search code examples
phpxmlcurlgravityforms

Gravity Forms sending entry data to third-party after submitting in xml


I am fairly new to php/curl and gravity form hooks. I have 5 forms that I'm trying to setup to use the gravity forms gform_after_submission hook so it send xml data to a third party (sbs web service running sql server).

This is what i have already.

add_action('gform_after_submission_73', 'post_to_third_party', 10, 2);
function post_to_third_party($entry, $form) {

$post_url = 'http://mywebsite.co.uk/customers?clientid=1599999&secret=123';
$body = array(
    'brand' => $entry['20'],
    'product' => $entry['22'],
    'form_id' => $entry['21'],
    'title' => $entry['24'],
    'fname' => $entry['23'],
    'lname' => $entry['17'],
    'postcode' => $entry['14'],
    'address1' => $entry['2.1'],
    'address2' => $entry['2.2'],
    'town' => $entry['2.3'],
    'county' => $entry['2.4']   
    );
$xml = '
   <?xml version="1.0" encoding="WINDOWS-1252"?>
<webform>
        <brand>$brand</brand>
    <product>$product</product>
    <form_id>$form_id</form_id>
    <title>$title</title>
    <fname>$fname</fname>
    <lname>$lname</lname>
    <postcode>$postcode</postcode>
    <address1>$address1</address1>
    <address2>$address2</address2>
    <town>$town</town>
    <county>$county</county>
    </webform>';
var_dump($xml);

$ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $post_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $output = curl_exec($ch);
    echo $output;
    curl_close($ch);
  }

Solution

  • Your code has several problems, which a decent IDE would show you immediately.

    1. function post_to_third_party($entry, $form)

      $form is never used, so just omit it.

    2. $body = array(...);

      You are never using $body, but trying to access the entries 'directly' later.

    3. $xml = '...';

      Single quoted strings are not interpolated (i.e., variables are not replaced), as var_dump($xml); already has shown you. Also, you don't escape the values, which may contain characters that are not allowed in XML.

    4. $ch = curl_init($url);

      $url does not exist. The value that you want to use, is in $post_url.

    5. You are using insecure settings for cURL, making your code vulnerable for a MITM attack (SSL server spoofing). See this documentation for more information.

    6. You don't have any form for error checking.

    After fixing the issues, your code looks like this and should now work:

    add_action('gform_after_submission_73', 'post_to_third_party', 10, 2);
    
    function post_to_third_party($entry)
    {
        $url      = 'http://mywebsite.co.uk/customers?clientid=1599999&secret=123';
        $encoding = 'WINDOWS-1252';
        $brand    = htmlspecialchars($entry['20'], ENT_XML1, $encoding);
        $product  = htmlspecialchars($entry['22'], ENT_XML1, $encoding);
        $form_id  = htmlspecialchars($entry['21'], ENT_XML1, $encoding);
        $title    = htmlspecialchars($entry['24'], ENT_XML1, $encoding);
        $fname    = htmlspecialchars($entry['23'], ENT_XML1, $encoding);
        $lname    = htmlspecialchars($entry['17'], ENT_XML1, $encoding);
        $postcode = htmlspecialchars($entry['14'], ENT_XML1, $encoding);
        $address1 = htmlspecialchars($entry['2.1'], ENT_XML1, $encoding);
        $address2 = htmlspecialchars($entry['2.2'], ENT_XML1, $encoding);
        $town     = htmlspecialchars($entry['2.3'], ENT_XML1, $encoding);
        $county   = htmlspecialchars($entry['2.4'], ENT_XML1, $encoding);
    
        $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>
        <webform>
            <brand>$brand</brand>
            <product>$product</product>
            <form_id>$form_id</form_id>
            <title>$title</title>
            <fname>$fname</fname>
            <lname>$lname</lname>
            <postcode>$postcode</postcode>
            <address1>$address1</address1>
            <address2>$address2</address2>
            <town>$town</town>
            <county>$county</county>
        </webform>";
    
        $ch = curl_init($url);
    
        if ($ch === false) {
            throw new RuntimeException("Unable to initialise a session");
        }
    
        $result = curl_setopt_array($ch, [
            CURLOPT_POST => 1,
            CURLOPT_HTTPHEADER => ['Content-Type: text/xml'],
            CURLOPT_POSTFIELDS => $xml,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_SSL_VERIFYPEER => 1,
        ]);
    
        if ($result === false) {
            throw new RuntimeException("Unable to set session options");
        }
    
        $output = curl_exec($ch);
    
        if ($output === false) {
            throw new RuntimeException("Request failed: " . curl_error($ch));
        }
    
        curl_close($ch);
    
        echo $output;
    }