zrgisa/swiftmailerdbbundle
A Symfony bundle that connects SwiftMailer with a database-backed mail spool, letting you queue outgoing messages in the database for later delivery instead of sending them immediately.
This is not a Laravel package. zrgisa/swiftmailerdbbundle is a Symfony bundle (a fork of WhiteOctober's SwiftMailer DB spool). There is no service provider, no facade, no config publish tag. If you composer require it into a Laravel app, nothing will auto-wire.
What to actually do first:
Entity/ (the spooled-message schema) and Spool/ (the queue/flush logic). That schema is the only part worth borrowing.Mail::to($user)->queue(new WelcomeMail) on a database queue driver. Use that first.The bundle's Symfony pattern is:
Swift_Spool with queueMessage() / flushQueue(), persisting rows via Doctrine.swiftmailer:spool:send to drain the table.The Laravel equivalent, in decreasing order of "you should do this":
Pattern 1 – Native queue (recommended).
Mail::to($user)->queue(new WelcomeMail($user));
Configure QUEUE_CONNECTION=database, run php artisan queue:work. You get retries, failed_jobs, and Horizon for free—the bundle offers none of that.
Pattern 2 – Transport decorator. Wrap Laravel's mailer transport so send() writes an RFC822 blob to a table, and a scheduled command re-sends and marks sent. Register by extending Illuminate\Mail\MailManager and adding a custom driver.
Pattern 3 – Full port of the bundle. If you insist: create a mail_spool migration (message LONGTEXT, status, attempts, next_attempt_at), an Eloquent model, a SpoolMail job, and a php artisan mail:flush command on the scheduler. Do not pull in doctrine/orm just to reuse the bundle's entities—Laravel devs should stay in Eloquent.
Integration tips for Pattern 2/3:
message_id column for idempotent re-sends.schedule->command('mail:flush')->everyMinute()->withoutOverlapping().white_october_swift_mailer_db or similar) is entirely ignored by Laravel's config system.doctrine/orm. Wiring that into Laravel means a second ORM and a second connection stack—almost never worth it.TEXT limits; use LONGTEXT/MEDIUMBLOB and guard against MySQL max_allowed_packet errors on the flush insert.->dailyAt('03:00')) that deletes sent rows older than N days, and index (status, next_attempt_at).UPDATE ... SET status='sending' WHERE id=? AND status='queued' and check affected rows. This is the main bug you need to fix if porting.MailManager::extend() (custom driver) or a queued job's middleware()/failed() callbacks—use those rather than editing vendor code.queued but no worker/scheduler is running—the bundle's design assumes an external cron (swiftmailer:spool:send) that has no Laravel analogue by default.How can I help you explore Laravel packages today?