From 6df308e02a2b3ee3fbbb75b724e5a0184336eb46 Mon Sep 17 00:00:00 2001 From: Tim Redmond Date: Wed, 29 Jun 2011 10:59:22 -0600 Subject: [PATCH 01/34] Fixed xsi:nil setting $result to "true" --- soapclient/SforceBaseClient.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index eecbf0d..9e203d1 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -1128,9 +1128,9 @@ function xml2array($contents, $get_attributes=1) { $result = $value; } - //Set the attributes too. - if(isset($attributes) && isset($attributes['xsi:nil'])) { - $result = $attributes['xsi:nil']; + //Check for nil and ignore other attributes. + if (isset($attributes) && isset($attributes['xsi:nil']) && !strcasecmp($attributes['xsi:nil'], 'true')) { + $result = null; } break; } From c9db55e7a32870fe7ada28ebdda7f7e5e022f555 Mon Sep 17 00:00:00 2001 From: David de Boer Date: Thu, 30 Jun 2011 16:34:49 +0200 Subject: [PATCH 02/34] Fix PHP strict notice --- soapclient/SforceEnterpriseClient.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soapclient/SforceEnterpriseClient.php b/soapclient/SforceEnterpriseClient.php index 8b269ad..6c79c50 100644 --- a/soapclient/SforceEnterpriseClient.php +++ b/soapclient/SforceEnterpriseClient.php @@ -86,6 +86,7 @@ public function update($sObjects, $type, $assignment_header = NULL, $mru_header } // ------ } + $arg = new stdClass; $arg->sObjects = $sObjects; return parent::_update($arg); } @@ -135,6 +136,7 @@ public function upsert($ext_Id, $sObjects, $type = 'Contact') { */ public function merge($mergeRequest, $type) { $mergeRequest->masterRecord = new SoapVar($mergeRequest->masterRecord, SOAP_ENC_OBJECT, $type, $this->namespace); + $arg = new stdClass; $arg->request = new SoapVar($mergeRequest, SOAP_ENC_OBJECT, 'MergeRequest', $this->namespace); return parent::_merge($arg); } From c9db0f7e248a51071752a093a2aace125ec8eca7 Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Fri, 22 Jul 2011 23:48:27 -0600 Subject: [PATCH 03/34] Allow fieldsToNull to be an array in create() call. Fixes #11 --- soapclient/SforceEnterpriseClient.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/soapclient/SforceEnterpriseClient.php b/soapclient/SforceEnterpriseClient.php index 6c79c50..3aaa976 100644 --- a/soapclient/SforceEnterpriseClient.php +++ b/soapclient/SforceEnterpriseClient.php @@ -50,8 +50,23 @@ function SforceEnterpriseClient() { * @return SaveResult */ public function create($sObjects, $type) { - foreach ($sObjects as &$sobject) { - $sobject = new SoapVar($sobject, SOAP_ENC_OBJECT, $type, $this->namespace); + foreach ($sObjects as &$sObject) { + // FIX for fieldsToNull issue - allow array in fieldsToNull (STEP #1) + $xmlStr = ''; + if(isset($sObject->fieldsToNull) && is_array($sObject->fieldsToNull)) { + foreach($sObject->fieldsToNull as $fieldToNull) { + $xmlStr .= '' . $fieldToNull . ''; + } + } + // ------ + + $sObject = new SoapVar($sObject, SOAP_ENC_OBJECT, $type, $this->namespace); + + // FIX for fieldsToNull issue - allow array in fieldsToNull (STEP #2) + if($xmlStr != '') { + $sObject->enc_value->fieldsToNull = new SoapVar(new SoapVar($xmlStr, XSD_ANYXML), SOAP_ENC_ARRAY); + } + // ------ } $arg = $sObjects; From 30d642f5264c7f9a914fcc0d0a35c9cf467254f1 Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Thu, 3 Nov 2011 11:18:04 -0700 Subject: [PATCH 04/34] Allow metadata types other than CustomObject to be created and deleted --- soapclient/SforceMetadataClient.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soapclient/SforceMetadataClient.php b/soapclient/SforceMetadataClient.php index 24806f6..a11b058 100644 --- a/soapclient/SforceMetadataClient.php +++ b/soapclient/SforceMetadataClient.php @@ -117,14 +117,14 @@ public function setSessionHeader($sessionId) { $this->sforce->__setSoapHeaders($header_array); } - public function create($obj) { - $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, 'CustomObject', $this->namespace); + public function create($obj, $objtype = 'CustomObject') { + $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $objtype, $this->namespace); return $this->sforce->create($encodedObj); } - public function delete($obj) { - $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, 'CustomObject', $this->namespace); + public function delete($obj, $objtype = 'CustomObject') { + $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $objtype, $this->namespace); return $this->sforce->delete($encodedObj); } From 2fc711750571bdc7d5ecaa6a6955e9e22c7aa23d Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Thu, 3 Nov 2011 11:34:29 -0700 Subject: [PATCH 05/34] Added SforceCustomObject->setSharingModel() --- soapclient/SforceMetaObject.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soapclient/SforceMetaObject.php b/soapclient/SforceMetaObject.php index a1c3baf..5c045af 100644 --- a/soapclient/SforceMetaObject.php +++ b/soapclient/SforceMetaObject.php @@ -79,6 +79,10 @@ public function setPluralLabel($pluralLabel) { $this->pluralLabel = $pluralLabel; } + public function setSharingModel($sharingModel) { + $this->sharingModel = $sharingModel; + } + public function setStartsWith($startsWith) { $this->startsWith = $startsWith; } From 08bfe09d831d8eb1f7bfe80213aa2d1ca2f994a7 Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Thu, 3 Nov 2011 22:47:14 -0700 Subject: [PATCH 06/34] Fixed E_STRICT messages --- soapclient/SforceMetadataClient.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soapclient/SforceMetadataClient.php b/soapclient/SforceMetadataClient.php index a11b058..0233ac7 100644 --- a/soapclient/SforceMetadataClient.php +++ b/soapclient/SforceMetadataClient.php @@ -118,12 +118,14 @@ public function setSessionHeader($sessionId) { } public function create($obj, $objtype = 'CustomObject') { + $encodedObj = new stdClass(); $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $objtype, $this->namespace); return $this->sforce->create($encodedObj); } public function delete($obj, $objtype = 'CustomObject') { + $encodedObj = new stdClass(); $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $objtype, $this->namespace); return $this->sforce->delete($encodedObj); From 45fe06554d29f132d060305804d812b458c36634 Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Thu, 3 Nov 2011 23:17:23 -0700 Subject: [PATCH 07/34] Infer SOAP object type from argument --- soapclient/SforceMetadataClient.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/soapclient/SforceMetadataClient.php b/soapclient/SforceMetadataClient.php index 0233ac7..8292aee 100644 --- a/soapclient/SforceMetadataClient.php +++ b/soapclient/SforceMetadataClient.php @@ -116,17 +116,26 @@ public function setSessionHeader($sessionId) { $this->_setClientId($header_array); $this->sforce->__setSoapHeaders($header_array); } + + private function getObjtype($obj) { + $classArray = explode('\\', get_class($obj)); + $objtype = array_pop($classArray); + if (strpos($objtype, 'Sforce', 0) === 0) { + $objtype = substr($objtype, 6); + } + return $objtype; + } - public function create($obj, $objtype = 'CustomObject') { + public function create($obj) { $encodedObj = new stdClass(); - $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $objtype, $this->namespace); + $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $this->getObjtype($obj), $this->namespace); return $this->sforce->create($encodedObj); } - public function delete($obj, $objtype = 'CustomObject') { + public function delete($obj) { $encodedObj = new stdClass(); - $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $objtype, $this->namespace); + $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $this->getObjtype($obj), $this->namespace); return $this->sforce->delete($encodedObj); } From 2f4b1f307289db1d32bab22f7e13181032448c4f Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Tue, 8 Nov 2011 10:40:07 -0800 Subject: [PATCH 08/34] Added update() method --- soapclient/SforceMetadataClient.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/soapclient/SforceMetadataClient.php b/soapclient/SforceMetadataClient.php index 8292aee..60f0007 100644 --- a/soapclient/SforceMetadataClient.php +++ b/soapclient/SforceMetadataClient.php @@ -133,6 +133,14 @@ public function create($obj) { return $this->sforce->create($encodedObj); } + public function update($obj) { + $encodedObj = new stdClass(); + $encodedObj->UpdateMetadata = $obj; + $encodedObj->UpdateMetadata->metadata = new SoapVar($obj->metadata, SOAP_ENC_OBJECT, $this->getObjtype($obj->metadata), $this->namespace); + + return $this->sforce->update($encodedObj); + } + public function delete($obj) { $encodedObj = new stdClass(); $encodedObj->metadata = new SoapVar($obj, SOAP_ENC_OBJECT, $this->getObjtype($obj), $this->namespace); From 6e6584339fdbaac9bd72d525602ca5d3f1f9b02d Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Tue, 8 Nov 2011 10:40:49 -0800 Subject: [PATCH 09/34] Fixed more E_STRICT warnings --- soapclient/SforceBaseClient.php | 46 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index 16fadca..86f2395 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -169,8 +169,8 @@ public function login($username, $password) { * @return LogoutResult */ public function logout() { - $this->setHeaders("logout"); - $arg = new stdClass; + $this->setHeaders("logout"); + $arg = new stdClass(); return $this->sforce->logout(); } @@ -180,9 +180,9 @@ public function logout() { * @return invalidateSessionsResult */ public function invalidateSessions() { - $this->setHeaders("invalidateSessions"); - $arg = new stdClass; - $this->logout(); + $this->setHeaders("invalidateSessions"); + $arg = new stdClass(); + $this->logout(); return $this->sforce->invalidateSessions(); } @@ -517,6 +517,7 @@ public function sendSingleEmail($request) { $email = new SoapVar($r, SOAP_ENC_OBJECT, 'SingleEmailMessage', $this->namespace); array_push($messages, $email); } + $arg = new stdClass(); $arg->messages = $messages; return $this->_sendEmail($arg); } else { @@ -532,6 +533,7 @@ public function sendMassEmail($request) { $email = new SoapVar($r, SOAP_ENC_OBJECT, 'MassEmailMessage', $this->namespace); array_push($messages, $email); } + $arg = new stdClass(); $arg->messages = $messages; return $this->_sendEmail($arg); } else { @@ -554,7 +556,7 @@ protected function _sendEmail($arg) { */ public function convertLead($leadConverts) { $this->setHeaders("convertLead"); - $arg = new stdClass; + $arg = new stdClass(); $arg->leadConverts = $leadConverts; return $this->sforce->convertLead($arg); } @@ -567,7 +569,7 @@ public function convertLead($leadConverts) { */ public function delete($ids) { $this->setHeaders("delete"); - $arg = new stdClass; + $arg = new stdClass(); $arg->ids = $ids; return $this->sforce->delete($arg)->result; } @@ -580,7 +582,7 @@ public function delete($ids) { */ public function undelete($ids) { $this->setHeaders("undelete"); - $arg = new stdClass; + $arg = new stdClass(); $arg->ids = $ids; return $this->sforce->undelete($arg)->result; } @@ -593,7 +595,7 @@ public function undelete($ids) { */ public function emptyRecycleBin($ids) { $this->setHeaders(); - $arg = new stdClass; + $arg = new stdClass(); $arg->ids = $ids; return $this->sforce->emptyRecycleBin($arg)->result; } @@ -609,6 +611,7 @@ public function processSubmitRequest($processRequestArray) { foreach ($processRequestArray as &$process) { $process = new SoapVar($process, SOAP_ENC_OBJECT, 'ProcessSubmitRequest', $this->namespace); } + $arg = new stdClass(); $arg->actions = $processRequestArray; return $this->_process($arg); } else { @@ -628,6 +631,7 @@ public function processWorkitemRequest($processRequestArray) { foreach ($processRequestArray as &$process) { $process = new SoapVar($process, SOAP_ENC_OBJECT, 'ProcessWorkitemRequest', $this->namespace); } + $arg = new stdClass(); $arg->actions = $processRequestArray; return $this->_process($arg); } else { @@ -658,7 +662,7 @@ public function describeGlobal() { */ public function describeLayout($type) { $this->setHeaders("describeLayout"); - $arg = new stdClass; + $arg = new stdClass(); $arg->sObjectType = new SoapVar($type, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); return $this->sforce->describeLayout($arg)->result; } @@ -672,7 +676,7 @@ public function describeLayout($type) { */ public function describeSObject($type) { $this->setHeaders("describeSObject"); - $arg = new stdClass; + $arg = new stdClass(); $arg->sObjectType = new SoapVar($type, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); return $this->sforce->describeSObject($arg)->result; } @@ -710,7 +714,7 @@ public function describeTabs() { */ public function describeDataCategoryGroups($sObjectType) { $this->setHeaders('describeDataCategoryGroups'); - $arg = new stdClass; + $arg = new stdClass(); $arg->sObjectType = new SoapVar($sObjectType, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); return $this->sforce->describeDataCategoryGroups($arg)->result; } @@ -724,7 +728,7 @@ public function describeDataCategoryGroups($sObjectType) { */ public function describeDataCategoryGroupStructures(array $pairs, $topCategoriesOnly) { $this->setHeaders('describeDataCategoryGroupStructures'); - $arg = new stdClass; + $arg = new stdClass(); $arg->pairs = $pairs; $arg->topCategoriesOnly = new SoapVar($topCategoriesOnly, XSD_BOOLEAN, 'boolean', 'http://www.w3.org/2001/XMLSchema'); @@ -742,7 +746,7 @@ public function describeDataCategoryGroupStructures(array $pairs, $topCategories */ public function getDeleted($type, $startDate, $endDate) { $this->setHeaders("getDeleted"); - $arg = new stdClass; + $arg = new stdClass(); $arg->sObjectType = new SoapVar($type, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); $arg->startDate = $startDate; $arg->endDate = $endDate; @@ -760,7 +764,7 @@ public function getDeleted($type, $startDate, $endDate) { */ public function getUpdated($type, $startDate, $endDate) { $this->setHeaders("getUpdated"); - $arg = new stdClass; + $arg = new stdClass(); $arg->sObjectType = new SoapVar($type, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); $arg->startDate = $startDate; $arg->endDate = $endDate; @@ -792,7 +796,7 @@ public function query($query) { */ public function queryMore($queryLocator) { $this->setHeaders("queryMore"); - $arg = new stdClass; + $arg = new stdClass(); $arg->queryLocator = $queryLocator; $QueryResult = $this->sforce->queryMore($arg)->result; return new QueryResult($QueryResult); @@ -824,7 +828,7 @@ public function queryAll($query, $queryOptions = NULL) { */ public function retrieve($fieldList, $sObjectType, $ids) { $this->setHeaders("retrieve"); - $arg = new stdClass; + $arg = new stdClass(); $arg->fieldList = $fieldList; $arg->sObjectType = new SoapVar($sObjectType, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); $arg->ids = $ids; @@ -839,7 +843,7 @@ public function retrieve($fieldList, $sObjectType, $ids) { */ public function search($searchString) { $this->setHeaders("search"); - $arg = new stdClass; + $arg = new stdClass(); $arg->searchString = new SoapVar($searchString, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); return new SforceSearchResult($this->sforce->search($arg)->result); } @@ -867,7 +871,7 @@ public function getUserInfo() { */ public function setPassword($userId, $password) { $this->setHeaders("setPassword"); - $arg = new stdClass; + $arg = new stdClass(); $arg->userId = new SoapVar($userId, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); $arg->password = $password; return $this->sforce->setPassword($arg); @@ -881,7 +885,7 @@ public function setPassword($userId, $password) { */ public function resetPassword($userId) { $this->setHeaders("resetPassword"); - $arg = new stdClass; + $arg = new stdClass(); $arg->userId = new SoapVar($userId, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema'); return $this->sforce->resetPassword($arg)->result; } @@ -1079,7 +1083,7 @@ function convertFields($any) { $array = $this->xml2array(''.$str.'', 2); - $xml = new stdClass; + $xml = new stdClass(); if (!count($array['Object'])) return $xml; From dd065c279976b2169a156b581224a2a9b34b45e1 Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Wed, 1 Feb 2012 16:50:41 -0800 Subject: [PATCH 10/34] Added explanatory preface to the license --- license | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/license b/license index 16a6267..73c2ab2 100644 --- a/license +++ b/license @@ -1,3 +1,9 @@ +This project is licensed under the 'BSD 3-Clause' license [1], also known as +the 'Modified BSD' license [2]. + +http://www.opensource.org/licenses/BSD-3-Clause +http://www.gnu.org/licenses/license-list.html#ModifiedBSD + Copyright (c) 2010, Salesforce.com All rights reserved. From d1dd8a5bab804d8b28e1200e91d7e7e2d37c1afc Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Wed, 1 Feb 2012 16:56:46 -0800 Subject: [PATCH 11/34] Correction to formatting --- license | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/license b/license index 73c2ab2..5201380 100644 --- a/license +++ b/license @@ -1,8 +1,8 @@ This project is licensed under the 'BSD 3-Clause' license [1], also known as the 'Modified BSD' license [2]. -http://www.opensource.org/licenses/BSD-3-Clause -http://www.gnu.org/licenses/license-list.html#ModifiedBSD +[1] http://www.opensource.org/licenses/BSD-3-Clause +[2] http://www.gnu.org/licenses/license-list.html#ModifiedBSD Copyright (c) 2010, Salesforce.com All rights reserved. From 0c3deb630abf73b33334ed31c3bfbe909d44ffc3 Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Thu, 12 Apr 2012 14:02:44 -0700 Subject: [PATCH 12/34] Prevent PHP from parsing away OldValue, NewValue tags in XxxHistory queries. Fixes #13. --- soapclient/SforceBaseClient.php | 10 +++++--- soapclient/SforcePartnerClient.php | 39 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index 96f3552..ded6e78 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -29,7 +29,6 @@ require_once ('ProxySettings.php'); require_once ('SforceHeaderOptions.php'); - /** * This file contains one class. * @package SalesforceSoapClient @@ -61,6 +60,10 @@ class SforceBaseClient { protected $localeOptions; protected $packageVersionHeader; + protected function getSoapClient($wsdl, $options) { + return new SoapClient($wsdl, $options); + } + public function getNamespace() { return $this->namespace; } @@ -90,7 +93,7 @@ public function printDebugInfo() { echo 'False'; } } - + /** * Connect method to www.salesforce.com * @@ -122,7 +125,8 @@ public function createConnection($wsdl, $proxy=null) { $soapClientArray = array_merge($soapClientArray, $proxySettings); } - $this->sforce = new SoapClient($wsdl, $soapClientArray); + $this->sforce = $this->getSoapClient($wsdl, $soapClientArray); + return $this->sforce; } diff --git a/soapclient/SforcePartnerClient.php b/soapclient/SforcePartnerClient.php index 5a818ad..2399626 100644 --- a/soapclient/SforcePartnerClient.php +++ b/soapclient/SforcePartnerClient.php @@ -32,6 +32,40 @@ * This file contains two classes. * @package SalesforceSoapClient */ +/** + * SforceSoapClient class. + * + * @package SalesforceSoapClient + */ + // When parsing partner WSDL, when PHP SOAP sees NewValue and OldValue, since + // the element has a xsi:type attribute with value 'string', it drops the + // string content into the parsed output and loses the tag name. Removing the + // xsi:type forces PHP SOAP to just leave the tags intact + class SforceSoapClient extends SoapClient { + function __doRequest($request, $location, $action, $version) { + $response = parent::__doRequest($request, $location, $action, $version); + + // Quick check to only parse the XML here if we think we need to + if (strpos($response, 'loadXML($response); + + $nodeList = $dom->getElementsByTagName('NewValue'); + foreach ($nodeList as $node) { + $node->removeAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'type'); + } + $nodeList = $dom->getElementsByTagName('OldValue'); + foreach ($nodeList as $node) { + $node->removeAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'type'); + } + + return $dom->saveXML(); + } + } + /** * SforcePartnerClient class. * @@ -43,6 +77,11 @@ class SforcePartnerClient extends SforceBaseClient { function SforcePartnerClient() { $this->namespace = self::PARTNER_NAMESPACE; } + + protected function getSoapClient($wsdl, $options) { + // Workaround an issue in parsing OldValue and NewValue in histories + return new SforceSoapClient($wsdl, $options); + } /** * Adds one or more new individual objects to your organization's data. From 2b867de2371f92c9df1605c2ebfe146978658fdc Mon Sep 17 00:00:00 2001 From: Brooks Boyd Date: Thu, 24 May 2012 13:28:16 -0500 Subject: [PATCH 13/34] Allow QueryResult object to lazy-load more results --- soapclient/SforceBaseClient.php | 52 ++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index ded6e78..5ea90de 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -785,10 +785,12 @@ public function getUpdated($type, $startDate, $endDate) { */ public function query($query) { $this->setHeaders("query"); - $QueryResult = $this->sforce->query(array ( + $raw = $this->sforce->query(array ( 'queryString' => $query ))->result; - return new QueryResult($QueryResult); + $QueryResult = new QueryResult($raw); + $QueryResult->setSf($this); // Dependency Injection + return $QueryResult; } /** @@ -802,8 +804,10 @@ public function queryMore($queryLocator) { $this->setHeaders("queryMore"); $arg = new stdClass(); $arg->queryLocator = $queryLocator; - $QueryResult = $this->sforce->queryMore($arg)->result; - return new QueryResult($QueryResult); + $raw = $this->sforce->queryMore($arg)->result; + $QueryResult = new QueryResult($raw); + $QueryResult->setSf($this); // Dependency Injection + return $QueryResult; } /** @@ -815,10 +819,12 @@ public function queryMore($queryLocator) { */ public function queryAll($query, $queryOptions = NULL) { $this->setHeaders("queryAll"); - $QueryResult = $this->sforce->queryAll(array ( + $raw = $this->sforce->queryAll(array ( 'queryString' => $query ))->result; - return new QueryResult($QueryResult); + $QueryResult = new QueryResult($raw); + $QueryResult->setSf($this); // Dependency Injection + return $QueryResult; } @@ -919,16 +925,22 @@ public function __construct($response) { } } -class QueryResult { +class QueryResult implements Iterator{ public $queryLocator; public $done; public $records; public $size; + public $pointer; // Current iterator location + private $sf; // SOAP Client + public function __construct($response) { $this->queryLocator = $response->queryLocator; $this->done = $response->done; $this->size = $response->size; + + $this->pointer = 0; + $this->sf = false; if($response instanceof QueryResult) { $this->records = $response->records; @@ -947,6 +959,32 @@ public function __construct($response) { } } } + + public function setSf(SforceBaseClient $sf) { $this->sf = $sf; } // Dependency Injection + + // Basic Iterator implementation functions + public function rewind() { $this->pointer = 0; } + public function next() { ++$this->pointer; } + public function key() { return $this->pointer; } + public function current() { return $this->records[$this->pointer]; } + + public function valid() { + while ($this->pointer >= count($this->records)) { + // Pointer is larger than (current) result set; see if we can fetch more + if ($this->done === false) { + if ($this->sf === false) throw new Exception("Dependency not met!"); + $response = $this->sf->queryMore($this->queryLocator); + $this->records = array_merge($this->records, $response->records); // Append more results + $this->done = $response->done; + $this->queryLocator = $response->queryLocator; + } else { + return false; // No more records to fetch + } + } + if (isset($this->records[$this->pointer])) return true; + + throw new Exception("QueryResult has gaps in the record data?"); + } } class SObject { From ddcaf8acbdcfd395cab0002e5ee663855b2f852b Mon Sep 17 00:00:00 2001 From: Brooks Boyd Date: Thu, 24 May 2012 13:45:18 -0500 Subject: [PATCH 14/34] Add overload methods to pull directly from sObject "fields" property without having to make a longer call. --- soapclient/SforceBaseClient.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index 5ea90de..309162d 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -1114,6 +1114,9 @@ public function __construct($response=NULL) { } } } + + function __get($name) { return (isset($this->fields->$name))? $this->fields->$name : false; } + function __isset($name) { return isset($this->fields->$name); } /** * Parse the "any" string from an sObject. First strip out the sf: and then From 489650583ab8bf945306147aaa48933bc3680658 Mon Sep 17 00:00:00 2001 From: Brooks Boyd Date: Wed, 20 Jun 2012 08:27:16 -0500 Subject: [PATCH 15/34] Saving memory usage for large result sets. Store records as standard objects, and only convert to SObjects when accessed. --- soapclient/SforceBaseClient.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index 309162d..b3c8317 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -949,12 +949,10 @@ public function __construct($response) { if (isset($response->records)) { if (is_array($response->records)) { foreach ($response->records as $record) { - $sobject = new SObject($record); - array_push($this->records, $sobject); + array_push($this->records, $record); }; } else { - $sobject = new SObject($response->records); - array_push($this->records, $sobject); + array_push($this->records, $record); } } } @@ -966,7 +964,7 @@ public function setSf(SforceBaseClient $sf) { $this->sf = $sf; } // Dependency I public function rewind() { $this->pointer = 0; } public function next() { ++$this->pointer; } public function key() { return $this->pointer; } - public function current() { return $this->records[$this->pointer]; } + public function current() { return new SObject($this->records[$this->pointer]); } public function valid() { while ($this->pointer >= count($this->records)) { From d6f2be01ca651c15071d454fa5774d1124646b40 Mon Sep 17 00:00:00 2001 From: burnabitPV Date: Wed, 1 Aug 2012 17:43:16 +0300 Subject: [PATCH 16/34] fixed E_STRICT error due to wrong method signature Fixed method signature of SfoceSoapClient->__doRequest in SforcePartnerClient.php to match PHP's native SoapClient method (E_STRICT error) --- soapclient/SforcePartnerClient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soapclient/SforcePartnerClient.php b/soapclient/SforcePartnerClient.php index 2399626..66bb75a 100644 --- a/soapclient/SforcePartnerClient.php +++ b/soapclient/SforcePartnerClient.php @@ -42,8 +42,8 @@ // string content into the parsed output and loses the tag name. Removing the // xsi:type forces PHP SOAP to just leave the tags intact class SforceSoapClient extends SoapClient { - function __doRequest($request, $location, $action, $version) { - $response = parent::__doRequest($request, $location, $action, $version); + function __doRequest($request, $location, $action, $version, $one_way=0) { + $response = parent::__doRequest($request, $location, $action, $version, $one_way); // Quick check to only parse the XML here if we think we need to if (strpos($response, ' Date: Fri, 28 Sep 2012 10:54:21 -0400 Subject: [PATCH 17/34] adding user-supplied "soap_options" to createConnection in SforceBaseClient.php to allow pass-thru options to SoapClient instantiation --- soapclient/SforceBaseClient.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index ded6e78..c19533c 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -98,17 +98,22 @@ public function printDebugInfo() { * Connect method to www.salesforce.com * * @param string $wsdl Salesforce.com Partner WSDL + * @param object $proxy (optional) proxy settings with properties host, port, + * login and password + * @param array $soap_options (optional) Additional options to send to the + * SoapClient constructor. @see + * http://php.net/manual/en/soapclient.soapclient.php */ - public function createConnection($wsdl, $proxy=null) { + public function createConnection($wsdl, $proxy=null, $soap_options=array()) { $phpversion = substr(phpversion(), 0, strpos(phpversion(), '-')); - $soapClientArray = array ( + $soapClientArray = array_merge(array ( 'user_agent' => 'salesforce-toolkit-php/'.$this->version, 'encoding' => 'utf-8', 'trace' => 1, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP - ); + ), $soap_options); // We don't need to parse out any subversion suffix - e.g. "-01" since // PHP type conversion will ignore it From e36071579714a7528c98bb597cbd516f12a70591 Mon Sep 17 00:00:00 2001 From: Logan Moore Date: Sun, 7 Oct 2012 16:19:39 +1300 Subject: [PATCH 18/34] Added orgWideEmailAddress support to soapclient/SForceEmail.php --- soapclient/SforceEmail.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soapclient/SforceEmail.php b/soapclient/SforceEmail.php index 1a7f876..b0b37a4 100644 --- a/soapclient/SforceEmail.php +++ b/soapclient/SforceEmail.php @@ -81,6 +81,10 @@ public function setHtmlBody($htmlBody) { $this->htmlBody = $htmlBody; } + public function setOrgWideEmailAddressId($orgWideEmailAddressId) { + $this->orgWideEmailAddressId = $orgWideEmailAddressId; + } + public function setPlainTextBody($plainTextBody) { $this->plainTextBody = $plainTextBody; } From e17e2d873fde1e03ca79fd81de9274a59f907b3a Mon Sep 17 00:00:00 2001 From: Jd Daniel Date: Mon, 18 Mar 2013 10:16:01 -0700 Subject: [PATCH 19/34] Upgrading to API version 27.0 --- soapclient/SforceBaseClient.php | 2 +- soapclient/SforceMetadataClient.php | 2 +- soapclient/enterprise.wsdl.xml | 4 ++-- soapclient/metadata.wsdl.xml | 4 ++-- soapclient/partner.wsdl.xml | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/soapclient/SforceBaseClient.php b/soapclient/SforceBaseClient.php index 3ab8a71..71174bc 100644 --- a/soapclient/SforceBaseClient.php +++ b/soapclient/SforceBaseClient.php @@ -41,7 +41,7 @@ class SforceBaseClient { protected $sforce; protected $sessionId; protected $location; - protected $version = '20.0'; + protected $version = '27.0'; protected $namespace; diff --git a/soapclient/SforceMetadataClient.php b/soapclient/SforceMetadataClient.php index 60f0007..7477d72 100644 --- a/soapclient/SforceMetadataClient.php +++ b/soapclient/SforceMetadataClient.php @@ -30,7 +30,7 @@ class SforceMetadataClient { public $sforce; protected $sessionId; protected $location; - protected $version = '20.0'; + protected $version = '27.0'; protected $namespace = 'http://soap.sforce.com/2006/04/metadata'; diff --git a/soapclient/enterprise.wsdl.xml b/soapclient/enterprise.wsdl.xml index 423bda2..06b1c74 100644 --- a/soapclient/enterprise.wsdl.xml +++ b/soapclient/enterprise.wsdl.xml @@ -1,6 +1,6 @@ @@ -3331,7 +3331,7 @@ Copyright 2006-2010 Salesforce.com, inc. All Rights Reserved Manage your Salesforce.com metadata - + \ No newline at end of file diff --git a/soapclient/partner.wsdl.xml b/soapclient/partner.wsdl.xml index 8d75c97..fa3f984 100644 --- a/soapclient/partner.wsdl.xml +++ b/soapclient/partner.wsdl.xml @@ -1,6 +1,6 @@