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

Email Bundle Laravel Package

nti/email-bundle

nti/email-bundle is a Symfony bundle for working with application emails. It provides reusable components for composing and sending messages, integrating email workflows into Symfony projects and helping centralize email logic. Use it to streamline transactional email setup and keep email code organ...

View on GitHub
Deep Wiki
Context7

Getting Started

Before writing a line of code, read the source. This bundle is small (2 stars, 0 dependents), so the README and src/ are the only authoritative docs you have.

  1. Install. The package name on Packagist should be nti/email-bundle; verify with composer show nti/email-bundle before committing it to composer.json. Now that a 5.5.x line exists with patch releases, ^5.5 is defensible — but check the changelog for the 5.x breaking changes first. If you started on a 2024-04-24-style tag, plan the 5.x upgrade deliberately.
  2. Register the bundle. Add it to config/bundles.php (Symfony Flex may not auto-register given the low profile):
    NTI\EmailBundle\NTIEmailBundle::class => ['all' => true],
    
  3. Configure it. Look first in vendor/nti/email-bundle/DependencyInjection/Configuration.php for the real config tree — do not guess YAML keys. Expect something like:
    # config/packages/nti_email.yaml
    nti_email:
      mailer: mailer.mailer          # or a dsn
      templates: '%kernel.project_dir%/templates/emails'
      persist: true                  # if it ships Doctrine entities
    
  4. Run migrations before anything else. v5.5.2 is a fix for "issue calling Smtp table", which confirms the bundle ships a Doctrine-mapped SMTP configuration table. bin/console doctrine:schema:validate and check Entity/ (or Model/) for Smtp. If the bundle ships no migrations, generate your own — an unmigrated SMTP table is the most likely cause of a blank/failing first send.
  5. First use case: send a single templated transactional email. Inject the bundle's mailer/service (usually something like NTI\EmailBundle\Mailer\EmailManager or an EmailFactory + EmailSender pair) into a controller or command and dispatch one email through your local MAILER_DSN. That two-minute smoke test tells you more than the README about how the pieces fit.
  6. Verify transport wiring. Check whether the bundle wraps Symfony Mailer (symfony/mailer), resolves SMTP settings from the DB table, or has its own transport. bin/console debug:container --tag=mailer.transport_factory and bin/console debug:container NTI will show what it registers.

Start in vendor/nti/email-bundle/ — read Resources/config/services.yaml, the DependencyInjection/ folder, and any Entity/ or Model/ directory. Those three tell you whether it is a thin Mailer wrapper, a DB-backed template/queue system, or an admin-facing email store.

Implementation Patterns

Wrap, don't reach in. Inject the bundle's sending service into your own App\Mail\Notifier (or similar) rather than calling it from controllers. That one seam lets you swap the bundle out if it is abandoned, and keeps your domain code free of a 2-star dependency.

Treat the DB SMTP table as configuration state, not code. The 5.5.2 fix makes clear SMTP settings live in a table and are read at send time. That means:

  • Seed it explicitly (fixture or migration) for every environment; don't rely on an admin UI existing.
  • Cache the lookup if it happens per message — a DB round-trip per email is easy to miss in a queue worker.
  • Decide whether SMTP credentials are per-tenant, per-purpose (transactional vs. marketing), or global. Multi-row support is the likely intent; verify in the repository class.

Secure the SMTP credentials. A table holding host/user/password is a compliance surface. Encrypt the password column at the application layer, restrict the table to the app's DB user, and never expose it via an admin route without an authorization check the bundle does not provide.

Template resolution. Most small Symfony email bundles resolve templates from the filesystem and optionally fall back to a DB-stored template. If the bundle supports both, choose one convention per project — DB-stored templates are great for marketing copy but painful for version control and code review of transactional emails.

Async sending via Messenger. If the bundle exposes the underlying Symfony\Component\Mailer\MailerInterface or a message object, route sends through Messenger (SendEmailMessage) so a slow SMTP server does not block a request. If it only has a synchronous send(), wrap that call in your own Message + MessageHandler — you get retries, throttling, and a dead-letter queue without modifying the bundle.

Persist-then-send for auditability. If the bundle ships entities for storing emails (look for Doctrine\ORM\Mapping\ attributes or Resources/config/doctrine/), enable persistence and run migrations for its schema. This is the most likely reason the bundle exists — a record of every outbound email for support and compliance. Pair it with a small listener that on MessageSentEvent / failure updates the record's status.

