private function doCall($url, array $parameters = null, $method = 'GET', $secure = false, $expectJSON = true, $returnHeaders = false)
{
// allowed methods
$allowedMethods = array('GET', 'POST', 'DELETE', 'PUT');
// add HTTP authentication. The call to retrieve the apikey works slightly different
switch ($url) {
case 'apikey':
$options[CURLOPT_USERPWD] = $this->username . ':' . $this->password;
$options[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC;
break;
default:
$options[CURLOPT_USERPWD] = $this->apiKey . ':' . md5(sha1(time()));
$options[CURLOPT_HTTPAUTH] = CURLAUTH_ANY;
}
// redefine
$url = (string) $url . '.' . $this->responseFormat;
$parameters = (array) $parameters;
$method = (string) $method;
$expectJSON = (bool) $expectJSON;
// validate method
if (!in_array($method, $allowedMethods)) {
throw new CampaignMonitorException('Unknown method (' . $method . '). Allowed methods are: ' . implode(', ', $allowedMethods));
}
// set the expect header to avoid connection fails
$headers = array();
$headers[] = 'Expect:';
// based on the method, we should handle the parameters in a different way
switch ($method) {
case 'DELETE':
$options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
break;
case 'GET':
// add the parameters into the querystring
if (!empty($parameters)) {
$url .= '?' . http_build_query($parameters, null, '&', PHP_QUERY_RFC3986);
}
break;
case 'POST':
// set postfields, repair forward slash bug
$options[CURLOPT_POSTFIELDS] = str_replace('\\/', '/', json_encode($parameters));
// enable post
$options[CURLOPT_POST] = true;
// set content-type to JSON
$headers[] = 'Content-Type: application/json';
break;
case 'PUT':
// set postfields, repair forward slash bug
$options[CURLOPT_POSTFIELDS] = str_replace('\\/', '/', json_encode($parameters));
// enable put
$options[CURLOPT_CUSTOMREQUEST] = 'PUT';
// set content-type to JSON
$headers[] = 'Content-Type: application/json';
break;
}
// set options
$options[CURLOPT_URL] = self::API_URL . '/' . $url;
$options[CURLOPT_PORT] = self::API_PORT;
$options[CURLOPT_USERAGENT] = $this->getUserAgent();
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
$options[CURLOPT_FOLLOWLOCATION] = true;
}
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
$options[CURLOPT_SSL_VERIFYPEER] = false;
$options[CURLOPT_SSL_VERIFYHOST] = false;
$options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
$options[CURLOPT_HTTPHEADER] = $headers;
// init
if ($this->curl == null) {
$this->curl = curl_init();
}
// set options
curl_setopt_array($this->curl, $options);
// execute
$response = curl_exec($this->curl);
$headers = curl_getinfo($this->curl);
// fetch errors
$errorNumber = curl_errno($this->curl);
$errorMessage = curl_error($this->curl);
// return the headers
if ($returnHeaders) {
return $headers;
}
// we don't expext JSON, return the response
if (!$expectJSON) {
return $response;
}
// replace ids with their string values, added because some PHP-versions can't handle these large values
$response = preg_replace('/id":(\\d+)/', 'id":"\\1"', $response);
/*
This is a tricky one. Apparently PHP 5.2 does not decode strings, but returns NULL instead. 5.2.1x has no issues with this.
So we can assume that, if the response is not empty, and it is not a json array or object, it is a string, and we return it
without the double quotes, and without json_decode().
I am aware this is somewhat dirty, but if it lets you use 5.2 without issues than I can live with it.
*/
$json = $response != '' && strpos($response, '{') === false && strpos($response, '[') === false ? str_replace('"', '', $response) : json_decode($response, true);
// 200 OK means everything went well, 201 OK means a resource just got created with a POST request.
if ($headers['http_code'] !== 200 && $headers['http_code'] !== 201 && !isset($json['ResultData'])) {
// should we provide debug information
if (self::DEBUG) {
// make it output proper
echo '<pre>';
// dump the header-information
var_dump($headers);
// dump the raw response
var_dump($response);
// end proper format
echo '</pre>';
}
// throw exception
throw new CampaignMonitorException($headers['http_code'] . ': ' . $json['Message']);
}
// if we did a delete request, return true at this point
if ($method === 'DELETE' && $json === null) {
return true;
}
// return
return $json;
}