Installation:
composer require ae/salesforce-rest-sdk
Basic Client Initialization (for OAuth):
use AE\SalesforceRestSdk\Rest\Client;
use AE\SalesforceRestSdk\AuthProvider\OAuthProvider;
$client = new Client(
new OAuthProvider(
env('SF_CLIENT_ID'),
env('SF_CLIENT_SECRET'),
env('SF_LOGIN_URL', 'https://login.salesforce.com'),
env('SF_USERNAME'),
env('SF_PASSWORD'),
env('SF_SECURITY_TOKEN', '') // Optional
),
'58.0' // API version (optional, defaults to 44.0)
);
First Use Case: Querying Data
$query = 'SELECT Id, Name FROM Account LIMIT 10';
$results = $client->query($query);
foreach ($results as $record) {
echo $record['Name'] . "\n";
}
Key Starting Points:
Client class methods: query(), queryAll(), queryMore(), describeSObject(), create(), update(), etc.OAuthProvider for web apps (redirect-based auth).
$provider = new OAuthProvider($clientId, $clientSecret, $loginUrl, null, null, null, $redirectUri);
$client = new Client($provider);
$accessToken = $provider->getAccessToken($authCode); // After redirect
$provider = new OAuthProvider($clientId, $clientSecret, $loginUrl, $username, $password, $securityToken);
try {
$client->query('SELECT Id FROM Account LIMIT 1');
} catch (\AE\SalesforceRestSdk\Exception\AuthException $e) {
$provider->refreshAccessToken();
retryOperation();
}
$account = [
'Name' => 'Test Account',
'Description' => 'Created via SDK'
];
$created = $client->create('Account', $account);
$updated = $client->update('Account', $created['id'], ['Description' => 'Updated']);
$batch = $client->newBatch();
$batch->add('Account', 'insert', $accountsArray);
$batch->add('Contact', 'upsert', $contactsArray, 'Email');
$results = $batch->execute();
$tree = $client->newTree();
$tree->add('Account', '001xx000003D', ['fields' => ['Name']]);
$tree->addChild('Contact', '003xx000004E', ['fields' => ['FirstName']], '001xx000003D');
$results = $tree->execute();
$collection = $client->newCollection();
$collection->add('Account', '001xx000003D', ['fields' => ['Name']]);
$collection->add('Account', '001xx000003E', ['fields' => ['Name']]);
$results = $collection->execute();
$client->subscribeToChangeData('Account', function ($event) {
log("Account updated: " . $event['ChangeEventHeader']['entityName']);
});
$client->subscribeToPushTopic('MyTopic', function ($payload) {
log("Push event: " . $payload['data']);
});
$describe = $client->describeGlobal();
$objects = $describe['sobjects'];
$describe = $client->describeSObject('Account');
$fields = $describe['fields'];
$job = $client->newBulkJob('Account', 'insert');
$job->addRecords($accountsArray);
$job->close();
$job->monitor(); // Poll for completion
$results = $job->getResults();
AuthException: Token expired or invalid.ApiException: Salesforce API errors (e.g., INVALID_FIELD).HttpException: Network issues.$client->getLimits() to check API usage.
$limits = $client->getLimits();
if ($limits['queriesRemaining'] < 5) {
sleep(60); // Wait to avoid hitting limits
}
$client->setLogger(new \Monolog\Logger('salesforce', [
new \Monolog\Handler\StreamHandler('salesforce.log', \Monolog\Logger::DEBUG)
]));
Client for unit tests:
$mockClient = Mockery::mock('AE\SalesforceRestSdk\Rest\Client');
$mockClient->shouldReceive('query')->andReturn([['Id' => '001xx000003D']]);
API Version Lock-In:
58.0) to avoid deprecated endpoints.Bulk API Quirks:
monitor() in a loop with delays:
while (!$job->isComplete()) {
sleep(5);
$job->monitor();
}
$client->newBulkJob()->addRecordsAsCsv() for complex data.Streaming API Issues:
while (true) {
try {
$client->subscribeToChangeData('Account', $callback);
break;
} catch (\Exception $e) {
sleep(10);
}
}
null to receive all events.Composite API Limits:
Authentication Edge Cases:
redirectUri matches the one registered in Salesforce.AuthException to refresh.SOQL Limitations:
SELECT Id, Name instead of SELECT *.queryMore() is required for large datasets. Avoid LIMIT without queryMore:
$query = 'SELECT Id FROM Account';
$results = $client->query($query);
do {
foreach ($results as $record) { /* ... */ }
$results = $client->queryMore($results['done'] ?? false);
How can I help you explore Laravel packages today?