Compose DTOs at the boundary. Build an EmailMessage DTO (to, template, variables, subject) in your app, then map it to whatever the bundle expects. Avoid passing bundle-specific objects past your service layer.

Integrations to wire explicitly:

  • Attach the Symfony Mailer transport via MAILER_DSN; confirm the bundle honors it rather than a hardcoded SMTP.
  • Add a Notifier-style adapter if the bundle predates Symfony's symfony/notifier — you get channel abstraction for free.
  • Unit-test by swapping the transport for symfony/mailer's null:// DSN or a MessageLoggerListener; integration-test with a MailHog/mailpit container.
  • Seed the SMTP table in your test fixtures so tests exercise the same resolution path as production.

Multi-tenant use. If you serve multiple tenants, the template directory, DB templates, and the SMTP rows need scoping; do it in your service layer, not by relying on a bundle feature that likely does not exist.

Gotchas and Tips

  • Adoption risk is still the headline. 2 stars, 0 dependents. The existence of a 5.5.2 patch line is mildly reassuring — someone is maintaining it — but a version number alone is not a support contract. Pin the version, vendor a copy if licensing permits (MIT — it does), and have a plan to replace it. Budget for reading the code when a Symfony upgrade breaks it.
  • Upgrade to 5.5.2 if you touch the SMTP table. The fix is specifically "issue calling Smtp table." If your sends fail with a Doctrine/TableNotFoundException, a query builder error, or an unexpected transport, apply the patch before debugging your own code. Diff Entity/Smtp* and its repository between your version and 5.5.2 — schema or method-name changes are the usual culprits and may require a migration.
  • Version skew between 2024 tags and 5.x. If your composer.json pins the April 2024 release, you are missing whatever the 5.x line fixed, including this SMTP table bug. Read the 5.0 changelog for BC breaks before jumping — a major bump on a small bundle is often a rename-everything release.
  • Undocumented config keys. The Configuration.php tree is your only schema. Run bin/console config:dump-reference nti_email after registration to see every key with defaults — this one command replaces most of the missing docs.
  • Doctrine schema surprises. The SMTP table is the concrete case: check config:dump-reference and the Entity/ folder, and generate your own migration if the bundle ships none. Missing migrations is the most common cause of a "bundle does nothing" bug on first install, and now the most common cause of a "transport not configured" bug too.
  • Autowiring may fail. Small bundles often declare services with string IDs and no aliases, so __construct(EmailManager $m) fails with "cannot autowire." Fix by aliasing in your services.yaml:
    NTI\EmailBundle\Mailer\EmailManager:
      alias: nti_email.manager  # verify the real service ID via debug:container
    
  • Do not assume symfony/mailer semantics. If the bundle ships its own transport or SwiftMailer-era code, MAILER_DSN, From headers, and attachments may behave differently. The DB-backed SMTP row may silently override MAILER_DSN — test both paths to learn which wins. Verify one email per feature (HTML, plain text, attachment, reply-to) on install.
  • Debugging checklist: bin/console debug:config nti_email, debug:container NTI, debug:event-dispatcher | grep -i email, doctrine:schema:validate, and set MAILER_DSN=null://null to isolate whether failures are bundle-side or transport-side. For this release specifically, dump the SMTP row you expect to be used and confirm the repository returns it.
  • Extension points, if any. Look for an interface ending in Interface in src/ and any CompilerPass in DependencyInjection/. Those are your customization hooks — a template resolver interface, a sender interface, or an SMTP provider interface is the usual set. If there is none, decorate the bundle's service in your own services.yaml (decorates:) rather than forking.
  • Symfony version matrix. April 2024 origin, 5.5.x patch in 2025-era. If you are on Symfony 7.x, test installation early; a package this small likely has no CI matrix and may need a patch branch.
  • This is a Symfony bundle. Despite the PHP-only framing, there is no Laravel service provider here. In a Laravel app you would be reimplementing rather than integrating — use it only if the SMTP-table/audit-trail design is worth porting, otherwise reach for Laravel's own mailer plus a small SmtpSetting model.
  • Treat it as a component, not a framework. Extract the value you need (DB-managed SMTP config + templated sending + audit trail) into your own App\Mail layer on day one. The two-hour investment to wrap it is what makes the low adoption score tolerable.
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