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

Swiftmailerdbbundle Laravel Package

vkalmuk/swiftmailerdbbundle

SwiftMailerDbBundle adds a database-backed spool to SwiftMailer, letting Symfony apps queue outgoing emails in the database instead of sending them at once. Messages persist until delivered, survive restarts, and can be retried, giving reliable, auditable mail delivery without an external queue serv...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle (originally by White October, forked by vkalmuk), not a Laravel package — there is no service provider, no config/mail.php integration, and no Illuminate\Mail transport. Treat it as something you reach for only on a legacy Symfony 2.x/3.x codebase, or as a reference implementation you copy the idea from when building a DB-backed spool in Laravel (where the equivalent is simply the database queue driver plus a Mail::queue()).

Minimal steps in a Symfony app:

  1. composer require vkalmuk/swiftmailerdbbundle — check the composer.json constraints first; it targets PHP 5.6–7.x and SwiftMailer ~5.4|~6.0, and SwiftMailer itself is end-of-life (replaced by Symfony Mailer). Confirm your PHP version still resolves.
  2. Register the bundle in app/AppKernel.php (or config/bundles.php if the fork happens to be Symfony 4+ compatible — verify, don't assume).
  3. Wire SwiftMailer to the DB spool rather than the default file/memory spool:
    swiftmailer:
        spool: { type: service, id: white_october.swiftmailer_db.spool }
    
  4. Make sure the bundle's Doctrine entity is mapped. Either enable auto_mapping or add the bundle's Resources/config/doctrine path manually in config.yml.
  5. Run doctrine:schema:update --force (or generate a migration) to create the spool table. Expect a message LONGBLOB/TEXT, a created_at, and a status flag — inspect the entity before migrating so you know what you're committing.
  6. Trigger a send with swiftmailer:spool:send only if the bundle registers itself as a Swift_Spool implementation the native command understands. In practice this fork ships its own console command (something like white-october:swiftmailer:db:send); run bin/console list swiftmailer and use whatever it exposes.

First use case to validate before anything else: queue one email, confirm it lands as a row, then run the send command and confirm the row is updated/deleted and the mail is delivered. If that loop doesn't close, stop — the package is not worth further investment.

Implementation Patterns

Use it only when you need durable, inspectable mail state. The genuine value of a DB spool over a file spool is that queued mail is (a) queryable, (b) transactional with your app data, and (c) survives a server rebuild. If you just want async mail, the file spool with a cron is simpler and this bundle adds nothing.

Transaction-coupled spooling. The classic pattern: you register a user and queue a welcome email in the same DB transaction. If the user insert rolls back, the queued mail rolls back with it. Configure the spool to use the same EntityManager/connection as your domain writes; do not let it use a separate connection or you lose atomicity.

Cron flush. Don't send inline. Schedule the bundle's send command every minute:

* * * * * cd /var/www && bin/console white-october:swiftmailer:db:send --env=prod --time-limit=60

Use --time-limit (if supported) so a large backlog doesn't overlap with the next run; pair with a lockfile or flock.

Monitoring / admin integration. Because spooled messages are rows, you can build a simple "outbox" page: count by status, oldest unsent age, failed deliveries. That's the payoff — lean into it. A cron alert on COUNT(*) WHERE status = 'pending' AND created_at < NOW() - INTERVAL 15 MINUTE catching a stuck spool is worth more than any feature this bundle ships.

Retry/failure handling. There is very little built in. The pattern that works: wrap your send command in a supervisor loop, catch transport exceptions yourself, and increment a retry_count column on the entity (extend the entity or add a listener). Cap retries at 3 and mark failed for manual inspection.

Custom entity. Copy the bundled Email entity into your own bundle/app namespace and point the spool at the repository of that class. This is the cleanest extension point — you keep the bundle's spool logic but own the schema (add tenant_id, headers, indexes).

Laravel translation of the pattern (if you arrived here from a Laravel context): you do not need this package. Use Mail::to(...)->queue(new WelcomeMail) with QUEUE_CONNECTION=database, run php artisan queue:work, and php artisan queue:failed gives you the inspectable outbox for free. The only thing worth borrowing is the atomicity guarantee — use DB::afterCommit() or ->afterCommit() on the job so mail isn't queued when the surrounding transaction rolls back.

Gotchas and Tips

  • The entire dependency is dead. SwiftMailer is abandoned; Symfony 6+ ships Symfony Mailer instead. If you are on a modern Symfony, this bundle will not install and there is no upgrade path. Budget for a migration to Symfony Mailer with a Messenger-backed async transport, which is the spiritual successor to this bundle.
  • The spool: service wiring is the sharp edge. If the service ID is wrong or the spool service isn't tagged/aliased correctly, SwiftMailer silently falls back to your configured transport and sends synchronously. Symptom: mail is delivered but no rows appear. Verify by asserting a row exists before running the send command, not after.
  • Console command name differs from core. swiftmailer:spool:send is the native file/memory command; it will not drain a custom DB spool. Running it against a DB spool either does nothing or throws. Always check bin/console list for the bundle's own command.
  • Blob size and table growth. The message column stores the full MIME body, base64-inflated. Attachments will bloat the table fast. Prune sent messages aggressively (DELETE FROM spool WHERE sent_at < NOW() - INTERVAL 7 DAY) — the bundle will not do it for you.
  • Doctrine mapping conflicts. If you already have auto_mapping: true, the bundle's entity can collide with a same-named class or fail to register if the mapping path isn't picked up. Explicitly declare the bundle's mapping in config.yml and check doctrine:mapping:info lists it.
  • Transactions and the spool write. Verify empirically whether the spool write participates in your app's transaction. In several Symfony setups it does not, because the spool holds its own EntityManager reference. Test it: throw after ->send(), roll back, and check whether a row exists.
  • No retry, no batching, no backoff. Everything you'd expect from a production mail spool is missing. Keep the send command's --time-limit / message cap conservative, and never run two flushers concurrently without a lock.
  • Zero stars, no dependents, no maintainer activity. Treat the codebase as an unmaintained snippet. Read the spool class (it will be short — a queueMessage, a flushQueue, a getMessages) before using it, and consider copying it into your app as a first-class class you own rather than depending on the fork. The logic is trivial enough to reimplement in an afternoon, and you'll own the debug path.
  • Extension point worth knowing: the spool class is the single seam. Subclass it, override queueMessage to add tenant/priority tagging, and override flushQueue to add your own error handling and dead-letter behaviour. Everything else in the bundle is wiring.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle