You need to sign in to do that
Don't have an account?
Climbatize
upsert problem with php toolkit 13
Hi,
I've got an exception trying to upsert on a custom object with php toolkit 13:
I usually use update function, but now I'd like to upsert. There is my code:
My connexion functions:
My upsert code on a 'Test_Case__c' custom object:
and the response:
erreur! SoapFault exception: [sf:INVALID_FIELD] INVALID_FIELD: No such column 'Comment__c' on entity 'contact'. in C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceBaseClient.php:419
Stack trace:
#0 [internal function]: SoapClient->__call('upsert', Array)
#1 C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceBaseClient.php(419): SoapClient->upsert(Object(stdClass))
#2 C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceEnterpriseClient.php(93): SforceBaseClient->_upsert(Object(stdClass))
#3 C:\Dev\Workspace\CnV\post.php(34): SforceEnterpriseClient->upsert('Comment__c', Array)
#4 {main}
Why does uspert tries to update the contact object instead of my custom one?
I've got an exception trying to upsert on a custom object with php toolkit 13:
Code:
SoapFault exception: [sf:INVALID_FIELD] INVALID_FIELD: No such column 'Comment__c' on entity 'contact'. in C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceBaseClient.php:419 Stack trace: #0 [internal function]: SoapClient->__call('upsert', Array) #1 C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceBaseClient.php(419): SoapClient->upsert(Object(stdClass)) #2 C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceEnterpriseClient.php(93): SforceBaseClient->_upsert(Object(stdClass)) #3 C:\Dev\Workspace\CnV\post.php(34): SforceEnterpriseClient->upsert('Comment__c', Array) #4 {main}
My connexion functions:
Code:
define("SOAP_CLIENT_BASEDIR", "phptoolkit-13_0/soapclient"); require_once (SOAP_CLIENT_BASEDIR.'/SforceEnterpriseClient.php'); require_once (SOAP_CLIENT_BASEDIR.'/SforceHeaderOptions.php'); require_once ('phptoolkit-13_0/userAuth.php'); function ConnectSession($USERNAME,$PASSWORD) { try { $mySforceConnection = new SforceEnterpriseClient(); $mySoapClient = $mySforceConnection->createConnection(SOAP_CLIENT_BASEDIR.'/enterprise.wsdl.xml'); $mylogin = $mySforceConnection->login($USERNAME, $PASSWORD); $_SESSION['connexion'] = $mySforceConnection; $_SESSION['location'] = $mySforceConnection->getLocation(); $_SESSION['sessionId'] = $mySforceConnection->getSessionId(); $_SESSION['wsdl'] = SOAP_CLIENT_BASEDIR.'/enterprise.wsdl.xml'; } catch (Exception $e) { echo $mySforceConnection->getLastRequest(); echo $e->faultstring; } } function reconnect() { $location = $_SESSION['location']; $sessionId = $_SESSION['sessionId']; $wsdl = $_SESSION['wsdl']; $mySforceConnection = new SforceEnterpriseClient(); $sforceSoapClient = $mySforceConnection->createConnection($wsdl); $mySforceConnection->setEndpoint($location); $mySforceConnection->setSessionHeader($sessionId); $_SESSION['connexion'] = $mySforceConnection; }
My upsert code on a 'Test_Case__c' custom object:
Code:
reconnect(); $sObject1 = new stdClass(); $sObject1->Comment__c = $_GET['comments']; $sObject1->Id = $_GET['id']; try { $response = $_SESSION['connexion']->upsert('Comment__c',array ($sObject1)); } catch(Exception $e) { echo "Update FAILED"; echo "erreur! ".str_replace("\n","<br>",$e); }
and the response:
erreur! SoapFault exception: [sf:INVALID_FIELD] INVALID_FIELD: No such column 'Comment__c' on entity 'contact'. in C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceBaseClient.php:419
Stack trace:
#0 [internal function]: SoapClient->__call('upsert', Array)
#1 C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceBaseClient.php(419): SoapClient->upsert(Object(stdClass))
#2 C:\Dev\Workspace\CnV\phptoolkit-13_0\soapclient\SforceEnterpriseClient.php(93): SforceBaseClient->_upsert(Object(stdClass))
#3 C:\Dev\Workspace\CnV\post.php(34): SforceEnterpriseClient->upsert('Comment__c', Array)
#4 {main}
Why does uspert tries to update the contact object instead of my custom one?
That does look like the problem. Have you tried modifying the Enterprise client function like this:
public function upsert($ext_Id, $sObjects, $type) {
$arg = new stdClass;
$arg->externalIDFieldName = new SoapVar($ext_Id, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema');
foreach ($sObjects as &$sObject) {
$sObject = new SoapVar($sObject, SOAP_ENC_OBJECT, $type, $this->namespace);
}
$arg->sObjects = $sObjects;
return parent::_upsert($arg);
}
I haven't tested this, but it should solve the problem.
Park
All Answers
First, in order to use the upsert command, you have to establish one field in theobject as an external ID.
Second, the syntax for the upsert command is upsert(string ExternalFieldName, sObject ObjectBeingUpdate).
So, in your code, it looks like Comment__c is a custom field, not a custom object, on the Contact object. It looks like it does not exist.
So in order to upsert Test_case__c, I have to define an external ID? I'm invistaging in this way, thanks both for the answer. I'll be back if it's too difficult :)
has any one resolved this?
I'm using the enterprise client and I'm having issues with upsert as well. I think it's because of line 90 in the client:
$sObject = new SoapVar($sObject, SOAP_ENC_OBJECT, 'Contact', $this->namespace);
that seems to specify the Contact object as the Type for the data being sent. all other calls specify a "type" param.
-CWD
That does look like the problem. Have you tried modifying the Enterprise client function like this:
public function upsert($ext_Id, $sObjects, $type) {
$arg = new stdClass;
$arg->externalIDFieldName = new SoapVar($ext_Id, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema');
foreach ($sObjects as &$sObject) {
$sObject = new SoapVar($sObject, SOAP_ENC_OBJECT, $type, $this->namespace);
}
$arg->sObjects = $sObjects;
return parent::_upsert($arg);
}
I haven't tested this, but it should solve the problem.
Park
yup. I did exactly that yesterday evening. everything works like a charm for me.
=)
-CWD
This is not at all a true solve. The part that this code change in the core PHP API is the fact that upsert allows the use of multiple different sObject types, this code solve provided, only allows it to work with one at a time which almost completely defeats the purpose and point of good OOP.
A more proper way to handle it would be to extract the $type from each sObject, respectively. The question being, what is the best way to construct this and during the process of encapsulation, destruct it, pull the type out, reconstruct it and apply it?
Am I wrong in my thoughts that upsert allows for multiple objects to be used, so long as they share a similar External ID's, such as the actual ID field itself?
--
Eric