I was helping a partner the other day with an issue they were having in a module they developed for Sugar that is safe to load on our On Demand environment. Here’s the code he was using that was causing issues:
1 2 3 |
$fh = tmpfile(); fwrite($fh, $update_json); fseek($fh, 0); |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$chlead = curl_init(); curl_setopt($chlead, CURLOPT_URL, $closeOppURL); curl_setopt($chlead, CURLOPT_USERAGENT, 'SugarConnector/1.4'); curl_setopt($chlead, CURLOPT_VERBOSE, 1); curl_setopt($chlead, CURLOPT_PUT, true); curl_setopt($chlead, CURLOPT_INFILE, $fh); curl_setopt($chlead, CURLOPT_INFILESIZE, strlen($update_json)); curl_setopt($chlead, CURLOPT_RETURNTRANSFER, true); curl_setopt($chlead, CURLOPT_SSL_VERIFYPEER, 0); $chleadresult = curl_exec($chlead); $chleadapierr = curl_errno($chlead); $chleaderrmsg = curl_error($chlead); curl_close($chlead); |
The problem here is that the tmpfile(), fwrite(), and fseek() functions are not allowed on the OD environment, as we don’t block raw file operations for potential security issues. However, the suggested way of doing PUT requests with cURL implies that you are PUTing a file, and it assumes you are reading a file from the filesystem. In this case however, the PUT payload is being generated as JSON, but to work with cURL it’s wanting you to inefficiently write it to a temporary file in order to send it.
Then I came across this post from esteemed PHP Community member Lorna Jane Mitchell, which showed a techique to get around this. So with help from that post, here’s how we refactored the code to eliminate the extranous file write.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$chlead = curl_init(); curl_setopt($chlead, CURLOPT_URL, $closeOppURL); curl_setopt($chlead, CURLOPT_USERAGENT, 'SugarConnector/1.4'); curl_setopt($chlead, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($update_json))); curl_setopt($chlead, CURLOPT_VERBOSE, 1); curl_setopt($chlead, CURLOPT_RETURNTRANSFER, true); <strong>curl_setopt($chlead, CURLOPT_CUSTOMREQUEST, "PUT"); </strong> <strong>curl_setopt($chlead, CURLOPT_POSTFIELDS,$update_json);</strong> curl_setopt($chlead, CURLOPT_SSL_VERIFYPEER, 0); $chleadresult = curl_exec($chlead); $chleadapierr = curl_errno($chlead); $chleaderrmsg = curl_error($chlead); curl_close($chlead); |
The key here is to not use the built-in PUT handling, but instead use the CURLOPT_CUSTOMREQUESTattribute to specify the request type we want manually, and then the CURLOPT_POSTFIELDS to pass the payload. And this works perfectly for Sugar On Demand, and eliminates the overhead of a filesystem write and read.