Weave Code
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

adcog-cpi/email-bundle

EBEmailBundle is a Symfony bundle to define and send templated emails via config. Set multiple senders, per-email subjects and Twig text/HTML templates, pass template variables, include inline images and PDF attachments, and apply global vars, images, attachments, and recipients.

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation:

    composer require adcog-cpi/email-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Adcog\EBEmailBundle\EBEmailBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration (config/packages/eb_email.yaml):

    eb_email:
        senders:
            - { name: "Support Team", email: "support@example.com" }
        emails: []
    
  3. Define an Email Template (templates/App/Email/_contact.txt.twig):

    Hello {{ name }},
    
    Thanks for contacting us!
    
  4. Register the Email (config/packages/eb_email.yaml):

    eb_email:
        emails:
            contact:
                subject: 'New contact from {{ name }}!'
                text_template: 'App/Email/_contact.txt.twig'
    
  5. Send the Email (Controller/Service):

    $this->get('eb_email')->send('contact', 'user@example.com', ['name' => 'John']);
    

First Use Case

Send a welcome email with dynamic content:

# config/packages/eb_email.yaml
eb_email:
    emails:
        welcome:
            subject: 'Welcome, {{ user.name }}!'
            html_template: 'App/Email/welcome.html.twig'
            text_template: 'App/Email/welcome.txt.twig'
// In a controller/service
$user = $this->getUser(); // Assume User has `name` and `email` properties
$this->get('eb_email')->send('welcome', $user);

Implementation Patterns

1. Dynamic Recipient Handling

  • Single Recipient:
    $this->get('eb_email')->send('contact', 'user@example.com', ['data' => 'value']);
    
  • Multiple Recipients:
    $this->get('eb_email')->send('newsletter', ['a@example.com', 'b@example.com']);
    
  • User Object (Auto-Resolves Email):
    $user = $this->getUser(); // Must implement `getEmail()` or `getUsername()`
    $this->get('eb_email')->send('password_reset', $user, ['token' => 'xyz']);
    

2. Template Inheritance

  • Base Template (templates/base_email.txt.twig):
    {# Base content #}
    {{ block('content') }}
    
  • Child Template (templates/App/Email/_contact.txt.twig):
    {% extends 'base_email.txt.twig' %}
    {% block content %}
    Hello {{ name }},
    {% endblock %}
    

3. Attachments

Extend the bundle or use a wrapper:

// Custom service (not natively supported)
$email = $this->get('eb_email')->create('contact', 'user@example.com');
$email->addAttachment('/path/to/file.pdf');
$this->get('mailer')->send($email);

4. Event-Driven Workflows

  • Subscriber for User Registration:
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use App\Events\UserRegisteredEvent;
    
    class EmailSubscriber implements EventSubscriberInterface {
        public static function getSubscribedEvents() {
            return [UserRegisteredEvent::class => 'sendWelcomeEmail'];
        }
    
        public function sendWelcomeEmail(UserRegisteredEvent $event) {
            $this->get('eb_email')->send('welcome', $event->getUser());
        }
    }
    

5. Localization

  • Subject/Template per Locale:
    eb_email:
        emails:
            contact:
                subject:
                    en: 'New contact from {{ name }}!'
                    fr: 'Nouveau contact de {{ name }}!'
                text_template: 'App/Email/_contact.txt.twig'
    
    $this->get('eb_email')->send('contact', 'user@example.com', ['name' => 'John'], 'fr');
    

6. Testing

  • Mock the Service:
    $container->set('eb_email', $this->createMock(EmailService::class));
    $mock->expects($this->once())->method('send')->with('contact', 'user@example.com');
    

Gotchas and Tips

Pitfalls

  1. Template Paths:

    • Use fully qualified paths (e.g., App/Email/_contact.txt.twig) or ensure twig.paths is configured.
    • Error: TemplateNotFoundException if the path is relative or incorrect.
  2. Recipient Resolution:

    • If passing a user object, it must implement getEmail() or getUsername().
    • Error: InvalidArgumentException if the recipient is neither a string nor an object with getEmail().
  3. Twig Context:

    • Variables passed to send() are not automatically merged with the template context.
    • Fix: Pass them explicitly:
      $this->get('eb_email')->send('contact', 'user@example.com', ['name' => 'John']);
      
  4. Sender Configuration:

    • Only one sender is required, but additional senders can be defined for different use cases.
    • Gotcha: If no sender is configured, emails will fail silently (check logs).
  5. HTML/Text Templates:

    • If only text_template is provided, the email will be sent as plaintext.
    • If both text_template and html_template are provided, the bundle sends a multipart/alternative email.

Debugging Tips

  1. Enable Twig Debugging:

    # config/packages/twig.yaml
    twig:
        debug: true
        strict_variables: true
    
  2. Log Email Content:

    • Extend the bundle to log emails before sending:
      $this->get('eb_email')->send('contact', 'user@example.com', ['name' => 'John'], null, true); // Debug mode
      
  3. Check for Typos:

    • Validate eb_email.emails.<name> keys in YAML (case-sensitive).
  4. Verify Mailer Transport:

    • Ensure framework.mailer is configured (e.g., transport: '%env(MAILER_DSN)%').

Extension Points

  1. Custom Email Service:

    • Override the default service to add features (e.g., attachments):
      # config/services.yaml
      services:
          App\Service\CustomEmailService:
              decorates: 'eb_email'
              arguments: ['@eb_email.inner']
      
  2. Dynamic Template Selection:

    • Use a compiler pass to resolve templates at runtime:
      $template = $this->getTemplateResolver()->resolve($emailName, $locale);
      
  3. Queue Support:

    • Wrap the send() call in a job for async processing:
      use Symfony\Component\Messenger\MessageBusInterface;
      
      $bus->dispatch(new SendEmailMessage('contact', 'user@example.com', ['name' => 'John']));
      
  4. Event Dispatching:

    • Extend the bundle to dispatch events before/after sending:
      $dispatcher->dispatch(new EmailSentEvent($emailName, $recipients, $context));
      
  5. Fallback Templates:

    • Implement a fallback mechanism for missing templates:
      if (!$this->templateLoader->getSource($template)) {
          $template = 'App/Email/_fallback.txt.twig';
      }
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware