From 0239f5c895cd4c22769a7fbf5ae56407b85b49ac Mon Sep 17 00:00:00 2001 From: Daniel Coffey Date: Wed, 26 Jun 2024 14:54:24 +1000 Subject: [PATCH 1/2] Updates to cater for Keap sunsetting of legacy API keys. This changes the legacy key settings in config.php to allow use of a SAK (Service Access Key) and adds the new X-Keap-Api-Key header in xmlrpc.php. --- Infusionsoft/App.php | 4 +++- Infusionsoft/config.sample.php | 13 ++++++++++++- Infusionsoft/xmlrpc.inc | 28 ++++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Infusionsoft/App.php b/Infusionsoft/App.php index 66f2685..a3aab95 100644 --- a/Infusionsoft/App.php +++ b/Infusionsoft/App.php @@ -48,7 +48,9 @@ public function initApiKeyClient($apiKey = null, $initAsFallback = false){ $this->apiKey = $apiKey; } - $this->client = new xmlrpc_client('/api/xmlrpc', $this->getHostname(), $this->port); + //$this->client = new xmlrpc_client('/api/xmlrpc', $this->getHostname(), $this->port); // Deprecated as of Oct 2024 - Keap sunsetting legacy api keys + $this->client = new xmlrpc_client('/crm/xmlrpc', 'api.infusionsoft.com', 443); + $this->client->setCustomHeader('X-Keap-Api-Key: ' . $apiKey); if ($initAsFallback){ $this->initOauthClient(); } diff --git a/Infusionsoft/config.sample.php b/Infusionsoft/config.sample.php index ab5b51c..7c34824 100644 --- a/Infusionsoft/config.sample.php +++ b/Infusionsoft/config.sample.php @@ -1,10 +1,21 @@ user_agent = $agentstring; } + + /** + * Add a custom header + * @param type $customheader + * @return type + */ + function setCustomHeader($customheader){ + foreach($this->customheaders as $ch){ + if ($ch===$customheader) return; + } + $this->customheaders[] = $customheader; + } + + /** * Send an xmlrpc request * @param mixed $msg The message object, or an array of messages for using multicall, or the complete xml representation of a request @@ -1235,7 +1250,8 @@ class xmlrpc_client $this->proxyport, $this->proxy_user, $this->proxy_pass, - $this->proxy_authtype + $this->proxy_authtype, + $this->customheaders ); } @@ -1361,6 +1377,9 @@ class xmlrpc_client // omit port if 80 $port = ($port == 80) ? '' : (':' . $port); + $customheaderString = (is_array($customheaders) && sizeof($customheaders)>0 ) ? implode("\r\n", $customheaders) . "\r\n" : ""; + + $op= 'POST ' . $uri. " HTTP/1.0\r\n" . 'User-Agent: ' . $this->user_agent . "\r\n" . 'Host: '. $server . $port . "\r\n" . @@ -1369,6 +1388,7 @@ class xmlrpc_client $accepted_encoding . $encoding_hdr . 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings) . "\r\n" . + $customheaderString . $cookieheader . 'Content-Type: ' . $msg->content_type . "\r\nContent-Length: " . strlen($payload) . "\r\n\r\n" . @@ -1436,11 +1456,11 @@ class xmlrpc_client function &sendPayloadHTTPS($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $cert='',$certpass='', $cacert='', $cacertdir='', $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, - $keepalive=false, $key='', $keypass='') + $keepalive=false, $key='', $keypass='', $customheaders=[]) { $r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username, $password, $authtype, $cert, $certpass, $cacert, $cacertdir, $proxyhost, $proxyport, - $proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass); + $proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass, $customheaders); return $r; } @@ -1453,7 +1473,7 @@ class xmlrpc_client function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $cert='', $certpass='', $cacert='', $cacertdir='', $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $method='https', - $keepalive=false, $key='', $keypass='') + $keepalive=false, $key='', $keypass='', $customheaders=[]) { if(!function_exists('curl_init')) { From d7f27c5571790013cea91080f09597f9b3cf126d Mon Sep 17 00:00:00 2001 From: Daniel Coffey Date: Wed, 26 Jun 2024 14:54:24 +1000 Subject: [PATCH 2/2] previous commit missed the changes to xmlrpc.inc --- Infusionsoft/App.php | 4 ++- Infusionsoft/config.sample.php | 13 +++++++++- Infusionsoft/xmlrpc.inc | 46 ++++++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Infusionsoft/App.php b/Infusionsoft/App.php index 66f2685..a3aab95 100644 --- a/Infusionsoft/App.php +++ b/Infusionsoft/App.php @@ -48,7 +48,9 @@ public function initApiKeyClient($apiKey = null, $initAsFallback = false){ $this->apiKey = $apiKey; } - $this->client = new xmlrpc_client('/api/xmlrpc', $this->getHostname(), $this->port); + //$this->client = new xmlrpc_client('/api/xmlrpc', $this->getHostname(), $this->port); // Deprecated as of Oct 2024 - Keap sunsetting legacy api keys + $this->client = new xmlrpc_client('/crm/xmlrpc', 'api.infusionsoft.com', 443); + $this->client->setCustomHeader('X-Keap-Api-Key: ' . $apiKey); if ($initAsFallback){ $this->initOauthClient(); } diff --git a/Infusionsoft/config.sample.php b/Infusionsoft/config.sample.php index ab5b51c..7c34824 100644 --- a/Infusionsoft/config.sample.php +++ b/Infusionsoft/config.sample.php @@ -1,10 +1,21 @@ user_agent = $agentstring; } + + /** + * Add a custom header + * @param type $customheader + * @return type + */ + function setCustomHeader($customheader){ + foreach($this->customheaders as $ch){ + if ($ch===$customheader) return; + } + $this->customheaders[] = $customheader; + } + + /** * Send an xmlrpc request * @param mixed $msg The message object, or an array of messages for using multicall, or the complete xml representation of a request @@ -1195,7 +1210,8 @@ class xmlrpc_client $this->proxy_authtype, $this->keepalive, $this->key, - $this->keypass + $this->keypass, + $this->customheaders ); } elseif($method == 'http11') @@ -1235,7 +1251,8 @@ class xmlrpc_client $this->proxyport, $this->proxy_user, $this->proxy_pass, - $this->proxy_authtype + $this->proxy_authtype, + $this->customheaders ); } @@ -1247,7 +1264,7 @@ class xmlrpc_client */ function &sendPayloadHTTP10($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $proxyhost='', - $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1) + $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $customheaders=[]) { if($port==0) { @@ -1361,6 +1378,9 @@ class xmlrpc_client // omit port if 80 $port = ($port == 80) ? '' : (':' . $port); + $customheaderString = (is_array($customheaders) && sizeof($customheaders)>0 ) ? implode("\r\n", $customheaders) . "\r\n" : ""; + + $op= 'POST ' . $uri. " HTTP/1.0\r\n" . 'User-Agent: ' . $this->user_agent . "\r\n" . 'Host: '. $server . $port . "\r\n" . @@ -1369,6 +1389,7 @@ class xmlrpc_client $accepted_encoding . $encoding_hdr . 'Accept-Charset: ' . implode(',', $this->accepted_charset_encodings) . "\r\n" . + $customheaderString . $cookieheader . 'Content-Type: ' . $msg->content_type . "\r\nContent-Length: " . strlen($payload) . "\r\n\r\n" . @@ -1436,11 +1457,11 @@ class xmlrpc_client function &sendPayloadHTTPS($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $cert='',$certpass='', $cacert='', $cacertdir='', $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, - $keepalive=false, $key='', $keypass='') + $keepalive=false, $key='', $keypass='', $customheaders=[]) { $r =& $this->sendPayloadCURL($msg, $server, $port, $timeout, $username, $password, $authtype, $cert, $certpass, $cacert, $cacertdir, $proxyhost, $proxyport, - $proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass); + $proxyusername, $proxypassword, $proxyauthtype, 'https', $keepalive, $key, $keypass, $customheaders); return $r; } @@ -1453,7 +1474,7 @@ class xmlrpc_client function &sendPayloadCURL($msg, $server, $port, $timeout=0, $username='', $password='', $authtype=1, $cert='', $certpass='', $cacert='', $cacertdir='', $proxyhost='', $proxyport=0, $proxyusername='', $proxypassword='', $proxyauthtype=1, $method='https', - $keepalive=false, $key='', $keypass='') + $keepalive=false, $key='', $keypass='', $customheaders=[]) { if(!function_exists('curl_init')) { @@ -1581,6 +1602,12 @@ class xmlrpc_client $headers[] = $encoding_hdr; } + if(is_array($customheaders) && sizeof($customheaders)>0){ + foreach($customheaders as $ch){ + $headers[] = $ch; + } + } + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); // timeout is borked if($timeout) @@ -2658,7 +2685,12 @@ class xmlrpcmsg // **END JORDAN NOVAK EDIT** //ForceUTF8 seems to have fixed our problems.. - $data = ForceUTF8\Encoding::toUTF8($data); + if (method_exists('ForceUTF8\Encoding','toUTF8')){ + $data = ForceUTF8\Encoding::toUTF8($data); + }else{ + $data = preg_replace(array('/\&#[0-9]{1,4}(?![0-9]{0,3};)/'),'', $data); + $data = str_replace(array("", " ", "�", "", "", "", "", "", " ", "", "", "", "", "", "", "", "", "´", "Á", "Ö", "ð", "ÿ", "ƒ", "‚", "™", '￿', ''/*non-printing character, this is not an empty string*/), "", $data); + } //0x19 is Ascii End of Medium and is causing problems, but we'll fix it AFTER ForceUTF8 //0x12 is Ascii something and is causing problems, but we'll fix it AFTER ForceUTF8