+ Start a Discussion
MJBuschMJBusch 

Using external id's with php

 

When the partner wsdl is used.

During create/update/upsert commands a reference field can in Java be populated by using code like this.

 

-----------

 

SObject referencedobject=new SObject();
MessageElement[] refencedobjectInfo=new MessageElement[1];

refencedobjectInfo[0]=new MessageElement(new QName("ext_id__c"), 12);

referencedobject.setType("Contact");
referencedobject.set_any(refencedobjectInfo)

....

 

carInfo[1]=new MessageElement(new QName("Designer__r"), referencedObject);

 

....

 

-----------

 

This works fine and is well documented in the apex_api. But now im trying to do the same in php,  using the following code:

 

----- 

 

$designer=new stdclass();
$designerInfo=array('ext_id__c'=>'12');

$designer->type="Contact";
$designer->fields=$designerInfo;

$carInfo= array('Name' => 'happyCar', 'Designer__r' => $designer);

$car=new stdClass();
$car->type="Car_Model__c";
$car->fields=$carInfo;

$createResp=$sfCon->create(array($car));
print_r($createResp);

---------------------------

This gives an error:

 

Catchable fatal error: Object of class stdClass could not be converted to string in /data/home/mjb/www/extern/salesforce/soapclient/SforceBaseClient.php on line 392

 

I can't find any documentation on this, so if anyone could give me a hint, on how to make this work in PHP i would be grateful.

Message Edited by MJBusch on 01-04-2010 05:14 AM
Best Answer chosen by Admin (Salesforce Developers) 
MJBuschMJBusch

I found out how to do it my self, but i had to change the SforceBaseClient.php::_convertToAny($fields), because it didn't support complex types.

 

I changed  the function to:

 

------

 

 protected function _convertToAny($fields) {
                $anyString = '';
                foreach ($fields as $key => $value) {
                        if($value instanceOf stdclass){
                                $anyString = $anyString.'<'.$key.' xmlns="">';
                                $anyString = $anyString.'<type xmlns="urn:sobject.partner.soap.sforce.com">'.$value->type.'</type>';
                                $anyString = $anyString.$this->_convertToAny($value->fields);
                                $anyString = $anyString.'</'.$key.'>';
                        }else{
                                $anyString = $anyString . '<' . $key . '
                                        xmlns="">' . $value . '</' . $key . '>';
                        }
                }
                return $anyString;
        }

 

 ------------

 

This is all I needed in order to make it work like it does in the Java api. I don't know if a similar change could be included in the next version of the api? (where do i suggest this?)

All Answers

Park Walker (TAGL)Park Walker (TAGL)

Your reference to the external Id field should be Designer__c rather than Designer__r and the value of the field shouild be the id:

 

$carInfo= array('Name' => 'happyCar', 'Designer__c' => 12);

 

 

From the API docs: 

 

You can use external ID fields as a foreign key, allowing you to create, update, or upsert records in a single step instead of querying a record to get the ID first. To do this, specify the foreign key name and the external ID field value. For example:

public void createForeignKeySample(){  Opportunity newOpportunity = new Opportunity();  newOpportunity.setStageName("Prospecting");  Account parentAccountRef = new Account();  parentAccountRef.setExternal_SAP1_ACCTID__c("SAP111111");   newOpportunity.setAccount(parentAccount);  SaveResult[] results = binding.create(new SObject[] {newOpportunity});  // check results and do more processing after the create call ...}

 

Park 

MJBuschMJBusch

Thanks for the response.

 

The problem is, that I don't want to use the Primary ID as external identifier for the referenced object I want to use another custom field, which have been set as an external identifier in SalesForce. Which is done as described in Java, but now i have to do it  in PHP.

 

MJBuschMJBusch

I found out how to do it my self, but i had to change the SforceBaseClient.php::_convertToAny($fields), because it didn't support complex types.

 

I changed  the function to:

 

------

 

 protected function _convertToAny($fields) {
                $anyString = '';
                foreach ($fields as $key => $value) {
                        if($value instanceOf stdclass){
                                $anyString = $anyString.'<'.$key.' xmlns="">';
                                $anyString = $anyString.'<type xmlns="urn:sobject.partner.soap.sforce.com">'.$value->type.'</type>';
                                $anyString = $anyString.$this->_convertToAny($value->fields);
                                $anyString = $anyString.'</'.$key.'>';
                        }else{
                                $anyString = $anyString . '<' . $key . '
                                        xmlns="">' . $value . '</' . $key . '>';
                        }
                }
                return $anyString;
        }

 

 ------------

 

This is all I needed in order to make it work like it does in the Java api. I don't know if a similar change could be included in the next version of the api? (where do i suggest this?)

This was selected as the best answer