function CMBase::makeCall in Campaign Monitor 6.2
Same name and namespace in other branches
- 5.2 lib/CMBase.php \CMBase::makeCall()
- 6.3 lib/CMBase.php \CMBase::makeCall()
* The direct way to make an API call. This allows developers to include new API * methods that might not yet have a wrapper method as part of the package. * *
Parameters
string $action The API call.: * @param array $options An associative array of values to send as part of the request. * @return array The parsed XML of the request.
29 calls to CMBase::makeCall()
- CampaignMonitor::campaignCreate in lib/
CMBase.php - *
- CampaignMonitor::campaignGeneric in lib/
CMBase.php - * A generic wrapper to feed Campaign.* calls. * *
- CampaignMonitor::campaignSend in lib/
CMBase.php - *
- CampaignMonitor::clientCreate in lib/
CMBase.php - *
- CampaignMonitor::clientGeneric in lib/
CMBase.php
File
- lib/
CMBase.php, line 119
Class
Code
function makeCall($action = '', $options = array()) {
// NEW [2008-06-24]: switch to soap automatically for these calls
$old_method = $this->method;
if ($action == 'Subscriber.AddWithCustomFields' || $action == 'Subscriber.AddAndResubscribeWithCustomFields' || $action == 'Campaign.Create') {
$this->method = 'soap';
}
if (!$action) {
return null;
}
$url = $this->url;
// DONE: like facebook's client, allow for get/post through the file wrappers
// if curl isn't available. (or maybe have curl-emulating functions defined
// at the bottom of this script.)
//$ch = curl_init();
if (!isset($options['header'])) {
$options['header'] = array();
}
$options['header'][] = 'User-Agent: CMBase URL Handler 1.5';
$postdata = '';
$method = 'GET';
if ($this->method == 'soap') {
$options['header'][] = 'Content-Type: text/xml; charset=utf-8';
$options['header'][] = 'SOAPAction: "' . $this->soapAction . $action . '"';
$postdata = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$postdata .= "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
$postdata .= " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"";
$postdata .= " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n";
$postdata .= "<soap:Body>\n";
$postdata .= "\t<{$action} xmlns=\"{$this->soapAction}\">\n";
$postdata .= "\t\t<ApiKey>{$this->api}</ApiKey>\n";
if (isset($options['params'])) {
$postdata .= $this
->array2xml($options['params'], "\t\t");
}
$postdata .= "\t</{$action}>\n";
$postdata .= "</soap:Body>\n";
$postdata .= "</soap:Envelope>";
$method = 'POST';
//curl_setopt( $ch, CURLOPT_POST, 1 );
//curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata );
}
else {
$postdata = "ApiKey={$this->api}";
$url .= "/{$action}";
// NOTE: since this is GET, the assumption is that params is a set of simple key-value pairs.
if (isset($options['params'])) {
foreach ($options['params'] as $k => $v) {
$postdata .= '&' . $k . '=' . rawurlencode(utf8_encode($v));
}
}
if ($this->method == 'get') {
$url .= '?' . $postdata;
$postdata = '';
}
else {
$options['header'][] = 'Content-Type: application/x-www-form-urlencoded';
$method = 'POST';
//curl_setopt( $ch, CURLOPT_POST, 1 );
//curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata );
}
}
$res = '';
// WARNING: using fopen() does not recognize stream contexts in PHP 4.x, so
// my guess is using fopen() in PHP 4.x implies that POST is not supported
// (otherwise, how do you tell fopen() to use POST?). tried fsockopen(), but
// response time was terrible. if someone has more experience with working
// directly with streams, please troubleshoot that.
// NOTE: fsockopen() needs a small timeout to force the socket to close.
// it's defined in SOCKET_TIMEOUT.
// preferred method is curl, only if it exists and $this->curl is true.
if ($this->curl && $this->curlExists) {
$ch = curl_init();
if ($this->method != 'get') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $options['header']);
curl_setopt($ch, CURLOPT_HEADER, $this->show_response_headers);
// except for the response, all other information will be stored when debugging is on.
$res = curl_exec($ch);
if ($this->debug_level) {
$this->debug_url = $url;
$this->debug_request = $postdata;
$this->debug_info = curl_getinfo($ch);
$this->debug_info['headers_sent'] = $options['header'];
}
$this->debug_response = $res;
curl_close($ch);
}
else {
// 'header' is actually the entire HTTP payload. as such, you need
// Content-Length header, otherwise you'll get errors returned/emitted.
$postLen = strlen($postdata);
$ctx = array(
'method' => $method,
'header' => implode("\n", $options['header']) . "\nContent-Length: " . $postLen . "\n\n" . $postdata,
);
if ($this->debug_level) {
$this->debug_url = $url;
$this->debug_request = $postdata;
$this->debug_info['overview'] = 'Used stream_context_create()/fopen() to make request. Content length=' . $postLen;
$this->debug_info['headers_sent'] = $options['header'];
//$this->debug_info['complete_content'] = $ctx;
}
$pv = PHPVER;
// the preferred non-cURL way if user is using PHP 5.x
if ($pv[0] == '5') {
$context = stream_context_create(array(
'http' => $ctx,
));
$fp = fopen($url, 'r', false, $context);
ob_start();
fpassthru($fp);
fclose($fp);
$res = ob_get_clean();
}
else {
// this should work with PHP 4, but it seems to take forever to get data back this way
// NOTE: setting the default_socket_timeout seems to alleviate this issue [finally].
list($protocol, $url) = explode('//', $url, 2);
list($domain, $path) = explode('/', $url, 2);
$fp = fsockopen($domain, 80, $tvar, $tvar2, SOCKET_TIMEOUT);
if ($fp) {
$payload = "{$method} /{$path} HTTP/1.1\n" . "Host: {$domain}\n" . $ctx['header'];
fwrite($fp, $payload);
// even with the socket timeout set, using fgets() isn't playing nice, but
// fpassthru() seems to be doing the right thing.
ob_start();
fpassthru($fp);
list($headers, $res) = explode("\r\n\r\n", ob_get_clean(), 2);
if ($this->debug_level) {
$this->debug_info['headers_received'] = $headers;
}
fclose($fp);
}
elseif ($this->debug_level) {
$this->debug_info['overview'] .= "\nOpening {$domain}/{$path} failed!";
}
}
}
if ($res) {
if ($this->method == 'soap') {
$tmp = $this
->xml2array($res, '/soap:Envelope/soap:Body');
if (!is_array($tmp)) {
return $tmp;
}
else {
return $tmp[$action . 'Response'][$action . 'Result'];
}
}
else {
return $this
->xml2array($res);
}
}
else {
return null;
}
}