Weave 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

Adobe Campaign Client Bundle Laravel Package

lafourchette/adobe-campaign-client-bundle

Symfony bundle that integrates the Adobe Campaign client into your application, providing configuration and services for connecting to and interacting with Adobe Campaign APIs.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and register

composer require lafourchette/adobe-campaign-client-bundle
  • Symfony 4+/5+: the bundle should be auto-registered via Flex. If not, add it to config/bundles.php:
    Lafourchette\AdobeCampaignClientBundle\AdobeCampaignClientBundle::class => ['all' => true],
    
  • Symfony 3.x: register it manually in app/AppKernel.php inside registerBundles().

Configure credentials

Put connection details in config/packages/adobe_campaign_client.yaml (or config.yml) and back the secrets with env vars:

adobe_campaign_client:
    # verify exact key names in DependencyInjection/Configuration.php
    endpoint: '%env(ADOBE_CAMPAIGN_ENDPOINT)%'
    login:    '%env(ADOBE_CAMPAIGN_LOGIN)%'
    password: '%env(ADOBE_CAMPAIGN_PASSWORD)%'
    # security_token / tenant / timeout may also be supported

Then add the matching entries to .env and, ideally, a real secrets store for production.

Where to look first

  1. README.md — usually the only place the client service ID and supported operations are documented.
  2. DependencyInjection/Configuration.php — the authoritative list of config keys and defaults.
  3. Resources/config/services.xml (or services.yaml) — the service IDs you will inject. These are the contract you build against.
  4. The underlying client library (lafourchette/adobe-campaign-client or equivalent in composer.json) — the bundle is mostly a thin Symfony wrapper; the real API surface lives there.

First use case

The fastest end-to-end validation is: boot the kernel, fetch the client service from the container in a console command, authenticate, and retrieve a single record from a Campaign schema (e.g. a profile or recipient by primary key). If that round-trips, you have config, networking, and credentials correct, and you can start building real sync jobs on top.

Implementation Patterns

Always inject, never instantiate

Resolve the client through the container (constructor injection in your own services, or $container->get() in a command). Never new the underlying client — you lose config, logging, and any decorators the bundle wires in.

Wrap the client in your own adapter

Create a thin App\AdobeCampaign\CampaignGateway service that owns the client and exposes domain methods (findProfileByEmail(), subscribeToNewsletter(), triggerDelivery()). This gives you:

  • a single place to handle session lifecycle and retries;
  • an interface you can mock in tests, since SOAP/REST calls should never run in unit tests;
  • insulation from the bundle going unmaintained or being replaced.

Treat the session as a resource, not a per-call login

Adobe Campaign sessions are authenticated and time-limited. Log in once per process, reuse the token for the duration of the job, and log out in a finally block. In long-running CLI workers, check token validity before each batch and re-authenticate on expiry rather than letting the first call fail.

Push bulk work off the request cycle

Campaign calls are network-bound and slow. Do not call them inline in a controller on a hot path. Instead:

  • enqueue a message (Symfony Messenger) and process it in a worker;
  • run scheduled syncs as console commands driven by cron or a scheduler;
  • keep per-message batches small (tens to low hundreds of records) so a retry is cheap and idempotent.

Model the direction of data flow explicitly

Most integrations are one of three shapes, and each deserves its own service:

  • Outbound events (order placed, account created) → push into Campaign via a custom resource or a subscription service.
  • Inbound segments → pull audience/segment membership from Campaign on a schedule, persist locally, act on it.
  • Delivery orchestration → trigger a transactional message with a payload of personalization variables.

Configuration per environment

Point dev/staging at a Campaign sandbox instance and never let a local run touch production. Because the bundle reads standard Symfony config, this is just config/packages/dev/adobe_campaign_client.yaml overriding the endpoint. Guard against accidental prod writes with an explicit adobe_campaign_client.dry_run flag checked in your gateway.

Observability

Tag the client service (or your adapter) with a Monolog channel so SOAP/REST traffic, timings, and faults land in a dedicated log file. This is the single highest-value thing you can do — Campaign errors are opaque otherwise.

Gotchas and Tips

SOAP faults are not HTTP errors

Campaign Classic exposes XML/SOAP web services; failures frequently arrive as a SoapFault with a numeric code and a message string, not an HTTP status. Catch \SoapFault explicitly in your gateway, map the known codes to domain exceptions, and log the raw fault string — the message often contains the offending field or query.

Schema field names, not labels

Campaign distinguishes the internal name (@email, @firstName) from the UI label. Your code must use internal names, and they are not always what you'd guess from the interface. Dump the schema metadata once during development and keep it next to your mapping code.

Query conditions need escaping

If your queries are built by concatenating conditions (the common queryDef pattern in Campaign Classic), values containing quotes, &, <, or > will break the XML or, worse, alter the query. Escape every interpolated value, and prefer parameterized helpers in the underlying client where available. Treat any user-supplied string that reaches a query as hostile.

Pagination is mandatory, not optional

Campaign will happily truncate at the default line count. Always set an explicit page size and a start line, and loop until fewer rows than the page size come back. A sync that silently stops at 200 records is the classic first bug in these integrations.

Timeouts and retries

Set a connect/response timeout in config; the default can hang a worker indefinitely. Retry only on transient transport faults with exponential backoff — retrying a validation fault just multiplies the noise.

Timezones and date formats

Campaign stores and compares dates in its own timezone settings, and date literals in queries must match the expected format. Normalize to UTC at the boundary and format explicitly; never rely on date('Y-m-d H:i:s') with PHP's ambient timezone.

Session leakage across workers

If you build a single long-lived worker, be aware that a stale session token will produce confusing, intermittent auth errors that look like credential problems. Add an explicit re-auth on the first auth-shaped failure before giving up.

Extension points

  • Decorate the bundle's client service (decorates: in services.yaml) to add logging, metrics, or caching without forking.
  • Use a Symfony event subscriber around your gateway for audit trails of outbound writes.
  • If the bundle lacks a needed API call, call the underlying client directly from your adapter rather than patching the bundle — keeps upgrades possible.

Maintenance risk

The package has essentially no dependents and no recent signal of activity. Pin the version in composer.json, vendor the underlying client knowledge into your own adapter, and write integration tests against a sandbox Campaign instance so that a future replacement of this bundle is a contained change rather than an archaeology project. Verify the bundle's Symfony version constraints before upgrading your framework — old bundles typically break on Symfony 5/6 due to removed container APIs.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings