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

Zasa Bundle Laravel Package

synaq/zasa-bundle

A PHP bundle from Synaq for integrating Zasa into your application, with package configuration and service wiring to help you add Zasa-backed features quickly and with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install into a Symfony 2.x project (this bundle targets the Symfony2 kernel era — expect to pin symfony/symfony to 2.8 LTS if your app is still on it):

    composer require synaq/zasa-bundle
    

    The underlying synaq/zasa library (the ZASA PHP client itself) and beberlei/assert/SoapClient dependencies come along transitively.

  2. Register the bundle in app/AppKernel.php:

    new Synaq\ZasaBundle\SynaqZasaBundle(),
    
  3. Configure your Zimbra connection in app/config/config.yml. The bundle exposes a DI extension that expects the Zimbra admin endpoint, credentials, and SSL options:

    synaq_zasa:
        host: zimbra-admin.example.com
        port: 7071
        user: "[email protected]"
        password: "%zimbra_admin_password%"
        # ssl: true
    

    Keep the admin password in parameters.yml, never in the committed config.

  4. Look first at the DependencyInjection/Configuration.php and the service definition XML/YAML — that tells you the actual service ID (typically synaq_zasa.client or a factory-backed synaq_zasa) and the config key names, which vary between tagged releases. Then read the ZASA library README on Packagist for the object API (accounts, COS, domains, distribution lists).

  5. First use case — provision an account in a controller or a console command:

    $zasa = $this->get('synaq_zasa');
    $account = $zasa->createAccount('[email protected]', 'TempPassw0rd!');
    $account->setAttribute('displayName', 'Jane Doe');
    $account->save();
    

    The pattern throughout ZASA is hydrate → mutate → save; each resource (Account, Cos, Domain, DistributionList) is a proxy that batches changes and flushes over SOAP when you call save().

Implementation Patterns

Wrap the client in a domain service. Don't inject synaq_zasa directly into controllers. Define a ZimbraAccountProvisioner service that takes the ZASA client and exposes intent-revealing methods:

class ZimbraAccountProvisioner
{
    public function __construct(private $zasa) {}

    public function provision(string $email, string $password, array $attrs = []): void
    {
        $account = $this->zasa->createAccount($email, $password);
        $account->setAttributes($attrs + ['zimbraMailQuota' => 5 * 1024 * 1024 * 1024]);
        $account->save();
    }
}

This isolates SOAP faults, retry logic, and the inevitable library API drift from your application code.

Use it for admin-side, not user-side, operations. ZASA is the admin API — provision/unprovision accounts, manage COS, set quotas, manage aliases and distribution lists, query getAllAccounts / searchDirectory for reporting. Do not try to use it to read mail; that's the mail client API.

Batch operations explicitly. Zimbra SOAP has high per-request overhead. When syncing a directory or bulk-provisioning, iterate and flush in chunks (e.g. 50 accounts per save() sweep or per BatchRequest if the library exposes one). A naive loop of createAccount()->save() is the single biggest performance trap.

Integrate with Symfony events / lifecycle. A common workflow is hooking account creation into your registration flow via a kernel or Doctrine event listener that calls the provisioner, and a corresponding deleteAccount on user deactivation. Route all such calls through the domain service so failures can be caught and logged without aborting the whole transaction.

Console commands are ideal. Admin operations map naturally to app/console commands — a zimbra:sync-users command, a zimbra:quota-report command. This gives you idempotent, cron-friendly tooling without exposing admin actions over HTTP.

Testing. The ZASA client is hard to mock because it returns proxy objects that call save(). Wrap it behind an interface your application owns (ZimbraClientInterface) and keep a test double in tests/. For integration tests, run against a throwaway Zimbra VM or a SOAP fixture server; the library has no built-in mock transport.

Gotchas and Tips

  • Legacy Symfony2 only. This bundle predates Symfony 3/4, the autowiring era, and PHP 7 typed signatures. If you're on Symfony 5+, you'll fight AppKernel, the ContainerAwareCommand base class, and old beberlei/assert constraints. Consider using the underlying synaq/zasa library directly (registered as a plain service) rather than the bundle in modern apps.

  • SOAP fault handling is your responsibility. The library surfaces Zimbra's soap:Fault as exceptions that are not always namespaced consistently. Wrap every admin call in a try/catch for \SoapFault and map Zimbra error codes (e.g. account.CHANGE_PASSWORD, service.INVALID_REQUEST) to your own exception types. Log the raw fault string — Zimbra codes are the fastest debugging path.

  • Certificate verification. Zimbra admin API runs over HTTPS on port 7071 with a self-signed cert by default. If the bundle's config doesn't expose verify_peer: false, you'll need a custom SoapClient or stream_context. Never ship that disabled in production — trust the CA properly, or ZASA calls will fail silently or throw opaque SSL errors.

  • Auth token expiry. Zimbra admin sessions expire. If you're building a long-lived worker (queue consumer) that holds a ZASA client, it will start returning auth errors mid-run. Re-authenticate on failure or re-instantiate the client per batch.

  • Config key naming is inconsistent across versions. Some releases call it host/port, others expect a full server URI. Read Configuration.php for the exact key set — a wrong key silently produces a client pointed at localhost.

  • save() semantics. The proxy objects don't persist until save() is called, and some attribute setters are no-ops if the attribute name isn't recognized by the account's COS. When an attribute "didn't take," check the COS inheritance chain, not your code.

  • Extension points: the bundle is thin — most flexibility lives in the ZASA library. If you need custom SOAP calls, extend the client service via a compiler pass and add methods wrapping ZimbraSoapClient::__soapCall (or the library's equivalent) with your own request objects.

  • Stars and dependents are low (9 / 0) — this is effectively an unmaintained single-vendor wrapper. Treat it as a reference implementation: either fork it, or copy the DI configuration and point the ZASA library at it yourself. Budget time for maintenance, and pin the version.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log