From 843461017b8d79e8824f60b9308967bc98ba7a91 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Wed, 27 Jan 2016 10:44:33 -0500 Subject: [PATCH 01/11] Compendium updates: Cleanup autoloading, replace die and echo statements, and fix casing in OptionalData --- Autoload.php | 78 ++++++++++++++++++++++++++++++++++++++++ bootstrap.php | 39 ++++++++++++++------ interact.php | 49 ++++++++++--------------- objects/OptionalData.php | 4 +-- 4 files changed, 127 insertions(+), 43 deletions(-) create mode 100644 Autoload.php diff --git a/Autoload.php b/Autoload.php new file mode 100644 index 0000000..7443c72 --- /dev/null +++ b/Autoload.php @@ -0,0 +1,78 @@ + 'interact.php', + 'getLaunchStatus' => 'includes/campaign.php', + 'launchCampaign' => 'includes/campaign.php', + 'mergeTriggerEmail' => 'includes/campaign.php', + 'scheduleCampaignLaunch' => 'includes/campaign.php', + 'triggerCustomEvent' => 'includes/campaign.php', + 'triggerCampaignMessage' => 'includes/campaign.php', + 'copyContentLibraryItem' => 'includes/content.php', + 'createContentLibraryItem' => 'includes/content.php', + 'createDocument' => 'includes/content.php', + 'deleteContentLibraryItem' => 'includes/content.php', + 'deleteDocument' => 'includes/content.php', + 'getContentLibraryItem' => 'includes/content.php', + 'getDocumentContent' => 'includes/content.php', + 'getDocumentImages' => 'includes/content.php', + 'moveContentLibraryItem' => 'includes/content.php', + 'setDocumentContent' => 'includes/content.php', + 'setDocumentImages' => 'includes/content.php', + 'updateContentLibraryItem' => 'includes/content.php', + 'deleteFolder' => 'includes/folder.php', + 'listFolders' => 'includes/folder.php', + 'mergeListMembersRIID' => 'includes/list.php', + 'retrieveListMembers' => 'includes/list.php', + 'deleteListMembers' => 'includes/list.php', + 'createTable' => 'includes/table.php', + 'createTableWithPK' => 'includes/table.php', + 'deleteProfileExtensionMembers' => 'includes/table.php', + 'deleteTable' => 'includes/table.php', + 'mergeIntoProfileExtension' => 'includes/table.php', + 'mergeTableRecords' => 'includes/table.php', + 'mergeTableRecordsWithPK' => 'includes/table.php', + 'deleteTableRecords' => 'includes/table.php', + 'retrieveTableRecords' => 'includes/table.php', + 'retrieveProfileExtensionRecords' => 'includes/table.php', + 'truncateTable' => 'includes/table.php', + 'CustomEvent' => 'objects/CustomEvent.php', + 'DefaultPermissionStatus' => 'objects/DefaultPermissionStatus.php', + 'EmailFormat' => 'objects/EmailFormat.php', + 'Field' => 'objects/Field.php', + 'FieldType' => 'objects/FieldType.php', + 'ImageData' => 'objects/ImageData.php', + 'InteractObject' => 'objects/InteractObject.php', + 'ItemData' => 'objects/ItemData.php', + 'LaunchPreferences' => 'objects/LaunchPreferences.php', + 'ListMergeRule' => 'objects/ListMergeRule.php', + 'MatchColumn' => 'objects/MatchColumn.php', + 'MatchOperator' => 'objects/MatchOperator.php', + 'OptionalData' => 'objects/OptionalData.php', + 'ProofLaunchOptions' => 'objects/ProofLaunchOptions.php', + 'ProofLaunchType' => 'objects/ProofLaunchType.php', + 'QueryColumn' => 'objects/QueryColumn.php', + 'RecipientData' => 'objects/RecipientData.php', + 'RecipientIdentifier' => 'objects/RecipientIdentifier.php', + 'Recipient' => 'objects/Recipient.php', + 'RecordData' => 'objects/RecordData.php', + 'Record' => 'objects/Record.php', + 'RejectChannel' => 'objects/RejectChannel.php', + 'UpdateOnMatch' => 'objects/UpdateOnMatch.php' + ); + } + $path = __DIR__; + if ( isset($class_map[$class]) ) { + $file = $path . '/' . $class_map[$class]; + require_once $file; + } + } + spl_autoload_register('Responsys_Autoload'); +} + +?> \ No newline at end of file diff --git a/bootstrap.php b/bootstrap.php index d8bbc78..76a0b3c 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,5 +1,14 @@ \ No newline at end of file diff --git a/interact.php b/interact.php index 18cf843..c03d211 100755 --- a/interact.php +++ b/interact.php @@ -151,23 +151,13 @@ private function print_xml() public function execute( $instance ) { $result = null; - - try - { + + try{ $result = self::$soapClient->{ get_class( $instance ) }( $instance->params ); - $this->print_xml(); - } - catch( SoapFault $fault ) - { - echo " *** SOAPFAULT *** \n"; - $this->print_xml(); - - } - catch( Exception $exception ) - { - echo " *** EXCEPTION *** \n"; - echo $exception->getMessage(); + } catch (Exception $ex){ + throw $ex; } + $this->print_xml(); if( $this->debug == true ) print_r( $result ); @@ -185,8 +175,7 @@ private function loadObjects() foreach( $objects as $object ) { - echo "Including object ( file/class ): " . $object . "\n"; - include( $object ); + require_once( $object ); } } @@ -223,7 +212,9 @@ public function login( $username, $password ) } else { - echo "Logged in -> session_id : " . $this->sessionId . "\n"; + if ($this->debug){ + echo "Logged in -> session_id : " . $this->sessionId . "\n"; + } self::$isLoggedIn = true; $result = true; @@ -256,7 +247,9 @@ public function logout() { self::$isLoggedIn = false; self::$soapClient = null; - echo "Logged Out from sessionId : " . $this->sessionId . "\n"; + if( $this->debug == true ) { + echo "Logged Out from sessionId : " . $this->sessionId . "\n"; + } $result = true; } } @@ -301,11 +294,11 @@ private function authenticateServer( $user, $challenge, $pod, $isHATM=false ) if( $this->setSoapClient() ) { $authServerParams = new authenticateServerCall( $user, $challenge ); - $this->doApiCall( $authServerParams::API_CALL_NAME, $authServerParams ); + $this->doApiCall( authenticateServerCall::API_CALL_NAME, $authServerParams ); } else { - die( self::SOAP_ERROR_CLIENT ); + throw new SoapFault( self::SOAP_ERROR_CLIENT ); } return isset( $this->result->result->authSessionId ); @@ -349,7 +342,7 @@ public function loginWithCertificate( $user, $byte_array_challenge, $pod, $isHAT } else { - die( "Failed authenticate server call - exiting" ); + throw new Exception( "Failed authenticate server call - exiting" ); } // Hack to deal with null returns in challenge strings ( weak! ) @@ -385,8 +378,7 @@ public function loginWithCertificate( $user, $byte_array_challenge, $pod, $isHAT } else { - echo openssl_error_string(); - die( "Failed to decrypt the challenge - exiting" ); + throw new Exception( "Failed to decrypt the challenge " . openssl_error_string() ); } @@ -415,7 +407,7 @@ public function loginWithCertificate( $user, $byte_array_challenge, $pod, $isHAT if ( !openssl_private_encrypt($encryptMe, $encryptedData, $private_key, OPENSSL_PKCS1_PADDING ) ) { - die( "Failed to Encrypt data with Private Key - exiting"); + throw new Exception( "Failed to Encrypt data with Private Key - exiting"); } // Now we have to unpack data which converts unsigned encrypted data to signed byte type @@ -446,19 +438,14 @@ public function loginWithCertificate( $user, $byte_array_challenge, $pod, $isHAT $this->execute( 'loginWithCertificate', $encryptedServerChallenge ); - //print_r( $this->result ); return $this->result->result->sessionId; } else { - die("Problem during handshake - exiting"); + throw new SoapFault("Problem during handshake - exiting"); } } } - - - - ?> diff --git a/objects/OptionalData.php b/objects/OptionalData.php index 0d04fea..d482aa5 100755 --- a/objects/OptionalData.php +++ b/objects/OptionalData.php @@ -1,6 +1,6 @@ value = $value; } -} \ No newline at end of file +} From 14d05724a58747291702c5dcbc4f274b474b56c7 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Wed, 27 Jan 2016 10:51:36 -0500 Subject: [PATCH 02/11] Support use of a different soap client implementation --- interact.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/interact.php b/interact.php index c03d211..96ba20f 100755 --- a/interact.php +++ b/interact.php @@ -16,7 +16,8 @@ class interact CONST RESPONSYS_PUBLIC_CERTIFICATE = "/Users/mdixon/Documents/certificatefun/ResponsysServerCertificate.cer"; CONST CLIENT_PRIVATE_KEY = "/Users/mdixon/Documents/certificatefun/mdixon/md_private.key"; - protected $endPoint, + protected $soapClientClass, + $endPoint, $wsdl, $uri, $soapNameSpace, @@ -32,7 +33,10 @@ class interact public $result, $debug = false; - function __construct(){} + function __construct($client_class = "SoapClient") + { + $this->soapClientClass = $client_class; + } /** * Constructor responsible for creating PHP dynamic soap client @@ -106,7 +110,7 @@ private function setSoapClient() //'proxy_port' => '8888', 'cache_wsdl' => WSDL_CACHE_NONE, ) ; - self::$soapClient = new SoapClient( $this->wsdl, $soapClientParams ); + self::$soapClient = new $this->soapClientClass( $this->wsdl, $soapClientParams ); if( self::$soapClient instanceof SoapClient) { From 26b84976eb04c25776d9a1f2b47cca3fa6391ae3 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Wed, 27 Jan 2016 10:55:16 -0500 Subject: [PATCH 03/11] Add api support for content library folders --- Autoload.php | 3 +++ includes/folder.php | 30 ++++++++++++++++++++++++++++++ interact.php | 1 + 3 files changed, 34 insertions(+) diff --git a/Autoload.php b/Autoload.php index 7443c72..46743d3 100644 --- a/Autoload.php +++ b/Autoload.php @@ -27,6 +27,9 @@ function Responsys_Autoload($class = NULL) 'updateContentLibraryItem' => 'includes/content.php', 'deleteFolder' => 'includes/folder.php', 'listFolders' => 'includes/folder.php', + 'createContentLibraryFolder' => 'includes/folder.php', + 'createFolder' => 'includes/folder.php', + 'doesContentLibraryFolderExist' => 'includes/folder.php', 'mergeListMembersRIID' => 'includes/list.php', 'retrieveListMembers' => 'includes/list.php', 'deleteListMembers' => 'includes/list.php', diff --git a/includes/folder.php b/includes/folder.php index 7b4ee64..38517ab 100755 --- a/includes/folder.php +++ b/includes/folder.php @@ -15,3 +15,33 @@ class listFolders extends interact { public $params = array(); } + +class createContentLibraryFolder extends interact +{ + public $params = array( 'path' => null ); + + public function setPathParam( $folderName ) + { + $this->params['path'] = $folderName; + } +} + +class createFolder extends interact +{ + public $params = array( 'folderName' => null ); + + public function setFolderNameParam( $folderName ) + { + $this->params['folderName'] = $folderName; + } +} + +class doesContentLibraryFolderExist extends interact +{ + public $params = array( 'path' => null ); + + public function setPathParam( $path ) + { + $this->params['path'] = $path; + } +} diff --git a/interact.php b/interact.php index 96ba20f..c07e111 100755 --- a/interact.php +++ b/interact.php @@ -159,6 +159,7 @@ public function execute( $instance ) try{ $result = self::$soapClient->{ get_class( $instance ) }( $instance->params ); } catch (Exception $ex){ + $this->print_xml(); throw $ex; } $this->print_xml(); From 1906a2562f553a196bba52c7aa4de9adc33a0640 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Wed, 27 Jan 2016 11:23:07 -0500 Subject: [PATCH 04/11] Add missing new classes to Autoload --- Autoload.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Autoload.php b/Autoload.php index 46743d3..a3fbc7b 100644 --- a/Autoload.php +++ b/Autoload.php @@ -13,6 +13,7 @@ function Responsys_Autoload($class = NULL) 'scheduleCampaignLaunch' => 'includes/campaign.php', 'triggerCustomEvent' => 'includes/campaign.php', 'triggerCampaignMessage' => 'includes/campaign.php', + 'HAmergeTriggerEmail' => 'includes/campaign.php', 'copyContentLibraryItem' => 'includes/content.php', 'createContentLibraryItem' => 'includes/content.php', 'createDocument' => 'includes/content.php', @@ -66,7 +67,10 @@ function Responsys_Autoload($class = NULL) 'RecordData' => 'objects/RecordData.php', 'Record' => 'objects/Record.php', 'RejectChannel' => 'objects/RejectChannel.php', - 'UpdateOnMatch' => 'objects/UpdateOnMatch.php' + 'UpdateOnMatch' => 'objects/UpdateOnMatch.php', + 'authenticateServer' => 'objects/Login.php', + 'loginWithCertificate' => 'objects/Login.php', + 'ProgressChunk' => 'objects/ProgressChunk.php' ); } $path = __DIR__; From b70e64e3cc408a798588ce164ac8833747846670 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Wed, 27 Jan 2016 11:25:50 -0500 Subject: [PATCH 05/11] Comment out print_r statement --- interact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interact.php b/interact.php index d59ee47..8b05dc8 100755 --- a/interact.php +++ b/interact.php @@ -452,7 +452,7 @@ public function loginWithCertificate( $user, $byte_array_challenge, $wsdl, $endp $result = $this->execute( $loginWithCertObj ); - print_r( $result ); + //print_r( $result ); return $result; } From 4d7fe92b365941259821613fcad30582219c484c Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Wed, 27 Jan 2016 11:44:13 -0500 Subject: [PATCH 06/11] Handle soap client class in initialize; fixes problems with subclasses --- interact.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/interact.php b/interact.php index 7a8cd48..25a014a 100755 --- a/interact.php +++ b/interact.php @@ -32,10 +32,7 @@ class interact public $result, $debug = false; - function __construct($client_class = "SoapClient") - { - $this->soapClientClass = $client_class; - } + function __construct(){} /** * Constructor responsible for creating PHP dynamic soap client @@ -43,20 +40,21 @@ function __construct($client_class = "SoapClient") * @param unknown $pod_number WILL BE A 2 or 5 depending on the account location ws5.responsys.net* or ws2.responsys.net* * @throws Exception */ - public function intitializeSoapClient( $wsdl, $end_point ) + public function intitializeSoapClient( $wsdl, $end_point, $client_class = "SoapClient" ) { - $this->setSoapParams( $wsdl, $end_point ); + $this->setSoapParams( $wsdl, $end_point, $client_class ); if( !$this->setSoapClient() ) throw new Exception(" *** Soap Client Init Failed *** "); } - private function setSoapParams( $wsdl, $end_point ) + private function setSoapParams( $wsdl, $end_point, $client_class = "SoapClient" ) { $this->wsdl = $wsdl; $this->endPoint = $end_point; $this->uri = ( stristr("ws3", $wsdl) || stristr("ws4", $wsdl) ) ? self::SOAP_URI_URSA : null; $this->soapNameSpace = ( stristr("ws3", $wsdl) || stristr("ws4", $wsdl) ) ? self::SOAP_NS_URSA : self::SOAP_NS; + $this->soapClientClass = $client_class; } private function setSoapHeaders( $authId = null ) @@ -301,7 +299,7 @@ private function authServer( $user, $challenge, $wsdl, $endpoint) $result = null; - $this->setSoapParams( $wsdl, $endpoint ); + $this->setSoapParams( $wsdl, $endpoint, $this->soapClientClass ); if( $this->setSoapClient() ) { From 894466909471546200b6d1b62aca8c7aa5976953 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Mon, 1 Feb 2016 09:53:31 -0500 Subject: [PATCH 07/11] Additional error handling in login/logout situations --- interact.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/interact.php b/interact.php index 25a014a..c9528e6 100755 --- a/interact.php +++ b/interact.php @@ -229,6 +229,17 @@ public function login( $username, $password ) $this->print_xml(); } } + else + { + throw new Exception (self::SOAP_ERROR_LOGIN); + } + } + else + { + if ($this->debug) { + echo "Attempt to login when already logged in"; + } + $result = true; } return $result; @@ -260,6 +271,13 @@ public function logout() } $result = true; } + else + { + if( $this->debug == true ) { + echo "Unable to perform logout"; + $this->print_xml(); + } + } } return $result; @@ -452,6 +470,9 @@ public function loginWithCertificate( $user, $byte_array_challenge, $wsdl, $endp throw new Exception( self::SOAP_ERROR_HEADER ); } } + else { + throw new Exception (self::SOAP_ERROR_LOGIN); + } //print_r( $result ); return $result; From 6e62515e4ad0de373d081136041baf0555252803 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Mon, 1 Feb 2016 10:25:03 -0500 Subject: [PATCH 08/11] Use isLoggedIn flags when dealing with cert auth --- interact.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interact.php b/interact.php index c9528e6..5849485 100755 --- a/interact.php +++ b/interact.php @@ -344,6 +344,13 @@ private function authServer( $user, $challenge, $wsdl, $endpoint) */ public function loginWithCertificate( $user, $byte_array_challenge, $wsdl, $endpoint, $responsys_public_cert_path, $client_private_key_path) { + + if( self::$isLoggedIn ) { + if ($this->debug) { + echo "Attempt to loginWithCertificate when already logged in"; + } + return false; + } // RESPONSYS PUBLIC CERT $responsys_certificate_file = file_get_contents( $responsys_public_cert_path ); @@ -469,6 +476,8 @@ public function loginWithCertificate( $user, $byte_array_challenge, $wsdl, $endp { throw new Exception( self::SOAP_ERROR_HEADER ); } + + self::$isLoggedIn = true; } else { throw new Exception (self::SOAP_ERROR_LOGIN); From 98b4ca90af1bc9307f1600341ce78d94b5090fbc Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Mon, 1 Feb 2016 13:11:32 -0500 Subject: [PATCH 09/11] Return false when already logged in to preserve existing functionality --- interact.php | 1 - 1 file changed, 1 deletion(-) diff --git a/interact.php b/interact.php index 5849485..52ba898 100755 --- a/interact.php +++ b/interact.php @@ -239,7 +239,6 @@ public function login( $username, $password ) if ($this->debug) { echo "Attempt to login when already logged in"; } - $result = true; } return $result; From 564d07d2ebc487f0c429842b451ac1005dbb1d27 Mon Sep 17 00:00:00 2001 From: Andrew Morin Date: Tue, 23 Feb 2016 16:06:04 -0500 Subject: [PATCH 10/11] Catch logout exceptions and force user as logged out --- interact.php | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/interact.php b/interact.php index 52ba898..9c56dcc 100755 --- a/interact.php +++ b/interact.php @@ -256,26 +256,36 @@ public function logout() if( self::$isLoggedIn ) { - $loggedOut = self::$soapClient->logout(); - - if( $this->debug == true ) - $this->print_xml(); - - if( $loggedOut->result == 1 ) - { - self::$isLoggedIn = false; - self::$soapClient = null; - if( $this->debug == true ) { - echo "Logged Out from sessionId : " . $this->sessionId . "\n"; + try { + $loggedOut = self::$soapClient->logout(); + + if( $this->debug == true ) + $this->print_xml(); + + if( $loggedOut->result == 1 ) + { + self::$isLoggedIn = false; + self::$soapClient = null; + if( $this->debug == true ) { + echo "Logged Out from sessionId : " . $this->sessionId . "\n"; + } + $result = true; + } + else + { + if( $this->debug == true ) { + echo "Unable to perform logout"; + $this->print_xml(); + } } - $result = true; } - else - { + catch( \Exception $ex) { + self::$isLoggedIn = false; + self::$soapClient = null; if( $this->debug == true ) { - echo "Unable to perform logout"; - $this->print_xml(); + echo "Error logging out: " . $ex->getMessage(); } + throw $ex; } } From e628f614d05dbc2be8b0d8085374c60fe288899b Mon Sep 17 00:00:00 2001 From: Stephen Gregory Date: Tue, 30 Aug 2016 13:37:13 -0400 Subject: [PATCH 11/11] Updates for merging users to lists - add mergeListMember object (only mergeListMembersRIID was available) - fix setDefaultPermissionStatus for merge rule (was always using null) --- includes/list.php | 24 ++++++++++++++++++++++++ objects/ListMergeRule.php | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/includes/list.php b/includes/list.php index 4b1683f..6bb4027 100755 --- a/includes/list.php +++ b/includes/list.php @@ -24,6 +24,30 @@ public function setListParam( InteractObject $interact_object ) } +class mergeListMembers extends interact +{ + public $params = array( 'recordData' => array( 'fieldNames' => null, 'records' => null ), + 'mergeRule' => null, + 'list' => null ); + + public function setMergeRuleParam( ListMergeRule $rule ) + { + $this->params['mergeRule'] = $rule; + } + + public function setRecordDataParam( array $fieldNames, array $records ) + { + $this->params['recordData']['fieldNames'] = $fieldNames; + $this->params['recordData']['records'] = $records; + } + + public function setListParam( InteractObject $interact_object ) + { + $this->params['list'] = $interact_object; + } + +} + /** * Retrieve a record or set of records by its QueryColumn value */ diff --git a/objects/ListMergeRule.php b/objects/ListMergeRule.php index 26123f0..b45f102 100644 --- a/objects/ListMergeRule.php +++ b/objects/ListMergeRule.php @@ -56,7 +56,7 @@ public function setRejectChannel( RejectChannel $channel ) public function setDefaultPermissionStatus( DefaultPermissionStatus $status ) { - $this->defaultPermissionStatus = null;//$status->defaultPermissionStatus; + $this->defaultPermissionStatus = $status->defaultPermissionStatus; } public function setMatchColumn1( MatchColumn $match_column )