Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Salesforce Mapper Bundle Laravel Package

ddeboer/salesforce-mapper-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ddeboer/salesforce-mapper-bundle
    

    Add to config/bundles.php:

    Ddeboer\SalesforceMapperBundle\DdeboerSalesforceMapperBundle::class => ['all' => true],
    
  2. 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'
    
  3. 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);
    

Implementation Patterns

Core Workflows

  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);
    
  2. 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);
    
  3. Fetching Related Records:

    $user = $this->get('ddeboer_salesforce_mapper')->find(User::class, 1, ['Account']);
    // Automatically loads related Account data
    
  4. Bulk Operations:

    $bulkSaver = $this->get('ddeboer_salesforce_mapper.bulk_saver');
    $bulkSaver->save($users); // Bulk upsert
    

Integration Tips

  • 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
    ) {}
    

Gotchas and Tips

Pitfalls

  1. Field Validation:

    • Salesforce ignores read-only fields during save, but Laravel validation may still fail. Exclude them explicitly:
      public function rules()
      {
          return [
              'FirstName' => 'required',
              'Id' => 'ignore', // Skip validation for Salesforce-generated fields
          ];
      }
      
  2. Bulk API Limits:

    • Bulk operations (MappedBulkSaver) are asynchronous. Check status with:
      $result = $bulkSaver->getResult($jobId);
      
    • Avoid mixing bulk and regular operations in the same request to prevent API throttling.
  3. SOQL Injection:

    • Always use 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);
      
  4. Field Name Case Sensitivity:

    • Salesforce API fields are case-insensitive, but the bundle expects exact matches. Use underscores (Custom_Field__c) in mappings.

Debugging

  • 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();
    

Extension Points

  1. Custom Mappers: Extend AbstractMapper to handle non-standard objects:

    class CustomObjectMapper extends AbstractMapper
    {
        protected $salesforceObject = 'Custom_Object__c';
    
        public function getSalesforceField($property)
        {
            // Custom logic
        }
    }
    
  2. 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
        }
    }
    
  3. Batch Processing: Use BatchProcessor for large datasets:

    $processor = new BatchProcessor($this->get('ddeboer_salesforce_mapper'));
    $processor->process($users, 200); // Process in batches of 200
    

Configuration Quirks

  • 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');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager