ddeboer/salesforce-mapper-bundle
Installation:
composer require ddeboer/salesforce-mapper-bundle
Add to config/bundles.php:
Ddeboer\SalesforceMapperBundle\DdeboerSalesforceMapperBundle::class => ['all' => true],
Configuration:
Define your Salesforce connection in config/packages/ddeboer_salesforce_mapper.yaml:
ddeboer_salesforce_mapper:
connections:
default:
username: 'your_username@example.com'
password: 'your_password'
security_token: 'your_token'
client_id: 'your_client_id'
client_secret: 'your_client_secret'
login_url: 'https://login.salesforce.com'
First Use Case:
Create a User entity mapped to Salesforce's Contact object:
use Ddeboer\SalesforceMapperBundle\Model\SalesforceEntity;
class User extends SalesforceEntity
{
protected $salesforceObject = 'Contact';
}
Fetch a record:
$user = $this->get('ddeboer_salesforce_mapper')->find(User::class, 1);
CRUD Operations:
// Create
$user = new User();
$user->setFirstName('John');
$user->setLastName('Doe');
$this->get('ddeboer_salesforce_mapper')->save($user);
// Update
$user->setEmail('john.doe@example.com');
$this->get('ddeboer_salesforce_mapper')->save($user);
// Delete
$this->get('ddeboer_salesforce_mapper')->delete($user);
Querying with Criteria:
use Ddeboer\SalesforceMapperBundle\Criteria\Criteria;
$criteria = new Criteria();
$criteria->where('FirstName', '=', 'John');
$users = $this->get('ddeboer_salesforce_mapper')->findBy(User::class, $criteria);
Fetching Related Records:
$user = $this->get('ddeboer_salesforce_mapper')->find(User::class, 1, ['Account']);
// Automatically loads related Account data
Bulk Operations:
$bulkSaver = $this->get('ddeboer_salesforce_mapper.bulk_saver');
$bulkSaver->save($users); // Bulk upsert
Custom Field Mappings:
Override getSalesforceField() in your entity to map custom fields:
public function getSalesforceField($property)
{
$mapping = [
'phone' => 'Phone',
'custom_field__c' => 'Custom_Field__c',
];
return $mapping[$property] ?? parent::getSalesforceField($property);
}
Event Listeners:
Use events to hook into lifecycle methods (e.g., preSave, postLoad):
# config/services.yaml
services:
App\EventListener\SalesforceUserListener:
tags:
- { name: kernel.event_listener, event: ddeboer_salesforce_mapper.pre_save, method: onPreSave }
Dependency Injection: Inject the mapper directly into services:
public function __construct(
private SalesforceMapper $mapper
) {}
Field Validation:
public function rules()
{
return [
'FirstName' => 'required',
'Id' => 'ignore', // Skip validation for Salesforce-generated fields
];
}
Bulk API Limits:
MappedBulkSaver) are asynchronous. Check status with:
$result = $bulkSaver->getResult($jobId);
SOQL Injection:
Criteria for queries to prevent SOQL injection:
// UNSAFE
$this->get('ddeboer_salesforce_mapper')->findBy(User::class, "FirstName = 'John'");
// SAFE
$criteria = new Criteria();
$criteria->where('FirstName', '=', 'John');
$this->get('ddeboer_salesforce_mapper')->findBy(User::class, $criteria);
Field Name Case Sensitivity:
Custom_Field__c) in mappings.Enable Logging: Configure Monolog to log Salesforce API calls:
# config/packages/monolog.yaml
handlers:
salesforce:
type: stream
path: "%kernel.logs_dir%/salesforce.log"
level: debug
Check API Limits: Monitor API usage via:
$limits = $this->get('ddeboer_salesforce_mapper')->getConnection()->getApiLimits();
Custom Mappers:
Extend AbstractMapper to handle non-standard objects:
class CustomObjectMapper extends AbstractMapper
{
protected $salesforceObject = 'Custom_Object__c';
public function getSalesforceField($property)
{
// Custom logic
}
}
Override Hydration:
Customize how Salesforce data is converted to entities by extending Hydrator:
class CustomHydrator extends Hydrator
{
protected function hydrateField($entity, $field, $value)
{
// Custom hydration logic
}
}
Batch Processing:
Use BatchProcessor for large datasets:
$processor = new BatchProcessor($this->get('ddeboer_salesforce_mapper'));
$processor->process($users, 200); // Process in batches of 200
Login URL:
Use https://test.salesforce.com for sandbox environments.
Connection Switching: Specify a custom connection name in queries:
$this->get('ddeboer_salesforce_mapper')->find(User::class, 1, [], 'sandbox');
How can I help you explore Laravel packages today?