<p>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.</p>

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

<pre><code>// 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);
</code></pre>

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

CC BY-SA 3.0
2017-10-21T17:32:49.527Z
2017-10-21T17:32:49.527Z
Aiden Bordner
<p>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.</p>

<p>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.</p>

<p><strong>Controller PHP</strong></p>

<pre><code>protected $allowAnonymous = array('actionPostLead');

public function actionPostLead()
{
    $this-&gt;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 =&amp;amp;gt; $value_of_input_field
        foreach ($_POST as $key =&gt; $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 &amp;amp;amp;
        $query_string = join('&amp;', $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-&gt;returnJson(array('success' =&gt; true));
    } else {
        $this-&gt;returnErrorJson($e-&gt;getMessage());
    }
}
</code></pre>

<p><strong>Javascript</strong></p>

<pre><code>$.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');
    }
});
</code></pre>

<p>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.</p>

CC BY-SA 3.0
2017-10-21T08:46:20.547Z
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?
Robin Schambach
CC BY-SA 3.0
2017-10-21T16:04:06.720Z
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.
Aiden Bordner
CC BY-SA 3.0
2017-10-21T16:56:50.343Z
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?
Robin Schambach
CC BY-SA 3.0
2017-10-21T17:25:06.247Z
#1 : https://imgur.com/cRKfAtC #2: https://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)....
Aiden Bordner
CC BY-SA 3.0
2017-10-21T17:29:00.533Z
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.
Aiden Bordner
<plugin-development><ajax><json><jquery>
JQuery $.ajax ":success" form logic with Plugin Controller?
# JQuery $.ajax ":success" form logic with Plugin Controller?

(Asked by: username_0 on 2017-10-20)

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 =&gt; $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 &amp;
        $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.

**Tags:** plugin-development, ajax, json, jquery

> **Comments:**
> **username_1**: 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?  
> **username_0**: 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.  
> **username_1**: 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?  
> **username_0**: #1 : https://imgur.com/cRKfAtC #2: https://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)....  
> **username_0**: 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.  

---

## 1 answers

### Answer by username_0 on 2017-10-21. Score: 2 | Accepted answer

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.


---

