How to Use the Entire Salesforce API, Part One (Core Calls, Enterprise WSDL format)
These posts are modeled after the EXAMPLES file that ships with the Salesforce Python Toolkit, in which I wrote snippets of code on how to use all the method calls in the Salesforce API spec. The posts will be modeled after the four sections of the Salesforce API docs; so they will be ‘Core Calls’, ‘Describe Calls’, ‘Utility Calls’, and ‘SOAP Headers’. There will be an Enterprise and Partner WSDL version of each.
NOTE: These examples are not intended to teach the Salesforce API; rather, they are here to illustrate how the PHP Toolkit implements the Salesforce API.
Prerequisites
All examples below assume the Toolkit has been instantiated and the connection has been made.
$crmHandle = new SforceEnterpriseClient();
$crmHandle->createConnection(‘/path/to/enterprise.wsdl.xml’);
Additionally, all examples except login() assume you are logged in, using a call such as
$crmHandle->login(‘joe@example.com.sbox1′, ‘*passwordhere*’ . ‘*securitytokenhere*’);
Conventions
<create lead> – implies that you copy and paste the code from create(), so you have a Lead in the variable $lead and a SaveResult in the variable $result
<create 2 leads> – same as create lead, except copy and paste the code from ‘create 2 leads’ in create()
Variable Names
- $crmHandle – reference to an instance of the Toolkit object
- $result – the result of a Salesforce method call
- $lead – a lead object
Notes
Date formats are in the SOAP dateTime format (ISO 8601), e.g. ‘2009-06-01T23:01:01Z’.
If you see an error like ‘INVALID_TYPE: Must send a concrete entity type’, most likely, you have forgotten to wrap your object in an array before passing it to a method.
convertLead()
<create lead> $leadConvert = new stdClass(); $leadConvert->leadId = $result->id; // The possible values for convertedStatus depend on what's in the // picklist for your org. You can take a look at the 'Convert Lead' screen // in the UI for your API user to see what's there $leadConvert->convertedStatus = 'Qualified'; $leadConvert->doNotCreateOpportunity = true; $leadConvert->overwriteLeadSource = false; $leadConvert->sendNotificationEmail = false; $result = $crmHandle->convertLead($leadConvert);
create()
$lead = new stdClass(); $lead->FirstName = 'Joe'; $lead->LastName = 'Moke'; $lead->Company = 'Jamoke, Inc.'; $lead->Email = 'joe@example.com'; $result = $crmHandle->create(array($lead), 'Lead');
delete()
<create lead> $result = $crmHandle->delete(array($result->id));
emptyRecycleBin()
$result = $crmHandle->emptyRecycleBin(array('*ID OF A DELETED OBJECT HERE*'));
getDeleted()
// $startDate must be the later of 30 days prior and the last recycle bin purge
$result = $crmHandle->getDeleted('Lead', $startDate, $endDate);
getUpdated()
// $startDate must be later than 30 days prior
$result = $crmHandle->getUpdated('Lead', $startDate, $endDate);
invalidateSessions()
BEWARE there is a bug in versions 13.0 and earlier of the PHP Toolkit where it calls both invalidateSessions() AND logout(), generating an exception. I would strongly discourage use of either call, as they log out all concurrent sessions of the user!
You were warned…
$result = $crmHandle->invalidateSessions($crmHandle->getSessionId());
login()
$crmHandle->login('joe@example.com.sbox1', '*password*' . '*securitytoken*');
logout()
SEE NOTES FOR invalidateSessions()
$result = $crmHandle->logout();
merge()
// assume we have two IDs stored in $id and $id2
// retrieve what will be the master record
$lead = $crmHandle->retrieve('FirstName, LastName, Company, Email', 'Lead', $id);
$mergeRequest = new stdClass();
$mergeRequest->masterRecord = $lead;
$mergeRequest->recordToMergeIds = $id2;
$result = $crmHandle->merge($mergeRequest, 'Lead');
process()
The Toolkit diverges slightly from the API here, as it doesn’t implement process(), but instead implements processSubmitRequest() and processWorkitemRequest().
processSubmitRequest() (non-standard)
NOTE: The API docs for this call are currently incorrect; the ProcessSubmitRequest object takes a property ‘comments’, not ‘comment’ as stated here.
$processRequest = new stdClass(); $processRequest->objectId = '*ID OF OBJECT PROCESS REQUEST AFFECTS*'; $processRequest->comments = 'This is what I think.'; $result = $crmHandle->processSubmitRequest(array($processRequest));
processWorkitemRequest() (non-standard)
NOTE: The API docs for this call are currently incorrect; the ProcessWorkitemRequest object takes a property ‘comments’, not ‘comment’ as stated here.
$processRequest = new stdClass(); $processRequest->action = 'Approve'; $processRequest->workitemId = '*ID OF OBJECT PROCESS REQUEST AFFECTS*'; $processRequest->comments = 'I approved this request.'; $result = $crmHandle->processWorkitemRequest(array($processRequest));
query()
$result = $crmHandle->query('SELECT FirstName, LastName FROM Lead');
queryAll()
NOTE: Using the QueryOptions header in conjunction with queryAll() (not query() or queryMore()) DOES NOT WORK as of version 13.1, even though it should per the API spec. This is because the Toolkit fails to attach the SOAP header correctly, and to fix this, simply add
$call == "queryAll" ||
at line 266 in SforceBaseClient.php.
$result = $crmHandle->queryAll('SELECT FirstName, LastName FROM Lead LIMIT 2');
foreach ($result->records as $record) {
echo $record->FirstName . ' ' . $record->LastName . "\n";
}
queryMore()
// return a maximum of 200 results
$queryOptions = new QueryOptions(200);
$crmHandle->setQueryOptions($queryOptions);
$result = $crmHandle->query('SELECT FirstName, LastName FROM Lead');
while ($result->done === false) {
$result = $crmHandle->queryMore($result->queryLocator);
// do something with results
}
retrieve()
$lead = $crmHandle->retrieve('FirstName, LastName, Company, Email', 'Lead', $id);
search()
$result = $crmHandle->search('FIND {Joe Moke} IN Name Fields RETURNING Lead(Name, Phone)');
undelete()
$result = $crmHandle->undelete(array('*ID HERE*'));
update()
NOTE: There is a bug in the Toolkit (as of v13.1) where when setting fields to null (using $obj->fieldsToNull()), you cannot pass an array of fields, you are only able to set one single field to null per update() call.
<create lead> $lead->Id = $result->id; $lead->fieldsToNull = 'Email'; $crmHandle->update(array($lead), 'Lead');
upsert()
NOTE: There is a VERY bad bug in versions 13.0 and earlier of the PHP Toolkit, it has ‘Contact’ hard-coded in the upsert() call in SforceEnterpriseClient.php (line 90). For it to be usable, it needs to take a type, so the method should be rewritten as follows (this will bring it in line with newer versions):
public function upsert($ext_Id, $sObjects, $sObjectType) {
$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, $sObjectType, $this->namespace);
}
$arg->sObjects = $sObjects;
return parent::_upsert($arg);
}
After you change that, you can use upsert() as follows:
<create lead>
$lead->Id = $result->id;
$lead->FirstName = 'Bob';
$crmHandle->upsert('Id', array($lead), 'Lead');

This site has been extremely useful as I have gone down the road of implementing the Salesforce API on our corporate site. Thanks for taking the time to put it together.
Hi! I’m pretty new to the intricacies of SalesForce. I’m trying to build an external webpage that would personalize content based on data stored within SalesForce.
I’m using the api to query SalesForce, but I’m unable to display the content. Any suggestions to whether I should use the query() or retrieve() functions? I’m a little lost and this is probably something extremely simple for someone of your expertise.
Thanks!