2

I'm working on a simple plugin to facilitate front-end, anonymous lead generation forms submitted to Salesforce via cURL to it's Web-to-Lead servlet. The logic and data transfer are working (debug showing positive receipt of the query from the servlet), but no matter what the :success function on the $.ajax call isn't triggered.

I'm getting a 200 OK back from the cURL, so my assumption is that the :error function is being triggered because the result isn't properly formatted JSON. I'm calling the returnJson function from the baseController, however all I can see in the response object is "responseText" with the raw HTML of the servlet response.

Controller PHP

protected $allowAnonymous = array('actionPostLead');

public function actionPostLead()
{
    $this->requireAjaxRequest();

    // Initialize the $kv array and query var for later use
    $kv = array();
    $query_string = '';

    //If there are POST variables
    if ($_POST) {

        // For each POST variable as $name_of_input_field => $value_of_input_field
        foreach ($_POST as $key => $value) {

            // Set array element for each POST variable (ie. first_name=Arsham)
            $kv[] = stripslashes($key).'='.stripslashes($value);
        }

        // Create a query string with join function separted by &
        $query_string = join('&', $kv);
    }

    // Check to see if cURL is installed ...
    if (!function_exists('curl_init')) {
        die('Sorry cURL is not installed!');
    }

    // The original form action URL from Step 2 :)
    $url = 'https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';

    // Open cURL connection
    $ch = curl_init();

    // Set the url, number of POST vars, POST data
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, count($kv));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);

    // Execute SalesForce web to lead PHP cURL
    $result = curl_exec($ch);

    // close cURL connection
    curl_close($ch);

    if ($result) {
        $this->returnJson(array('success' => true));
    } else {
        $this->returnErrorJson($e->getMessage());
    }
}

Javascript

$.ajax({
    type: 'POST',
    url: '/',
    data: data,
    dataType: 'json',
    success: function(response) {

        formBlock.removeClass('submitting');
        var successMessage = $('.formBlock.on').data('success-message');
        showFormSuccessBanner(successMessage);
        hideForm(id);
    },
    error: function(err) {
        console.log("Error");
        console.log(err);

        formBlock.removeClass('submitting');
    }
});

I think I'm close, but I've been digging for several hours and can't figure out what I'm doing wrong with the response.

5
  • Do you habe all your warnings activated on your server? Maybe the error is caused because you have an undeclared variable $e in your code, so the server returns that -> no json? Oct 21, 2017 at 8:46
  • A good catch, but not the cause, unfortunately. I removed the undefined variable and replaced it with a string ($this->returnErrorJson("Curl failed.");), and still no luck on the response. Oct 21, 2017 at 16:04
  • I was looking at your code the entire day multiple times but I still can't understand where the error is... maybe one last solution out of despair: what happens if you remove dataType: 'json' from your ajax I never used that in my craft projects, maybe this is key(?) If not, could you please make a screenshot from your network tab with the exact response from the server? Oct 21, 2017 at 16:56
  • #1 : imgur.com/cRKfAtC #2: imgur.com/P4p1duW -- So this has helped me track it down. The response has two lines, first the raw output from the curl as HTML, then the JSON. Undoubtedly this is the issue—jQuery is failing because of the raw HTML response. I've tried CURLOPT_RETURNTRANSFER, TRUE, but that's not working (even though it should).... Oct 21, 2017 at 17:25
  • AH! curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE ); WAS working, but I had left a var_dump in the code that was, now that I was debugging with xdebug, ALSO dumping to the response. When I remove that, RETURNTRANSFER did it's job, squelching the direct response and letting the JSON return properly. Oct 21, 2017 at 17:29

1 Answer 1

2

The issue was that curl was, by default, returning the result of the http request to the WebToLead servlet directly, rather than only storing it as $result. This raw HTML response was super-ceding the returnJson() response, resulting in an error in jQuery's ajax function.

To force PHP curl to echo the result rather than return it, you need to set a curl option for CURLOPT_RETURNTRANSFER to true. Revised as such:

// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE  );
curl_setopt($ch, CURLOPT_POST, count($kv));
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);

This returns just the JSON response from the function in Craft's baseController, and therefore a successful response to jQuery.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.