ae/connect-bundle
AEConnect is a Symfony bundle for integrating with Salesforce via the Salesforce REST SDK. It supports configurable entity mapping, inbound/outbound sync with validation and transformations, bulk synchronization, and command/debug tooling.
Install via Composer (adjust for Laravel’s Symfony compatibility):
composer require ae/connect-bundle
Note: Laravel lacks native Symfony bundle support. Use a Service Provider wrapper or manually register services.
Configure Connections (config/ae_connect.php):
return [
'connections' => [
'default' => [
'username' => env('SF_USERNAME'),
'password' => env('SF_PASSWORD'),
'token' => env('SF_TOKEN'),
'client_id' => env('SF_CLIENT_ID'),
'client_secret' => env('SF_CLIENT_SECRET'),
'domain' => env('SF_DOMAIN', 'login.salesforce.com'),
],
],
];
Map a Doctrine Entity (e.g., Lead):
use AE\ConnectBundle\Annotation\Connection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @Connection("default")
*/
class Lead {
// ...
}
Run a One-Time Sync (via Artisan):
php artisan ae_connect:bulk:sync Lead --insert-new
Note: Use php artisan make:command to wrap commands in Laravel’s CLI.
Define a Transformer (for custom field mapping):
use AE\ConnectBundle\Transformer\TransformerInterface;
class LeadTransformer implements TransformerInterface {
public function transform($entity, $direction) {
if ($direction === 'outbound') {
$entity->setSalesforceId($entity->sf_id); // Custom logic
}
return $entity;
}
}
Annotate the entity:
/**
* @Transformer("lead_transformer")
*/
class Lead { ... }
Trigger a Sync (via Event Listener or Cron):
use AE\ConnectBundle\Event\SyncEvent;
public function onSync(SyncEvent $event) {
if ($event->getEntityName() === 'Lead') {
$this->log->info('Syncing Leads...');
}
}
@Connection and @Transformer annotations.LIMIT/OFFSET.ae_connect:listen for real-time CDC).Outbound (Laravel → Salesforce):
SalesforceConnector to push entities:
$connector = $this->container->get('ae_connect.connector');
$connector->save($leadEntity);
ae_connect:bulk:outbound with --insert-new flag.Inbound (Salesforce → Laravel):
php artisan ae_connect:listen Lead --connection=default
use AE\ConnectBundle\Event\ChangeEvent;
public function onChange(ChangeEvent $event) {
$lead = $event->getEntity();
// Process or reject changes
}
Validation:
ae_connect.inbound/ae_connect.outbound):
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Assert\NotBlank(groups={"ae_connect.inbound"})
*/
private $salesforce_id;
Laravel-Specific Adaptations:
AppServiceProvider:
public function register() {
$this->app->register(\AE\ConnectBundle\AEConnectBundle::class);
}
$this->app->make('ae_connect.queue_worker')->process();
Doctrine in Laravel:
doctrine/orm and doctrine/dbal:
composer require doctrine/orm doctrine/dbal
config/doctrine.php to point to your Laravel database.Logging:
# config/services.php
'Psr\Log\InboundLogger' => \Monolog\Logger::class . '@salesforce_inbound',
Error Handling:
AE\ConnectBundle\Exception\SyncException and log via Laravel’s Log facade:
try {
$connector->save($entity);
} catch (SyncException $e) {
\Log::error($e->getMessage(), ['entity' => get_class($entity)]);
}
Multi-Org Sync:
/**
* @Connection({"default", "sandbox"})
*/
class Account { ... }
Bulk Query Optimization:
LIMIT/OFFSET in bulk commands:
php artisan ae_connect:bulk:query:import Lead --limit=1000 --offset=0
Real-Time CDC:
ae_connect:listen with Laravel Echo/Pusher for live updates:
// Broadcast changes via Laravel Events
event(new LeadSynced($lead));
Custom Transformers:
AbstractTransformer for complex logic:
class CustomTransformer extends AbstractTransformer {
public function transform($entity, $direction) {
if ($direction === 'inbound') {
$entity->setFormattedPhone($this->formatPhone($entity->phone));
}
return parent::transform($entity, $direction);
}
}
PCNTL Dependency:
parallel:workers config to limit processes or switch to sequential processing.Doctrine vs. Eloquent:
eloquent-doctrine.doctrine/orm with Eloquent via illuminate/database's Doctrine integration.Salesforce API Changes:
salesforce/php-sdk.Entity Manager Leaks:
$em->flush();
$em->close();
Bulk Sync Gaps:
--batch-size=1000 and verify progress logs.UUID Handling:
sf_id field uses string type in Doctrine:
/**
* @ORM\Column(type="string", length=36)
*/
private $sf_id;
Enable Debug Logs:
debug: true in config/ae_connect.php and check storage/logs/ae_connect.log.SOQL Errors:
--dry-run in bulk commands to test queries.Transformer Debugging:
var_dump($entity) in transformers to inspect data flow.Connection Issues:
How can I help you explore Laravel packages today?